2017-10-09 58 views
0

我正在尝试从以下网页导入XML数据:http://www.tcmb.gov.tr/kurlar/today.xml。这是一个不断更新的网页,我希望我的SQL代码获取最新值。导入Unicode 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 

不过,如果我使用此代码从一个非Unicode的XML文件中获取数据(只是更改代码的网站从http://www.tcmb.gov.tr/kurlar/today.xmlhttp://www.bnr.ro/nbrfxrates.xml,它的工作原理,我可以。修改我的代码或方法,这样我可以使用在线的XML文件。

非常感谢!

回答

0

您可能需要的最后一个参数更改为True,在sp_OAMethod电话。喜欢的东西,如下图所示。

EXEC @hr = sp_OAMethod @win, 'Open', NULL, 'GET', @url, True 

假 - 是ANSI

真 - 是UNICODE

查找到下面的链接和搜索的Unicode。

http://notes.szemtsov.com/?p=73&print=print

+0

我做了改变,但现在我得到一个NULL值作为我的SELECT语句 – SQLfreaq

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) 

返回

enter image description here

+0

的最佳解决方案的输出,但它是值得一提,那'BULK'可以在[v2014 SP2]之前处理'UTF-8'(https://support.microsoft.com/en-us/help/3136780) – Shnugo

+0

@Shnugo嗨,你好!很高兴知道。当我和银行在一起时,我只遇到过这样的事情。 –

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 

的问题是,不是所有的字符会正确显示...

一些背景

最后一个参数,它设置为“假”,并不意味着陈述编码(如别处所建议的),但sync/async switch,这将不利于...

您可能会将其导入VARBINARY(MAX)变量,但SQL-Server本身不能处理utf-8编码的字符串。

约翰的解决方案是伟大的,但我认为,这将需要at least v2014 SP2