SQL Server将XML分解为临时表

时间:2010-12-16 17:47:42

标签: xml sql-server-2008

我有以下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)

3 个答案:

答案 0 :(得分: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 :(得分: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 )

答案 2 :(得分: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)