我正在尝试从以下网页导入XML数据:http://www.tcmb.gov.tr/kurlar/today.xml。这是一个不断更新的网页,我希望我的SQL代码获取最新的值。
如果我手动将xml文件下载到我的计算机并运行我的SQL代码,它可以正常运行:
DECLARE @xmlFile XML
SET @xmlFile = (SELECT * FROM OPENROWSET(BULK 'C:\Users\sqlfreaq\Desktop\today.xml', SINGLE_CLOB) AS xmldata)
SELECT @xmlFile.value('(Tarih_Date/Currency/ForexSelling)[1]', 'decimal(18,5)') AS DatabaseID
但是,当我尝试使用OLE存储过程导入数据时,某些Unicode字符会发生变化,因此无法解析XML。我的代码如下:
DECLARE @url VARCHAR(300),
@win INT,
@hr INT,
@xml xml
SET @url = 'http://www.tcmb.gov.tr/kurlar/today.xml'
EXEC @hr = sp_OACreate 'WinHttp.WinHttpRequest.5.1', @win OUT
IF @hr <> 0 EXEC sp_OAGetErrorInfo @win
EXEC @hr = sp_OAMethod @win, 'Open', NULL, 'GET', @url, 'false'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @win
EXEC @hr = sp_OAMethod @win, 'Send'
IF @hr <> 0 EXEC sp_OAGetErrorInfo @win
Create table #tmp(dt nvarchar(max))
insert into #tmp exec @hr =sp_OAGetProperty @win, 'ResponseText'
Select
CAST(CAST([dt] AS VARCHAR(MAX)) AS XML) TT
from #tmp -- single column/single row.
Drop Table #tmp -- clean up
EXEC @hr = sp_OADestroy @win
IF @hr <> 0 EXEC sp_OAGetErrorInfo @win
但是,如果我使用此代码从NON-UNICODE xml文件中获取数据(只需将代码中的网站从http://www.tcmb.gov.tr/kurlar/today.xml更改为http://www.bnr.ro/nbrfxrates.xml,它就可以工作。如何修改我的代码或方法,以便我可以使用在线XML文件。
非常感谢!
答案 0 :(得分:2)
只是另一种选择
示例强>
exec master..xp_cmdshell 'powershell.exe Invoke-WebRequest "http://www.tcmb.gov.tr/kurlar/today.xml" -OutFile "c:\working\today.xml"',no_output
Declare @XML xml;
Select @XML = BulkColumn FROM OPENROWSET(BULK 'c:\working\today.xml', SINGLE_BLOB) x;
Select [CrossOrder] = lvl1.n.value('@CrossOrder' ,'int')
,[Kod] = lvl1.n.value('@Kod' ,'nvarchar(50)') -- Set desired data tyoe
,[CurrencyCode] = lvl1.n.value('@CurrencyCode' ,'nvarchar(50)')
,[Unit] = lvl1.n.value('Unit[1]' ,'nvarchar(50)')
,[Isim] = lvl1.n.value('Isim[1]' ,'nvarchar(50)')
,[CurrencyName] = lvl1.n.value('CurrencyName[1]' ,'nvarchar(50)')
,[ForexBuying] = lvl1.n.value('ForexBuying[1]' ,'nvarchar(50)')
,[ForexSelling] = lvl1.n.value('ForexSelling[1]' ,'nvarchar(50)')
,[BanknoteBuying] = lvl1.n.value('BanknoteBuying[1]' ,'nvarchar(50)')
,[BanknoteSelling] = lvl1.n.value('BanknoteSelling[1]','nvarchar(50)')
,[CrossRateUSD] = lvl1.n.value('CrossRateUSD[1]' ,'nvarchar(50)')
,[CrossRateOther] = lvl1.n.value('CrossRateOther[1]' ,'nvarchar(50)')
From @XML.nodes('Tarih_Date/Currency') lvl1(n)
<强>返回强>
答案 1 :(得分:1)
这不是解决方案,只是代码失败的解释:
问题出现在这里并且是双重的:
Select
CAST(CAST([dt] AS VARCHAR(MAX)) AS XML) TT
转换为VARCHAR
而不是NVARCHAR
会破坏VARCHAR's
归类未涵盖的字符。
第二个问题是,您的XML以指令开头,声明编码为UTF-8
。但实际数据为UTF-16
(实际上是UCS-2
)。
将其更改为此功能
Select
CAST(REPLACE(CAST([dt] AS NVARCHAR(MAX)),'UTF-8','UTF-16') AS XML) TT
问题是,并非所有字符都能正确显示......
更多背景
您设置为'false'的最后一个参数并不是要声明编码(如其他地方所建议的那样),而是sync/async
switch,这无济于事......
您可以将其导入VARBINARY(MAX)
变量,但SQL-Server本身无法处理utf-8
编码的字符串。
John的解决方案很棒,但我认为,它需要at least v2014 SP2
答案 2 :(得分:0)
您可能需要在True
来电中将最后一个参数更改为sp_OAMethod
。如下所示的东西。
EXEC @hr = sp_OAMethod @win, 'Open', NULL, 'GET', @url, True
错误 - 适用于ANSI
是 - 适用于UNICODE
查看以下链接并搜索Unicode。