2013-02-27 85 views
3

如何使用T-SQL在XML數據中查詢多個節點,並將結果輸出爲單個逗號分隔的字符串?使用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') 

回答

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 APPLYFOR 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 | 
+1

謝謝您的回答細節和例子。我甚至不知道SQLFiddle存在。 – FloatLeft 2013-02-28 09:34:53