2010-12-16 113 views
0

我有下面的XML:SQL Server的XML分解到臨時表

<query> 
    <param weight="0.3"> 
    <item type="1" low="18" hi="20" pos="1" /> 
    <item type="1" low="220" hi="220" pos="0" /> 
    </param> 
    <param weight="0.7"> 
    <item type="2" low="5" hi="5" pos="1" /> 
    </param> 
</query> 

我希望它會導致以下數據集:

1 0.3 1 18 20 1 
2 0.3 1 220 220 0 
3 0.7 2 5 5 1 

ROW_NUMBER()將使該行數。我只得到第一行(第[1]項),但沒有其他的。如果我刪除'[1]',我會得到一個「單例錯誤」。我怎麼寫這個?

這是我到目前爲止有:

SELECT x.node.value('@weight', 'float') As [Weight], 
     x.node.value('(item/@type)[1]', 'int') AS [Type], 
     x.node.value('(item/@low)[1]', 'float') AS Low, 
     x.node.value('(item/@hi)[1]', 'float') AS Hi, 
     x.node.value('(item/@pos)[1]', 'bit') AS Pos 
FROM @Input.nodes('/query//*') AS x(node) 
+0

誰會降低這種關懷分享爲什麼 - 沒有任何理由說沒有意義就會下結果。 – IamIC 2010-12-16 18:11:50

+0

剛剛刪除了xpath標記 - 這是99%的SQL問題,我沒有看到任何正在討論的xpath問題。 – 2010-12-16 18:27:06

+0

@Dimitre - 我對你的評論感到困惑......我得到的問題是通過對XPath的更好理解而得到解決的。這是確切的問題。或者我在這裏錯過了什麼? – IamIC 2010-12-17 09:54:12

回答

3

我OPENXML想通了:

INSERT INTO @ref 
SELECT * 
FROM OPENXML (@idoc, '/query/param/item', 2) 
WITH ([Weight] float '../@weight', 
     ParamType int  '@type', 
     Low   float '@low', 
     Hi   float '@hi', 
     Pos   bit  '@pos') 
1

你的方式肯定是比我更容易,但它向我挑戰與FLWOR玩:

DECLARE @XML XML= '<query> 
    <param weight="0.3"> 
    <item type="1" low="18" hi="20" pos="1" /> 
    <item type="1" low="220" hi="220" pos="0" /> 
    </param> 
    <param weight="0.7"> 
    <item type="2" low="5" hi="5" pos="1" /> 
    </param> 
</query> 
' 


SELECT x.node.query('.').value('(//weight)[1]', 'float') AS [Weight] 
     , x.node.query('.').value('(//type)[1]', 'int') AS [Type] 
     , x.node.query('.').value('(//low)[1]', 'float') AS Low 
     , x.node.query('.').value('(//hi)[1]', 'float') AS Hi 
     , x.node.query('.').value('(//pos)[1]', 'bit') AS Pos 
FROM (SELECT @XML.query('for $param in /query/param 
        return 
         for $item in $param/item 
         return 
          <item> 
           <weight> {data($param/@weight)} </weight> 
           <type> {data($item/@type) } </type> 
           <low> {data($item/@low) } </low> 
           <hi> {data($item/@hi) } </hi> 
           <pos> {data($item/@pos) } </pos> 
          </item> 
         ') AS result 
     ) q 
     CROSS APPLY result.nodes('./item') AS x (node) 
1

以下查詢應該可以工作。

SELECT x.node.value('../@weight', 'float') As [Weight], 
     x.node.value('(@type)[1]', 'int') AS [Type], 
     x.node.value('(@low)[1]', 'float') AS Low, 
     x.node.value('(@hi)[1]', 'float') AS Hi, 
     x.node.value('(@pos)[1]', 'bit') AS Pos 
FROM @Input.nodes('/query/param/item') AS x(node) 
+0

+1工作,謝謝。我發現這是在發揮作用的層次結構。速度方面,這比OPENXML長34%。有趣。 – IamIC 2010-12-16 19:29:55