您所遇到的問題是由於您的XML模式規範。如果XML文檔中的節點是架構的一部分,則在查詢該節點時必須指定該架構。或者,您可以爲模式規範使用通配符。但是,在沒有模式的情況下指定節點名稱不起作用(正如你所經歷的那樣)。
因此,讓我們來看一個例子:
SQL Fiddle
MS SQL Server 2008的架構設置:
CREATE TABLE dbo.Tbl(id INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, dict XML);
INSERT INTO dbo.Tbl(dict)
VALUES('<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<KeyValueOfstringanyType>
<Key>code</Key><Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">WFR 052</Value>
</KeyValueOfstringanyType>
<KeyValueOfstringanyType>
<Key>type</Key><Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">Newsletter</Value>
</KeyValueOfstringanyType>
</ArrayOfKeyValueOfstringanyType>');
表dbo.Tbl
與剛剛兩列創建一個身份id
列和XML的dict
列。
爲了讓您的第一個查詢工作,指定使用通配符每個節點的架構:
查詢1:返回
SELECT dict.value('/*:ArrayOfKeyValueOfstringanyType[1]/*:KeyValueOfstringanyType[1]/*:Key[1]','NVARCHAR(MAX)')
FROM dbo.Tbl;
導致第一Key
:
Results:
| COLUMN_0 |
|----------|
| code |
現在,您希望返回Key ='code'處的所有鍵值對的Value節點。你可以在xquery中進行過濾,但我通常更喜歡用SQL進行過濾。爲此,我們首先需要獲取所有對。該XML節點功能會讓我們更接近了一步:
查詢2:
SELECT id,key_value.query('.')
FROM dbo.Tbl
CROSS APPLY dict.nodes('/*:ArrayOfKeyValueOfstringanyType/*:KeyValueOfstringanyType') AS N(key_value);
它返回每一個行KeyValueOfstringanyType
節點:
Results:
| ID | COLUMN_1 |
|----|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 1 | <p1:KeyValueOfstringanyType xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><p1:Key>code</p1:Key><p1:Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d3p1:string">WFR 052</p1:Value></p1:KeyValueOfstringanyType> |
| 1 | <p1:KeyValueOfstringanyType xmlns:p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><p1:Key>type</p1:Key><p1:Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="d3p1:string">Newsletter</p1:Value></p1:KeyValueOfstringanyType> |
使用那我們可以去Key
和Value
使用XML.value功能: 查詢3:
SELECT id,
key_value.value('./*:Key[1]','NVARCHAR(MAX)') AS [key],
key_value.value('./*:Value[1]','NVARCHAR(MAX)') AS [value]
FROM dbo.Tbl
CROSS APPLY dict.nodes('/*:ArrayOfKeyValueOfstringanyType/*:KeyValueOfstringanyType') AS N(key_value);
現在我們必須爲每個鍵值對的行與鍵和在單獨的列的值:
Results:
| ID | KEY | VALUE |
|----|------|------------|
| 1 | code | WFR 052 |
| 1 | type | Newsletter |
從WHERE
子句中可以很容易地應用額外的過濾器:
查詢4:
WITH KeyValues AS(
SELECT id,
key_value.value('./*:Key[1]','NVARCHAR(MAX)') AS [key],
key_value.value('./*:Value[1]','NVARCHAR(MAX)') AS [value]
FROM dbo.Tbl
CROSS APPLY dict.nodes('/*:ArrayOfKeyValueOfstringanyType/*:KeyValueOfstringanyType') AS N(key_value)
)
SELECT *
FROM KeyValues
WHERE [Key] = 'code';
Results:
| ID | KEY | VALUE |
|----|------|---------|
| 1 | code | WFR 052 |
這是很清楚的,謝謝。 – emarcee
+1好的詳細答案,仍然我會添加按鍵過濾節點()函數 –