2014-01-09 76 views
1
ALTER FUNCTION [dbo].[fnGetTrustNotesByTrustIDForAdminConsole] 
(@TrustID INT 
) 
RETURNS varchar(MAX) 
AS 
BEGIN 
    DECLARE @listStr VARCHAR(MAX) 

    SELECT @listStr = COALESCE(@listStr + '|' , '') + ltrim(Note.NoteText) 
    FROM TrustNote 
    JOIN Note 
    ON  TrustNote.NoteID = Note.NoteID 
    and Note.Archived = 0 
    WHERE Trustid = @TrustID 

    RETURN @listStr 

END 

該函數從數據庫返回「Notes」並對它們進行編譯,但Note(Note.ListOrderNumber)中還有另一個列,除了coalesce之外,我還想對它們進行排序。SQL函數,COALESCE和排序

我知道它不起作用,只是在返回之前添加一個訂單,但有沒有辦法添加它?

實例數據

Note 1, Position 2 
Note 2, Position 3 
Note 3, Position 1 

目前檢索完全按照規定在那裏。 後添加ORDER BY Note.ListOrderNumber Where子句僅產生一個結果:

Note 2, Position 3 
+0

嘗試在'WHERE'子句之後添加'ORDER BY'子句,我無法測試它,但我確信它會起作用。 – Matthew

+0

Guido,請不要在此代碼中刪除'dbo',特別是在'ALTER FUNCTION'語句中。僅僅因爲'dbo'是用戶的默認模式並不意味着當前用戶沒有並且當前沒有使用他或她自己的模式!至少總是以存儲的proc或函數的名稱來表示模式,這是一種很好的做法! – JayC

+0

(上面的消息是針對以前的編輯器的,對不起。) – JayC

回答

0

您的功能正在返回一個VARCHAR(MAX) - 和SELECT語句將變量設置爲1個的行場(可能是第一行)。這將始終返回1個varchar字段。如果您希望返回所有行,您必須執行以下兩項操作之一(取決於如何將其與其他代碼相匹配,因爲您可能需要更改調用過程):

選項1: 創建遊標和循環通過你的SELECT語句,並保留追加到變量@liststr 這一操作將仍然返回一個長字符串

選項2: 更改函數返回一個表 例如:

ALTER FUNCTION [dbo].[fnGetTrustNotesByTrustIDForAdminConsole] 
(@TrustID INT 
) 
RETURNS @Temp TABLE(
    lstStr varchar(MAX) 
) 
AS 
BEGIN 

    INSERT INTO @Temp(lstStr) 
    SELECT @listStr = COALESCE(@listStr + '|' , '') + ltrim(Note.NoteText) 
    FROM TrustNote 
    JOIN Note 
    ON  TrustNote.NoteID = Note.NoteID 
    AND Note.Archived = 0 
    WHERE Trustid = @TrustID 

    RETURN 

END 
0

這種方法來連接字符串沒有t總是按預期工作。

PRB: Execution Plan and Results of Aggregate Concatenation Queries Depend Upon Expression Location

使用for xml代替。

CREATE FUNCTION [dbo].[fnGetTrustNotesByTrustIDForAdminConsole] 
(@TrustID INT 
) 
RETURNS varchar(MAX) 
AS 
BEGIN 
    DECLARE @listStr VARCHAR(MAX) 

    SET @listStr = 
     (
     SELECT '|'+Note.NoteText 
     FROM  TrustNote 
     JOIN  Note 
     ON  TrustNote.NoteID = Note.NoteID 
     and  Note.Archived = 0 
     WHERE Trustid = @TrustID 
     ORDER BY Note.ListOrderNumber 
     FOR XML PATH(''), TYPE 
    ).value('text()[1]', 'varchar(max)') 

    RETURN STUFF(@listStr, 1, 1, '') 

END