这似乎应该做起来很简单,但是我尝试了很多方法,并且不断出错,而我的google-fu却让我失望了。我正在T-SQL中切碎xml文件,并且xml文件可以包含1到数千个项目。我只需要遍历所有项目,以便提取各种数据。可接受的解决方案是简单地将所有项目日期放入节点作为列标题的临时表中。任何帮助将不胜感激。
declare @x as xml
set @x = '<root>
<item>
<itemCharacteristicA>this</itemCharacteristicA>
<itemCharacteristicB>part of this</itemCharacteristicB>
</item>
<item>
<itemCharacteristicA>that</itemCharacteristicA>
<itemCharacteristicB>part of that</itemCharacteristicB>
</item>
</root>'
declare @i int = 1
while @x.value('(/root/item[@i]/itemCharacteristicA)[1]','varchar(50)') is not null
begin
select @x.value('(/root/item[@i]/itemCharacteristicA)[1]','varchar(50)') CharA, @x.value('(/root/item[@i]/itemCharacteristicB)[1]','varchar(50)') CharB
set @i = @i + 1
end
使用XML数据类型.nodes()
和.value()
方法相对简单。
这称为分解,即将XML转换为矩形关系结构。无需执行任何循环。
SQL
declare @x as xml
set @x = '<root>
<item>
<itemCharacteristicA>this</itemCharacteristicA>
<itemCharacteristicB>part of this</itemCharacteristicB>
</item>
<item>
<itemCharacteristicA>that</itemCharacteristicA>
<itemCharacteristicB>part of that</itemCharacteristicB>
</item>
</root>';
SELECT c.value('(itemCharacteristicA/text())[1]','VARCHAR(30)') AS itemCharacteristicA
, c.value('(itemCharacteristicB/text())[1]','VARCHAR(30)') AS itemCharacteristicB
FROM @x.nodes('/root/item') AS t(c);
输出
+---------------------+---------------------+
| itemCharacteristicA | itemCharacteristicB |
+---------------------+---------------------+
| this | part of this |
| that | part of that |
+---------------------+---------------------+