如何使用T-SQL查询XML数据中的多个节点,并将结果输出到一个以逗号分隔的字符串?
例如,我想获得以下XML中所有目的地名称的列表,看起来像“德国,法国,英国,意大利,西班牙,葡萄牙”
<Holidays>
<Summer>
<Regions>
<Destinations>
<Destination Name="Germany" />
<Destination Name="France" />
<Destination Name="UK" />
<Destination Name="Italy" />
<Destination Name="Spain" />
<Destination Name="Portugal" />
</Destinations>
<Regions>
</Summer>
</Holidays>
我正在尝试类似的事情:
Countries = [xmlstring].value('/Holidays/Summer/Regions/Destinations/@Name', 'varchar')
答案 0 :(得分:3)
首先,要从源XML表中获取记录列表,您需要使用.nodes
函数(DEMO):
select Destination.value('data(@Name)', 'varchar(50)') as name
from [xmlstring].nodes('/Holidays/Summer/Regions/Destinations/Destination')
D(Destination)
示例输出:
| NAME |
-------------
| Germany |
| France |
| UK |
| Italy |
| Spain |
| Portugal |
从这里开始,您希望将目标值连接到以逗号分隔的列表中。不幸的是,这不是T-SQL直接支持的,因此您必须使用某种解决方法。如果您使用多行处理源表,最简单的方法是FOR XML PATH('')
技巧。在此查询中,我使用名为Data
的源表,并将XML拆分为单独的记录,然后CROSS APPLY
与FOR XML PATH('')
生成以逗号分隔的行。最后,从结果中删除最终,
以创建列表(DEMO):
;with Destinations as (
select id, name
from Data
cross apply (
select Destination.value('data(@Name)', 'varchar(50)') as name
from [xmlstring].nodes('/Holidays/Summer/Regions/Destinations/Destination') D(Destination)
) Destinations(Name)
)
select id, substring(NameList, 1, len(namelist) - 1)
from Destinations as parent
cross apply (
select name + ','
from Destinations as child
where parent.id = child.id
for xml path ('')
) DestList(NameList)
group by id, NameList
示例输出(请注意,我已将另一个XML片段添加到测试数据中以制作更复杂的示例):
| ID | COLUMN_1 |
-----------------------------------------------
| 1 | Germany,France,UK,Italy,Spain,Portugal |
| 2 | USA,Australia,Brazil |