Динамическое поведение sql и spexecutesql - PullRequest
2 голосов
/ 07 августа 2011

У меня есть таблица типа

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

Как правило, я не знаю количество столбцов (в коде @d здесь 4), чтобы получить строку в виде:

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

Для этого я делаю:

 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

Так что, если я делаю

select @CommaString;

enter image description here

Почему не @CommaString намомент выбора, возвращающий строку, если при выполнении sp_executesql он печатает правильно?

1 Ответ

3 голосов
/ 07 августа 2011

Возможно, я что-то упускаю из-за того, как работает sp_executesql, но разве вам не нужно что-то вроде 'SELECT @CommaString = ...' в @template, чтобы он назначал строку запятой параметру out?

Просто чтобы уточнить, я думаю, вам нужно что-то вроде:

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

В качестве более простого примера, что-то вроде этого, возможно, легче прочитать / понять, что я имею в виду:

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

Кстати, я обычно видел такие вещи для конкатенации строк:

DECLARE @MyString varchar(max)

SET @MyString = ''

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