I have noticed that most people come up with the following solution to build a string in T-SQL:
WITH [Numbers] AS (
SELECT TOP(10) [n]
FROM [Nums]
)
SELECT @message = COALESCE(@message, '') + ', ' + CAST([n] AS nvarchar(2))
FROM [Numbers];
SELECT @message = STUFF(@message, 1, 2, '');
SELECT @message;
Important! Microsoft has no official documentation describing this aggregate concatenation
technique that is based on the assignment SELECT syntax. The behavior described here is
based on observation alone. The current implementation of the ConcatOrders function doesn’t
incorporate
an ORDER BY clause and does not guarantee the order of concatenation. According
to a blog entry by Microsoft’s Conor Cunningham, it seems that SQL Server will respect an
ORDER BY clause if specified (http://blogs.msdn.com/sqltips/archive/2005/07/20/441053.aspx).
Conor is a very credible source, but I should stress that besides
this blog entry I haven’t found
any official documentation describing how a multi-row assignment
SELECT should behave—with
or without an ORDER BY clause.
With the aid of FOR XML PATH (as mentionned in Inside Microsoft SQL Server 2008: T-SQL Programming we can solve this problem using a documented approach:
WITH [Numbers] AS (
SELECT TOP(10) [n]
FROM [Nums]
)
SELECT @message = (SELECT ', ' + CAST([n] AS nvarchar(2)) AS 1[/text]
FROM [Numbers]
FOR XML PATH(''));
SELECT @message = STUFF(@message, 1, 2, '');
SELECT @message;