edgarmtze
edgarmtze

Reputation: 25038

Dynamic sql and spexecutesql behavior

I have a table like

c1  c2    c3  c4
-----------------
2    1    7    13 
9    2    8    14
1    3    9    15
5    4   10    16
2    5   11    17
11   6   12    18

As in general I would not know the number of columns (in the code @d here 4) to get a string in the form:

2,9,1,5,2,11,  1,2,3,4,5,6,  7,8,9,10,11,12,  13,14,15,16,17,18  

To do so I am doing:

 DECLARE  @d INT
         ,@counterI INT
         ,@template AS nvarchar(max) 

   SET  @d  = 4;       
   SET  @counterI   = 1;
   Set  @template = 'SELECT STUFF( 
                         (  SELECT  '','' + CAST([col] AS VARCHAR) FROM (';                        
   WHILE (@counterI < @d) BEGIN
        SET @template += ' SELECT [c'+CAST(@counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] UNION ALL ';
        SET @counterI   = @counterI + 1; 
   END
  Set  @template += ' SELECT [c'+CAST(@counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] ' 
  Set  @template += ') alldata FOR XML PATH('''')  )  ,   1  ,   1  ,  '''' )';    

declare @CommaString varchar(max)
set @CommaString = ''
exec sp_executesql @template, N'@CommaString varchar(max) out', @CommaString out

So if I do

select @CommaString;

enter image description here

Why is not @CommaString at the moment of selecting it returning the string if when doing the sp_executesql it is printing it right?

Upvotes: 2

Views: 278

Answers (1)

James
James

Reputation: 293

I may be missing something about how sp_executesql works, but don't you need something like 'SELECT @CommaString = ...' in @template, so that it assigns the comma string to the out parameter?

Just to clarify, I think you need something like:

DECLARE  @d INT
        ,@counterI INT
        ,@template AS nvarchar(max) 

SET  @d  = 4;       
SET  @counterI   = 1;
Set  @template = 'SELECT @CommaString = STUFF( 
                     (  SELECT  '','' + CAST([col] AS VARCHAR) FROM (';                        
WHILE (@counterI < @d) BEGIN
    SET @template += ' SELECT [c'+CAST(@counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] UNION ALL ';
    SET @counterI   = @counterI + 1; 
END
Set  @template += ' SELECT [c'+CAST(@counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] ' 
Set  @template += ') alldata FOR XML PATH('''')  )  ,   1  ,   1  ,  '''' )';    

declare @CommaString varchar(max)
set @CommaString = ''
exec sp_executesql @template, N'@CommaString varchar(max) out', @CommaString = @CommaString out

As a simpler example, something like this is perhaps easier to read/see what I mean:

declare @CommaString varchar(max)
set @CommaString = ''
exec sp_executesql 'SELECT @CommaString = ''1,2,3''', '@CommaString varchar(max) out', @CommaString = @CommaString out

Incidentally, I've usually seen this kind of thing for string concatenation:

DECLARE @MyString varchar(max)

SET @MyString = ''

SELECT @MyString = @MyString + ',' + MyColumn
  FROM MyTable

Upvotes: 3

Related Questions