我如何使用 SQL 和 XML 从 TCMB 获取带有日期的美元外汇买入汇率和欧元外汇买入汇率?
How can I take USD Forex Buying and EUR Forex Buying Rates with date from TCMB, using SQL and XML?
我想从 TCMB 页面获取美元和欧元汇率。
我首先使用这个。
Use Coruscant
go
sp_configure 'show advanced options' , 1
go
Reconfigure with Override
go
sp_configure 'Ole Automation Procedures' , 1
go
Reconfigure with Override
Go
我正在使用它来创建 table。
Use Coruscant
go
-- Döviz Kurlarının Yazılacağı Tablo oluşturuluyor
if not exists (select * from sys.tables where name = N'DVZKRLR' and type = 'U')
begin
Create table DVZKRLR (Tarih date, DolarForexBuying float,EuroForexBuying float)
end
Go
我正在使用它来解析 XML 文件,但我无法正确解析。我只想采用 Date(as Tarih)、DolarForexBuying、EuroForexBuying 汇率。
if exists (select * from sys.objects where type = 'P' AND name = 'UPR_GetDovizKurlari_frm_MerkezBankasi')
drop procedure UPR_GetDovizKurlari_MerkezBankasi
go
Create proc [dbo].[UPR_GetDovizKurlari_frm_MerkezBankasi]
(@pYil Smallint, @pAy TinyInt, @pGun TinyInt)
As
begin
Declare @url as varchar(8000)
/*
Set @url = 'https://www.tcmb.gov.tr/kurlar/today.xml'
Set @url = 'https://www.tcmb.gov.tr/kurlar/201903/12032019.xml'
*/
Declare @XmlYilAy NVarchar(6), @XmlTarih NVarchar(10)
Set @XmlYilAy = Right('0000' + cast(@pYil as varchar(4)) , 4) + Right('00' + cast(@pAy as varchar(2)) , 2)
Set @XmlTarih = Right('00' + cast(@pGun as varchar(2)) , 2) + Right('00' + cast(@pAy as varchar(2)) , 2) + Right('0000' + cast(@pYil as varchar(4)) , 4)
If DateFromParts(@pYil, @pAy, @pGun) = DateAdd(dd,0,DateDiff(dd,0,GetDate())) --gelen parametrelergünün tarihi ise
Set @url = 'https://www.tcmb.gov.tr/kurlar/today.xml'
else
Set @url = 'https://www.tcmb.gov.tr/kurlar/' + @XmlYilAy + '/' + @XmlTarih + '.xml'
Print @url
declare @OBJ AS INT
declare @RESULT AS INT
EXEC @RESULT = SP_OACREATE 'MSXML2.XMLHTTP', @OBJ OUT
EXEC @RESULT = SP_OAMethod @OBJ , 'open' , null , 'GET', @url, false
EXEC @RESULT = SP_OAMethod @OBJ, send, NULL,''
If OBJECT_ID('tempdb..#XML') IS NOT Null DROP TABLE #XML
Create table #XML ( STRXML varchar(max))
Insert INTO #XML(STRXML) EXEC @RESULT = SP_OAGetProperty @OBJ, 'responseXML.xml'
--Select * From #XML
DECLARE @XML AS XML
SELECT @XML = STRXML FROM #XML
DROP TABLE #XML
DECLARE @HDOC AS INT
EXEC SP_XML_PREPAREDOCUMENT @HDOC OUTPUT , @XML
Delete from DVZKRLR where tarih = DateFromParts(@pYil, @pAy, @pGun)
INSERT INTO DVZKRLR ( Tarih,DolarForexBuying,EuroForexBuying)
SELECT DateFromParts(@pYil, @pAy, @pGun) As Tarih,
* FROM OPENXML(@HDOC, 'Tarih_Date/Currency')
--I WANT TO TAKE ONLY DOLAR FOREX BUYING AND EURO FOREX BUYING RATE WITH DATE..
--I COULDN'T PARSE XML FILE
With (CrossOrder NVarchar(5), CurrencyCode NVarchar(5),ForexBuying float 'ForexBuying')
End
Go
我正在使用此代码为我的 table 添加费率。
USE CORUSCANT
DECLARE @SAYAC INT = 1
WHILE @SAYAC <= 31
BEGIN
Exec UPR_GetDovizKurlari_MerkezBankasi @pYil = 2022, -- smallint
@pAy = 1, -- tinyint
@pGun = @SAYAC -- tinyint
SET @SAYAC = @SAYAC + 1
END
您可以将整个 XML 文档移动到一个 xml 变量中并使用 values
函数:
declare @MyXmlVar xml;
select @MyXmlVar=strxml from #XML
select USDBuyRate=@MyXmlVar.value('/Tarih_Date[1]/Currency[@Kod="USD"][1]/ForexBuying[1]', 'float'),
EURBuyRate=@MyXmlVar.value('/Tarih_Date[1]/Currency[@Kod="EUR"][1]/ForexBuying[1]', 'float')
这里,#XML 是您的临时文件 table,在 varchar 列中保存 XML 文档。
你也可以先把整个XML转成一个table,再转成select,比如:
select cast(strxml as xml) as XmlCol into #XmlTbl from #XML;
with CurrencyBuyRates as (
SELECT
Currencies.Currency.value('@Kod', 'varchar(3)') as Kod
, Currencies.Currency.value('./ForexBuying[1]', 'float') as ForexBuying
FROM #XMLTbl
CROSS APPLY xmlCol.nodes('/Tarih_Date/Currency') AS Currencies(Currency)
)
select
*
from CurrencyBuyRates
where Kod in ('USD','EUR')
Iyi sanslar!
Microsoft 专有 OPENXML
及其伙伴 sp_xml_preparedocument
和 sp_xml_removedocument
的保留只是为了与过时的 SQL Server 2000 向后兼容。它们的使用减少到非常多少数边缘案例。
从 SQL Server 2005 开始,强烈建议 re-write 您的 SQL 并将其切换到 XQuery。
要点:
- Tarih 列是
DATE
数据类型
- DolarForexBuying 和 *EuroForexBuying * 列应使用
DECIMAL(10,4)
数据类型。 FLOAT 数据类型用于不精确
数字如 PI 3.14159.....
SQL
DECLARE @xml XML =
'<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="isokur.xsl"?>
<Tarih_Date Tarih="18.02.2022" Date="02/18/2022" Bulten_No="2022/35">
<Currency CrossOrder="0" Kod="USD" CurrencyCode="USD">
<Unit>1</Unit>
<Isim>ABD DOLARI</Isim>
<CurrencyName>US DOLLAR</CurrencyName>
<ForexBuying>13.6118</ForexBuying>
<ForexSelling>13.6363</ForexSelling>
<BanknoteBuying>13.6022</BanknoteBuying>
<BanknoteSelling>13.6567</BanknoteSelling>
<CrossRateUSD/>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="1" Kod="AUD" CurrencyCode="AUD">
<Unit>1</Unit>
<Isim>AVUSTRALYA DOLARI</Isim>
<CurrencyName>AUSTRALIAN DOLLAR</CurrencyName>
<ForexBuying>9.7935</ForexBuying>
<ForexSelling>9.8573</ForexSelling>
<BanknoteBuying>9.7484</BanknoteBuying>
<BanknoteSelling>9.9165</BanknoteSelling>
<CrossRateUSD>1.3866</CrossRateUSD>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="2" Kod="DKK" CurrencyCode="DKK">
<Unit>1</Unit>
<Isim>DANİMARKA KRONU</Isim>
<CurrencyName>DANISH KRONE</CurrencyName>
<ForexBuying>2.0770</ForexBuying>
<ForexSelling>2.0872</ForexSelling>
<BanknoteBuying>2.0756</BanknoteBuying>
<BanknoteSelling>2.0920</BanknoteSelling>
<CrossRateUSD>6.5433</CrossRateUSD>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="9" Kod="EUR" CurrencyCode="EUR">
<Unit>1</Unit>
<Isim>EURO</Isim>
<CurrencyName>EURO</CurrencyName>
<ForexBuying>15.4745</ForexBuying>
<ForexSelling>15.5024</ForexSelling>
<BanknoteBuying>15.4637</BanknoteBuying>
<BanknoteSelling>15.5257</BanknoteSelling>
<CrossRateUSD/>
<CrossRateOther>1.1369</CrossRateOther>
</Currency>
...
</Tarih_Date>';
-- INSERT INTO DVZKRLR -- uncomment when you are ready
SELECT TRY_CONVERT(DATE, @xml.value('(/Tarih_Date/@Tarih)[1]', 'CHAR(10)'),104) AS Tarih
, @xml.value('(/Tarih_Date/Currency[@Kod="USD"]/ForexBuying/text())[1]', 'DECIMAL(10,4)') AS DolarForexBuying
, @xml.value('(/Tarih_Date/Currency[@Kod="EUR"]/ForexBuying/text())[1]', 'DECIMAL(10,4)') AS EuroForexBuying
输出
+------------+------------------+-----------------+
| Tarih | DolarForexBuying | EuroForexBuying |
+------------+------------------+-----------------+
| 2022-02-18 | 13.6118 | 15.4745 |
+------------+------------------+-----------------+
我想从 TCMB 页面获取美元和欧元汇率。
我首先使用这个。
Use Coruscant
go
sp_configure 'show advanced options' , 1
go
Reconfigure with Override
go
sp_configure 'Ole Automation Procedures' , 1
go
Reconfigure with Override
Go
我正在使用它来创建 table。
Use Coruscant
go
-- Döviz Kurlarının Yazılacağı Tablo oluşturuluyor
if not exists (select * from sys.tables where name = N'DVZKRLR' and type = 'U')
begin
Create table DVZKRLR (Tarih date, DolarForexBuying float,EuroForexBuying float)
end
Go
我正在使用它来解析 XML 文件,但我无法正确解析。我只想采用 Date(as Tarih)、DolarForexBuying、EuroForexBuying 汇率。
if exists (select * from sys.objects where type = 'P' AND name = 'UPR_GetDovizKurlari_frm_MerkezBankasi')
drop procedure UPR_GetDovizKurlari_MerkezBankasi
go
Create proc [dbo].[UPR_GetDovizKurlari_frm_MerkezBankasi]
(@pYil Smallint, @pAy TinyInt, @pGun TinyInt)
As
begin
Declare @url as varchar(8000)
/*
Set @url = 'https://www.tcmb.gov.tr/kurlar/today.xml'
Set @url = 'https://www.tcmb.gov.tr/kurlar/201903/12032019.xml'
*/
Declare @XmlYilAy NVarchar(6), @XmlTarih NVarchar(10)
Set @XmlYilAy = Right('0000' + cast(@pYil as varchar(4)) , 4) + Right('00' + cast(@pAy as varchar(2)) , 2)
Set @XmlTarih = Right('00' + cast(@pGun as varchar(2)) , 2) + Right('00' + cast(@pAy as varchar(2)) , 2) + Right('0000' + cast(@pYil as varchar(4)) , 4)
If DateFromParts(@pYil, @pAy, @pGun) = DateAdd(dd,0,DateDiff(dd,0,GetDate())) --gelen parametrelergünün tarihi ise
Set @url = 'https://www.tcmb.gov.tr/kurlar/today.xml'
else
Set @url = 'https://www.tcmb.gov.tr/kurlar/' + @XmlYilAy + '/' + @XmlTarih + '.xml'
Print @url
declare @OBJ AS INT
declare @RESULT AS INT
EXEC @RESULT = SP_OACREATE 'MSXML2.XMLHTTP', @OBJ OUT
EXEC @RESULT = SP_OAMethod @OBJ , 'open' , null , 'GET', @url, false
EXEC @RESULT = SP_OAMethod @OBJ, send, NULL,''
If OBJECT_ID('tempdb..#XML') IS NOT Null DROP TABLE #XML
Create table #XML ( STRXML varchar(max))
Insert INTO #XML(STRXML) EXEC @RESULT = SP_OAGetProperty @OBJ, 'responseXML.xml'
--Select * From #XML
DECLARE @XML AS XML
SELECT @XML = STRXML FROM #XML
DROP TABLE #XML
DECLARE @HDOC AS INT
EXEC SP_XML_PREPAREDOCUMENT @HDOC OUTPUT , @XML
Delete from DVZKRLR where tarih = DateFromParts(@pYil, @pAy, @pGun)
INSERT INTO DVZKRLR ( Tarih,DolarForexBuying,EuroForexBuying)
SELECT DateFromParts(@pYil, @pAy, @pGun) As Tarih,
* FROM OPENXML(@HDOC, 'Tarih_Date/Currency')
--I WANT TO TAKE ONLY DOLAR FOREX BUYING AND EURO FOREX BUYING RATE WITH DATE..
--I COULDN'T PARSE XML FILE
With (CrossOrder NVarchar(5), CurrencyCode NVarchar(5),ForexBuying float 'ForexBuying')
End
Go
我正在使用此代码为我的 table 添加费率。
USE CORUSCANT
DECLARE @SAYAC INT = 1
WHILE @SAYAC <= 31
BEGIN
Exec UPR_GetDovizKurlari_MerkezBankasi @pYil = 2022, -- smallint
@pAy = 1, -- tinyint
@pGun = @SAYAC -- tinyint
SET @SAYAC = @SAYAC + 1
END
您可以将整个 XML 文档移动到一个 xml 变量中并使用 values
函数:
declare @MyXmlVar xml;
select @MyXmlVar=strxml from #XML
select USDBuyRate=@MyXmlVar.value('/Tarih_Date[1]/Currency[@Kod="USD"][1]/ForexBuying[1]', 'float'),
EURBuyRate=@MyXmlVar.value('/Tarih_Date[1]/Currency[@Kod="EUR"][1]/ForexBuying[1]', 'float')
这里,#XML 是您的临时文件 table,在 varchar 列中保存 XML 文档。
你也可以先把整个XML转成一个table,再转成select,比如:
select cast(strxml as xml) as XmlCol into #XmlTbl from #XML;
with CurrencyBuyRates as (
SELECT
Currencies.Currency.value('@Kod', 'varchar(3)') as Kod
, Currencies.Currency.value('./ForexBuying[1]', 'float') as ForexBuying
FROM #XMLTbl
CROSS APPLY xmlCol.nodes('/Tarih_Date/Currency') AS Currencies(Currency)
)
select
*
from CurrencyBuyRates
where Kod in ('USD','EUR')
Iyi sanslar!
Microsoft 专有 OPENXML
及其伙伴 sp_xml_preparedocument
和 sp_xml_removedocument
的保留只是为了与过时的 SQL Server 2000 向后兼容。它们的使用减少到非常多少数边缘案例。
从 SQL Server 2005 开始,强烈建议 re-write 您的 SQL 并将其切换到 XQuery。
要点:
- Tarih 列是
DATE
数据类型 - DolarForexBuying 和 *EuroForexBuying * 列应使用
DECIMAL(10,4)
数据类型。 FLOAT 数据类型用于不精确 数字如 PI 3.14159.....
SQL
DECLARE @xml XML =
'<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="isokur.xsl"?>
<Tarih_Date Tarih="18.02.2022" Date="02/18/2022" Bulten_No="2022/35">
<Currency CrossOrder="0" Kod="USD" CurrencyCode="USD">
<Unit>1</Unit>
<Isim>ABD DOLARI</Isim>
<CurrencyName>US DOLLAR</CurrencyName>
<ForexBuying>13.6118</ForexBuying>
<ForexSelling>13.6363</ForexSelling>
<BanknoteBuying>13.6022</BanknoteBuying>
<BanknoteSelling>13.6567</BanknoteSelling>
<CrossRateUSD/>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="1" Kod="AUD" CurrencyCode="AUD">
<Unit>1</Unit>
<Isim>AVUSTRALYA DOLARI</Isim>
<CurrencyName>AUSTRALIAN DOLLAR</CurrencyName>
<ForexBuying>9.7935</ForexBuying>
<ForexSelling>9.8573</ForexSelling>
<BanknoteBuying>9.7484</BanknoteBuying>
<BanknoteSelling>9.9165</BanknoteSelling>
<CrossRateUSD>1.3866</CrossRateUSD>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="2" Kod="DKK" CurrencyCode="DKK">
<Unit>1</Unit>
<Isim>DANİMARKA KRONU</Isim>
<CurrencyName>DANISH KRONE</CurrencyName>
<ForexBuying>2.0770</ForexBuying>
<ForexSelling>2.0872</ForexSelling>
<BanknoteBuying>2.0756</BanknoteBuying>
<BanknoteSelling>2.0920</BanknoteSelling>
<CrossRateUSD>6.5433</CrossRateUSD>
<CrossRateOther/>
</Currency>
<Currency CrossOrder="9" Kod="EUR" CurrencyCode="EUR">
<Unit>1</Unit>
<Isim>EURO</Isim>
<CurrencyName>EURO</CurrencyName>
<ForexBuying>15.4745</ForexBuying>
<ForexSelling>15.5024</ForexSelling>
<BanknoteBuying>15.4637</BanknoteBuying>
<BanknoteSelling>15.5257</BanknoteSelling>
<CrossRateUSD/>
<CrossRateOther>1.1369</CrossRateOther>
</Currency>
...
</Tarih_Date>';
-- INSERT INTO DVZKRLR -- uncomment when you are ready
SELECT TRY_CONVERT(DATE, @xml.value('(/Tarih_Date/@Tarih)[1]', 'CHAR(10)'),104) AS Tarih
, @xml.value('(/Tarih_Date/Currency[@Kod="USD"]/ForexBuying/text())[1]', 'DECIMAL(10,4)') AS DolarForexBuying
, @xml.value('(/Tarih_Date/Currency[@Kod="EUR"]/ForexBuying/text())[1]', 'DECIMAL(10,4)') AS EuroForexBuying
输出
+------------+------------------+-----------------+
| Tarih | DolarForexBuying | EuroForexBuying |
+------------+------------------+-----------------+
| 2022-02-18 | 13.6118 | 15.4745 |
+------------+------------------+-----------------+