在不使用FOR XML PATH的情况下将多个结果行连接到单个结果中

时间:2010-08-20 16:35:23

标签: .net sql-server

我继承了一个存储过程,该过程在子选择中使用FOR XML PATH将子选择中的多个结果行连接到“main”查询的单个结果列中。请考虑以下内容,其中表“z”是主查询的FROM子句的一部分:

SELECT SUBSTRING((SELECT ('; ' + RTRIM(c.SomeField))
FROM a (NOLOCK)
INNER JOIN b (NOLOCK) ON a.aid = b.aid
INNER JOIN c (NOLOCK) ON b.cid = c.cid
WHERE a.zid = z.zid
FOR XML PATH('')), 3, 1000)

如果子选择中有三个结果行,则返回以下内容:

value1; value2; value3

大多数时候,这很有效。但是,c.SomeField的几个值(varchar)中包含特殊的XML字符,最常见的是&符号。因此,当其中一个值有&符号时,我得到了这个:

value1 & more value1; value2; value3

还有另一种方法可以将这些行结果连接在一起吗?如果没有,是否有一种简单的方法来解码.NET中的字符串?

2 个答案:

答案 0 :(得分:2)

来自MVP Rob Farley

SELECT SUBSTRING((
  SELECT ('; ' + RTRIM(c.SomeField))
  FROM a (NOLOCK)
  INNER JOIN b (NOLOCK) ON a.aid = b.aid
  INNER JOIN c (NOLOCK) ON b.cid = c.cid
  WHERE a.zid = z.zid
  FOR XML PATH(''), ROOT('xml'), TYPE
).value('/xml[1]','varchar(max)'), 3, 1000)

他指出:

  

但是,如果我真的制作了我的FOR XML   调用返回实际格式良好的XML,   然后我可以提取内容,   它将数据返回给我   原始(正确)形式。

答案 1 :(得分:1)

您可以将这些语句作为一个批处理运行,以获得所需内容:

declare @s as varchar(max); 
select @s = isnull(@s + '; ', '') + SomeField
from (
    SELECT RTRIM(c.SomeField) as SomeField
    FROM a (NOLOCK) 
    INNER JOIN b (NOLOCK) ON a.aid = b.aid 
    INNER JOIN c (NOLOCK) ON b.cid = c.cid 
    WHERE a.zid = z.zid 
) a; 
select @s as SomeFieldList; 

更新:这是一个不使用您的架构的概念证明:

declare @s as varchar(max);  
select @s = isnull(@s + '; ', '') + SomeField
from ( 
    SELECT 'aaa' as SomeField
    UNION ALL
    SELECT 'bbb' 
    UNION ALL
    SELECT 'ccc' 
) a;  
select @s as SomeFieldList;