【问题标题】:Transform XML record to table将 XML 记录转换为表
【发布时间】:2019-09-21 00:33:44
【问题描述】:

我在表“sample”列名“xmlrec”中有 XML 数据,如下所示:

<row id='1'>
 <c1>rec1</c1>
 <c2>a</c2>
 <c2>b</c2>
 <c2>c</c2>
</row>

同样需要改造如下:

c1      c2
----    ----
rec1    a
rec1    b
rec1    c

请帮忙

【问题讨论】:

    标签: sql-server xml tsql sql-server-2005 sql-server-2012


    【解决方案1】:

    您可以使用CROSS APPLY xmlrec.nodes('/row/c2') 查找所有c2 节点。找到对应的c1 很简单:

    SELECT n.value('(../c1)[1]', 'VARCHAR(100)') AS c1
         , n.value('.', 'VARCHAR(100)') AS c2
    FROM sample
    CROSS APPLY xmlrec.nodes('/row/c2') AS x(n)
    

    【讨论】:

    • 正是我要发布的内容。来自我的 +1。
    • 不完全相同,但此查询遇到与this question 相同的问题。
    • 感谢大家的解决方案。它起作用了..我采用了以下解决方案 SELECT n.value('(../c1)[1]', 'VARCHAR(100)') AS c1 , n.value('.', 'VARCHAR(100)' ) AS c2 FROM sample CROSS APPLY xmlrec.nodes('/row/c2') AS x(n)
    【解决方案2】:

    我更喜欢向前导航。可以像在另一个答案中一样使用../c1,但是-据我所知-性能并不是最好的。这是另一种选择:

    DECLARE @xml XML =
    N'<row id="1">
     <c1>rec1</c1>
     <c2>a</c2>
     <c2>b</c2>
     <c2>c</c2>
    </row>';
    
    SELECT A.r.value('@id','int') AS row_id
          ,A.r.value('(c1/text())[1]','nvarchar(10)') AS c1
          ,B.c2.value('text()[1]','nvarchar(10)') AS c2
    FROM @xml.nodes('/row') A(r)
    CROSS APPLY A.r.nodes('c2') B(c2);
    

    如果您的 XML 中只有一个 &lt;row&gt;,这是最好的

    SELECT @xml.value('(/row/@id)[1]','int') AS row_id
          ,@xml.value('(/row/c1/text())[1]','nvarchar(10)') AS c1
          ,B.c2.value('text()[1]','nvarchar(10)') AS c2
    FROM @xml.nodes('/row/c2') B(c2);
    

    【讨论】:

    • + 1 "性能不是最好的" 我写了一些关于它的东西here
    • @MikaelEriksson 不久前我确实阅读了您的精彩回答,并在发布此提示时想到了这一点 :-) 但我不记得链接了,感谢您路过!
    猜你喜欢
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 1970-01-01
    • 2017-03-02
    • 1970-01-01
    相关资源
    最近更新 更多