3

如何使用 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')   
4

1 回答 1

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('')生成逗号分隔的行。最后,,从结果中删除 final 以创建列表(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 | 
于 2013-02-27T15:43:30.257 回答