将 XML 记录转换为 table

Transform XML record to table

我在 table "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

请帮忙

您可以使用 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)

我更喜欢向前导航。可以像在其他答案中那样使用 ../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 中只有一个 <row>,这是最好的

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);