2016-05-12 49 views
2

我知道已經有關於MS的T-SQL查詢XML無數話題,但與所有的樣品,我不能讓我的查詢才能正常工作。解析XML在T-SQL

我有下面的XML:

<group> 
    <items> 
     <groupitem> 
      <key>23137</key> 
     </groupitem> 
     <groupitem> 
      <key>23139</key> 
     </groupitem> 
     <groupitem> 
      <key>23151</key> 
     </groupitem> 
     <groupitem> 
      <key>23153</key> 
     </groupitem> 
    </items> 
</group> 

我想所有的「鑰匙」的項目,這樣我就可以將它們插入到一個表(SO 4行)

我開始把我的XML爲可變@xml並運行此查詢:

SELECT doc.value('(key/text())[1]', 'nvarchar(255)') AS 'key' 
    FROM @xml.nodes('/group/items/groupitem/*') AS ref(doc) 

這給了我4個空行,如果我刪除[1],它給了我這個錯誤:「XQuery的[值()]:「* value()'需要一個單例(或者空seque NCE),發現類型的操作數 'XDT:untypedAtomic類型'

然後我嘗試這樣的:

SELECT doc.value('(/group/items/groupitem/key)[1]', 'nvarchar(255)') AS 'key' 
    FROM @xml.nodes('/group/items/groupitem/*') AS ref(doc) 

這實際上給了我一些數據,但不幸的是,它的4倍相同的密鑰23137,可能由聲明中的[1]引起。然而,刪除它會讓我回到以前的相同錯誤信息。

我知道我應該怎麼辦呢在XPath(/組/項目/ groupitem /鍵),但不能讓我的身邊,我應該怎麼做,在T-SQL頭。有任何想法嗎?

+0

你有任何理由在'.nodes()'中將XPath表達式的末尾加上星號嗎?你是否期待不同的元素? – Shnugo

回答

1

試試這個:

SELECT 
    doc.value('(key)[1]', 'int') AS 'key' 
FROM 
    @xml.nodes('/group/items/groupitem') AS ref(doc) 

在我而言,這將返回等的輸出:

key 
----- 
23137 
23139 
23151 
23153 

這是你」重新找?

.nodes()通話基本上是給你的XML片段的「僞」表格 - 一個用於XPath表達式的每場比賽。因此,就您的情況而言,您會收到四行XML,每行都代表<groupitem>節點的內容。你伸手進去,抓住裏面包含的<key>元素的值,將它投射到int - 然後,你就完成了!

+0

感謝您的解釋,這確實是我一直在尋找的。還有一個問題:爲什麼需要[1]? – ErikL

+0

@ErikL:因爲潛在地,可能有多個嵌套在父元素下的元素。只要使用'(key)'就會返回元素的**集合**,並且不能將整個XML元素集合轉換爲原子值(比如'int') - 只有一個元素 –

1

在下面的查詢中,doc背景元素已經key元素:

SELECT doc.value('(key/text())[1]', 'nvarchar(255)') AS 'key' 
FROM @xml.nodes('/group/items/groupitem/*') AS ref(doc) 

所以,你不應該再在SELECT子句中提到key。您可以使用.,而不是引用當前上下文元素:

SELECT doc.value('.', 'nvarchar(255)') AS 'key' 
FROM @xml.nodes('/group/items/groupitem/*') AS ref(doc) 
+0

謝謝,這確實有效。我猜測節點語句中的*作爲通配符,並且由於groupitem下面只有一個元素,它被分配給doc的根目錄? – ErikL

+0

它可能是文本()在OP的查詢中是故意的,可能忽略更深的節點內容。然後'(./text())[1]' – Serg