2015-04-04 92 views
0

我有一個程序,它將XML數據插入到SQL Server中的XML列中,並且我發現SQL Server在插入時正在更改源XML數據的格式。這使得以後使用相同的源XML來查詢數據變得非常困難。插入XML到SQL Server數據庫,然後查詢它

例如,一個非常簡單的演示是爲了說明問題:

INSERT INTO XMLRecord (XMLData) VALUES ('<Test></Test>') 

Select * from XMLrecord 

返回:

<Test /> 

現在,如果我嘗試運行一個查詢,看看我最初的XML中存在數據庫:

select count (*) as 'Count' from XMLRecord where cast (XMLData AS NVARCHAR(MAX)) = '<Test></Test>' 

0 rows returned; 

但是,如果源XML不包含「空」標記,那麼插入和搜索工作fi NE:

INSERT INTO XMLRecord (XMLData) VALUES ('<Test>Test Values</Test>') 

Select * from XMLrecord 

返回:

<Test>Test Values</Test> 

現在,如果我嘗試運行一個查詢,看看我最初的XML數據庫中存在:

select count (*) as 'Count' from XMLRecord where cast (XMLData AS NVARCHAR(MAX)) = '<Test>Test Values</Test>' 

1 rows returned; 

我希望有人能協助解決如何讓這個工作。如何獲取源XML塊(未知大小,內容等),將其插入數據庫,然後在數據庫中查詢我剛插入的XML上的EXACT匹配項。

數據需要以XML格式存儲在數據庫中,因爲我也將它用於許多其他xQuery。

非常感謝。

+0

如果要匹配確切的字符串,則需要將該值存儲爲字符串而不是XML。您仍然可以將其轉換爲XQuery的XML。 – 2015-04-05 01:29:29

回答

1

Xml數據類型只保證內容被保留。從this MSDN reference

本地存儲爲XML數據類型

的數據被存儲在該保留數據的XML內容的內部表示。此內部表示形式包含有關包含層次結構,文檔順序以及元素和屬性值的信息。具體而言,XML數據的InfoSet內容被保留。有關InfoSet的更多信息,請訪問http://www.w3.org/TR/xml-infosetInfoSet內容可能不是文本XML的完全相同副本,因爲不保留以下信息:無關緊要的空格,屬性順序,命名空間前綴和XML聲明。

其結果是,如果你絕對需要保留原始XML的形狀和結構,你可能需要將其保存爲爲nvarchar(max)和強制轉換爲XML時需要執行的XQuery。如果鑄件XML不是你的使用情況太貴了,你可以使用一個計算列呈現的Xml鑄造版本:

create table XMLRecord (
    XMLData nvarchar(max), 
    XMLDataAsXml as cast(XMLData as xml) 
) 

INSERT INTO XMLRecord (XMLData) VALUES ('<Test></Test>') 
INSERT INTO XMLRecord (XMLData) VALUES ('<Test>Test Values</Test>') 

Select * from XMLrecord; 
-- Returns records and shows Xml casted version is different for empty record 
select count (*) as 'Count' from XMLRecord where cast (XMLData AS NVARCHAR(MAX)) = '<Test></Test>'; 
-- returns 1 
select count (*) as 'Count' from XMLRecord where cast (XMLData AS NVARCHAR(MAX)) = '<Test>Test Values</Test>'; 
-- returns 1 

select XmlDataAsXml.value('Test[1]', 'nvarchar(max)') from XmlRecord; 
-- returns 2 rows, 1 with empty string and 1 with Test Values as expected 

如果轉換爲XML的開銷是適合您的需求太昂貴,您可能需要以兩種格式(2列)存儲。

+0

謝謝 - 一些偉大的信息和想法繼續。 – user3689706 2015-04-06 06:52:12

0

XMLNVARCHAR是不同的數據類型;他們有不同的行爲,混合起來會讓你的代碼非常混亂。

你不能像=>和這樣的謂詞比較XML,你必須使用XQuery predicates.value

SELECT * FROM XmlRecord WHERE XmlData.value('/Test[1]', 'NVARCHAR(max)') = 'Test Values' 

XQuery表達式/Test[1]將提取您的第一個<Test>元素的內容,並.value(..., 'NVARCHAR(max)')會把它轉換成到NVARCHAR,所以你可以使用=比較。