简体   繁体   English

SQL函数,粗化和排序

[英]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. 此函数从数据库返回“ Notes”并对其进行编译,但是,除了合并之外,Note(Note.ListOrderNumber)中还有另一列我希望进行排序。

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: 在Where子句之后添加ORDER BY Note.ListOrderNumber仅产生一个结果:

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). 您的函数当前正在返回VARCHAR(MAX)-SELECT语句将变量设置为1行字段(可能是第一行)。 This will always return 1 varchar field. 这将始终返回1 varchar字段。 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 选项1:创建一个游标并遍历SELECT语句,然后继续追加到变量@liststr,这将仍然返回一个长字符串

Option 2: Change the function to return a table eg: 选项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

That approach to concatenate strings does not always work as expected. 这种连接字符串的方法并不总是能按预期工作。

PRB: Execution Plan and Results of Aggregate Concatenation Queries Depend Upon Expression Location PRB:执行计划和聚合连接查询的结果取决于表达式的位置

Use for xml instead. 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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