在动态 sql 脚本中使用变量

Using variables within a dynamic sql script

我目前正在编辑一个过程,我们称它为 A,它对在过程 B 中创建的临时 table 进行一些操作(因此过程 B 调用 A)。过程B包含一个参数,即所述临时table.

的名称

也就是说,我们需要将临时 table 的所有列(在 CSV 中)检索到一个变量中。由于每次名称都不一样,我需要使用动态 SQL.

这是我的:

-- Input parameters: @sTempTableName VARCHAR(MAX) --> Name of the temporary table to alter

DECLARE 
    @sColumns               AS NVARCHAR(MAX) = '',
    @sAlterTableDynamicSQL  AS VARCHAR(MAX)

            
SET @sAlterTableDynamicSQL =
'
    SELECT @sColumns = @sColumns + [name] + N'','' FROM Tempdb.Sys.Columns WHERE [object_id] = object_id(''tempdb..' + @sTempTableName + ''')
'

PRINT (@sAlterTableDynamicSQL)
EXEC (@sAlterTableDynamicSQL)

这没有说明我需要声明 @sColumns 因为它不存在(我猜变量不在连接之间共享)。我怎样才能做到这一点?我想我可以创建另一个临时 table 来保存该 CSV,但我认为应该有另一种方式。

您应该使用 sp_executesql 语句。它看起来像这样:

DECLARE 
    @sColumns                NVARCHAR(MAX),
    @sAlterTableDynamicSQL   NVARCHAR(MAX),
    @temptableid INT = 3;
        
SELECT @sAlterTableDynamicSQL =
    N'SELECT @sColumns = STRING_AGG([name], '','') FROM Tempdb.Sys.Columns WHERE [object_id] =  + CAST(@temptableid AS VARCHAR(10))';

EXEC sp_executesql @sAlterTableDynamicSQL, N'@sColumns NVARCHAR(MAX) OUTPUT, @temptableid INT', @sColumns = @sColumns OUTPUT, @temptableid = @temptableid

SELECT @sColumns;

您可以通过 sp_executesql

将变量传递给动态 SQL
  • 请注意,您应该始终使用 QUOTENAME 来转义对象名称
  • 此外,动态 SQL 变量应始终 nvarchar
  • 您也不应该使用变量合并来聚合,而是使用 STRING_AGGFOR XML
DECLARE 
    @sColumns               AS NVARCHAR(MAX) = '',
    @sAlterTableDynamicSQL  AS NVARCHAR(MAX),
    @sGUID                  AS VARCHAR(MAX) = CAST(NEWID() AS VARCHAR(MAX))

            
SET @sAlterTableDynamicSQL =
'
SELECT @sColumns = STRING_AGG(CAST([name] AS nvarchar(max)), N'','')
FROM Tempdb.sys.columns
WHERE [object_id] = object_id(N''tempdb..' + QUOTENAME(@sNomTableTemporaire, '''') + ''');
';

PRINT (@sAlterTableDynamicSQL);

EXEC sp_executesql
  @sAlterTableDynamicSQL,
  N'@sColumns nvarchar(max) OUTPUT'
  @sColumns = @sColumns OUTPUT;

但实际上您根本不需要动态 SQL。 您可以将 table 名称直接传递给 object_id()

DECLARE 
    @sColumns               AS NVARCHAR(MAX) = '',
    @sAlterTableDynamicSQL  AS NVARCHAR(MAX),
    @sGUID                  AS VARCHAR(MAX) = CAST(NEWID() AS VARCHAR(MAX))
            
SELECT @sColumns = STRING_AGG(CAST([name] AS nvarchar(max)), N',')
FROM Tempdb.sys.columns
WHERE [object_id] = object_id(N'tempdb..' + QUOTENAME(@sNomTableTemporaire));

For SQL Server 2016 and earlier, you can use the FOR XML PATH('') method