将XML记录转换为表

时间:2019-05-02 13:10:27

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

我在表“ 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

请帮助

2 个答案:

答案 0 :(得分:3)

您可以使用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 :(得分:3)

我更喜欢向前导航。可以在其他答案中使用../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);