在动态 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_AGG
或 FOR 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
我目前正在编辑一个过程,我们称它为 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
- 请注意,您应该始终使用
QUOTENAME
来转义对象名称 - 此外,动态 SQL 变量应始终
nvarchar
- 您也不应该使用变量合并来聚合,而是使用
STRING_AGG
或FOR 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