从xml数据中获取逗号分隔值

时间:2014-04-09 08:30:41

标签: sql-server xml tsql xquery

我知道如何在最简单的情况下做到这一点,例如

DECLARE @commaSeparatedValues NVARCHAR(MAX)
DECLARE @xml XML = N'<id>1</id>
<name>test</name>
<istest>1</istest>'

;WITH nodes AS 
(
    SELECT Tbl.Col.value('.', 'nvarchar(max)') as Value
    FROM @xml.nodes('*/text()') Tbl(Col)
),
prepareStrings
AS
(
    SELECT IIF(ISNUMERIC(n.value) = 1, n.Value, '''' + n.Value + '''') AS Value
    FROM nodes n
)
SELECT @commaSeparatedValues = CASE WHEN @commaSeparatedValues IS NULL THEN s.Value ELSE @commaSeparatedValues + ',' + s.value END
FROM prepareStrings s

SELECT @commaSeparatedValues as csv

这完美无缺。当我想以这种方式解析以下xml数据时出现问题。 我在编写正确的查询时遇到了问题。

DECLARE @xml XML = N'
<e>
  <id>1</id>
  <name>test</name>
  <istest>1</istest>
</e>
<e>
  <id>2</id>
  <name>test2</name>
  <istest>0</istest>
</e>
'

我可以使用

逐行获取元素
select Tbl.col.query('.') as [xml]
from @xml.nodes('e') Tbl(col)

我不知道的是如何向前迈进。不知道如何使用此查询,现在查询[xml]列。

2 个答案:

答案 0 :(得分:2)

请尝试以下SQL查询

DECLARE @commaSeparatedValues NVARCHAR(MAX)
DECLARE @xml XML = N'
<e>
  <id>1</id>
  <name>test1</name>
  <istest>1</istest>
</e>
<e>
  <id>2</id>
  <name>test2</name>
  <istest>2</istest>
</e>
'

;with cte as (
    select 
        rownr = ROW_NUMBER() over (order by @commaSeparatedValues),
        Tbl.col.query('.') as [xml]
    from @xml.nodes('e') Tbl(col)
), cols as (
    select
        rownr,
        Tbl.Col.value('.', 'nvarchar(max)') as Value
    from cte
    cross apply cte.xml.nodes('//text()') Tbl(Col)
)
select distinct 
     STUFF((
       SELECT ',' + IIF(ISNUMERIC(value) = 1, Value, '''' + Value + '''')
       FROM cols SSF WHERE SSF.rownr = S.rownr
       FOR XML PATH(''),TYPE
       ).value('.','VARCHAR(MAX)'
     ), 1, 1, '')
    from cols S

我使用SQL row_number() function对记录进行编号,并在将列值分隔为值时区分列值(第二个CTE使用Partition By子句对行数据中的列进行排序)

然后我使用SQL string concatenation方法将字符串值连接成逗号分隔的字符串,并使用XML PATH()

我希望它有所帮助

答案 1 :(得分:0)

你在找这样的东西吗?

DECLARE @xml XML = N'
<e>
  <id>1</id>
  <name>test</name>
  <istest>1</istest>
</e>
<e>
  <id>2</id>
  <name>test2</name>
  <istest>0</istest>
</e>'

SELECT
    XC.value('(id)[1]', 'varchar(10)') + ',' +
    XC.value('(name)[1]', 'varchar(100)') + ',' +
    xc.value('(istest)[1]', 'varchar(10)')
FROM @Xml.nodes('/e') AS XT(XC)

输出:

1,test,1
2,test2,0

基本上,.nodes()运算符将创建XML片段的“虚拟列表”(XML文档中每个<e>节点一个),然后选择“到达”该XML片段该虚拟表中的每一行,将用逗号分隔的各个部分连接成一个字符串