Преобразовать запись XML в таблицу - PullRequest
1 голос
/ 02 мая 2019

У меня есть данные XML в таблице «образец» с именем столбца «xmlrec», который выглядит следующим образом:

<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 ]

3 голосов
/ 02 мая 2019

Я бы предпочел навигацию вперед.Можно использовать ../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);
3 голосов
/ 02 мая 2019

Вы можете использовать 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)
...