我继承了一个存储过程,该过程在子选择中使用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中的字符串?
答案 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;