2010-08-20 87 views
2

我已經繼承了存儲過程,它使用子查詢中的FOR XML PATH將來自子查詢的多個結果行連接到「主要」查詢中的單個結果列。考慮以下內容,其中表「Z」是FROM子句主查詢的一部分:將多個結果行連接成單個結果而不使用FOR XML PATH

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) 

這將返回以下,如果有從子查詢3個結果行:

value1; value2; value3 

大多數時間,這很好。然而,c.SomeField的一些值是varchar,它們中有特殊的XML字符,最常見的是&符號。所以,當值中的一個具有符號,我得到這個:

value1 & more value1; value2; value3 

有另一種方式我可以連接這些排結果放在一起?如果沒有,是否有一種簡單的方法來解碼.NET中的字符串?

回答

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, 那麼我就可以將內容提取出來, 並在其 原來的(正確)的形式將數據返回給我。

+0

不知道.value是什麼,但是這個效果很好!非常感謝你。 – 2010-08-23 13:34:35

+2

@AJ:這個問題的標題說*「不使用FOR XML PATH」*。 – RedFilter 2010-08-23 13:48:28

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; 
+0

雖然我不能將其作爲子查詢嵌入,但這是我需要做的。 – 2010-08-20 17:49:05

+1

請發佈整個查詢。 – RedFilter 2010-08-20 18:25:23

+0

經過40分鐘的試圖讓這個程序「安全地發佈」,我放棄了。這是相當龐大的,我不確定我可以把它放在這裏,而不會把事情搞砸。 – 2010-08-20 19:09:48