简体   繁体   中英

SQL Function, COALESCE & Sorting

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

This function returns "Notes" from the database and compiles them, however there is a another column in Note (Note.ListOrderNumber) that I would like to sort by in addition to coalesce.

I know it doesn't work to just add in an order by prior to returning, but is there a way to add this in?

EXAMPLE DATA

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

Currently retrieves exactly as stated there. Adding ORDER BY Note.ListOrderNumber after the Where clause only produces a single result:

Note 2, Position 3

Your function is currently returning a VARCHAR(MAX) - and the SELECT statement sets the variable to 1 rows fields (probably the first row). This will always return 1 varchar field. If you wish to return all the rows you must either do one of two things (depends on how this fits into your other code as you may need to change the calling procedure):

Option 1: Create a cursor and loop through your SELECT statement and keep appending to the variable @liststr This will then still return one long string

Option 2: Change the function to return a table eg:

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

That approach to concatenate strings does not always work as expected.

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

Use for xml instead.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM