2013-04-11 66 views
4

我們有一個SQL Server 2008 R2數據庫表,其中XML存儲在VARCHAR數據類型的列中。我現在不得不取得xml的一些元素。將字符串轉換爲xml並插入Sql Server

所以我想先將存儲爲VARCHAR數據類型的xml轉換爲存儲爲xml數據類型的xml。

實施例:

表A

Id(int) , ProductXML (varchar(max)) 

表B

Id(int), ProductXML(XML) 

我想將ProductXMLTable A轉換爲XML數據類型並插入到Table B

我使用CAST()CONVERT()函數試圖如下所示:

insert into TableB (ProductXML) 
select CAST(ProductXML as XML) from TableA; 

類似地試圖轉換,但我得到一個錯誤

XML解析:無法切換編碼

有什麼辦法可以將表中的varchar條目轉換爲XML條目嗎?

關於XML:它有很多節點,其結構動態變化。

示例:一行可以具有1個產品的XML條目,另一行可以具有多個產品的xml條目。

回答

12

給我們您的XML樣本爲所有這些將工作:

CONVERT(XML, '<root><child/></root>') 
CONVERT(XML, '<root>   <child/>   </root>', 1) 
CAST('<Name><FName>Carol</FName><LName>Elliot</LName></Name>' AS XML) 

你也可能需要將它轉換爲nvarchar或varbinary第一(從微軟的文檔):

您可以分析任何通過強制轉換(CAST)或將字符串轉換(轉換)爲xml數據類型,將SQL Server字符串數據類型(例如[n] [var] char,[n] text,varbinary和image)轉換爲xml數據類型。未被類型化的XML被檢查以確認其格式正確。如果存在與xml類型關聯的模式,則也會執行驗證。有關更多信息,請參閱將鍵入的XML與未鍵入的XML進行比較。

XML文檔可以用不同的編碼進行編碼(例如,UTF-8,UTF-16,windows-1252)。下面概述有關字符串和二進制源類型如何與XML文檔編碼進行交互以及解析器的行爲方式的規則。

由於nvarchar採用雙字節Unicode編碼,如UTF-16或UCS-2,因此XML解析器會將字符串值視爲一個雙字節Unicode編碼的XML文檔或片段。這意味着XML文檔需要以雙字節Unicode編碼進行編碼,以便與源數據類型兼容。一個UTF-16編碼的XML文檔可以有一個UTF-16字節順序標記(BOM),但它不需要,因爲源類型的上下文清楚地表明它只能是一個雙字節的Unicode編碼文檔。

XML分析器將varchar字符串的內容視爲一個字節的編碼XML文檔/片段。由於varchar源字符串具有關聯的代碼頁,因此如果在XML本身中未指定明確的編碼,解析器將使用該代碼頁進行編碼。如果XML實例具有BOM或編碼聲明,則BOM或聲明需要是與代碼頁一致,否則解析器將報告錯誤。

varbinary的內容被視爲直接傳遞給XML解析器的代碼點流。因此,XML文檔或片段需要內嵌提供BOM或其他編碼信息。解析器只會查看流以確定編碼。這意味着UTF-16編碼的XML需要提供UTF-16 BOM和沒有BOM的實例,並且沒有聲明編碼將被解釋爲UTF-8。

如果XML文檔的編碼事先並未知道,並且在將數據轉換爲XML之前將數據作爲字符串或二進制數據而不是XML數據傳遞,則建議將數據視爲varbinary。例如,從使用OPENROWSET()的XML文件中讀取數據時,應指定數據將被讀取作爲VARBINARY(最大)值:

select CAST(x as XML) 
from OpenRowset(BULK 'filename.xml', SINGLE_BLOB) R(x) 

SQL Server在內部表示XML在於使用高效的二進制表示UTF-16編碼。用戶提供的編碼不被保留,但在解析過程中被考慮。

解決方案:

CONVERT(XML, CONVERT(NVARCHAR(max), ProductXML)) 
+0

謝謝!我仍然會瀏覽你寫的所有內容.xml實際上是動態變化的。它可以爲單個產品或多個產品提供xml信息。我剛剛舉了一個例子。實際上,它是一個將不同日誌記錄數據(xmls)存儲在表中的日誌記錄表。 – CodeNinja 2013-04-11 16:04:09

+0

數據庫設置了什麼編碼? – Darek 2013-04-11 16:08:51

+0

對不起,我是新手。我運行了下面的命令,我在網上找到它來查找數據庫編碼SELECT DATABASEPROPERTYEX('DBName','Collat​​ion')SQLCollat​​ion;我得到'SQL_Latin1_General_CP1_CI_AS'這是你要求的嗎? – CodeNinja 2013-04-11 16:24:00

1

這爲我工作:

select CAST(REPLACE(CAST(column3 AS NVARCHAR(MAX)),'utf-8','utf-16') AS XML) from table