我需要获取位于另一个数据库中的表的列名。以下脚本适用于活动数据库,但我需要针对同一服务器实例中的另一个数据库运行它:
SELECT @ColumnList =
CASE
WHEN @ColumnList IS NULL THEN name
WHEN @ColumnList IS NOT NULL THEN @ColumnList + ',' + name
END
FROM sys.columns
WHERE object_id = Object_Id(@TableName);
以下是问题所在...数据库在编译时未知,会在运行时传递给存储过程。因此,我认为没有别的选择,只能使用动态SQL。过去我曾尝试在动态SQL脚本中使用Use [DBName]
,但总是遇到问题,直到我意识到我可以这样做:
SET @SQL = 'SELECT Foo FROM Bar'
SET @sp_executesql = quotename(@DatabaseName) + '..sp_executesql'
EXECUTE @sp_executesql @SQL
但是我在使用上述脚本时遇到了困难,不知道该如何实现。我的第一次尝试如下所示:
-- @DatabaseName and @TableName are parameters of the
-- stored procedure containing this script
DECLARE @ColumnList nvarchar(max),
@SQL nvarchar(max),
@sp_executesql nvarchar(max) = quotename(@DatabaseName) + '..sp_executesql';
SET @SQL =
'SELECT @ColumnList =
CASE
WHEN @ColumnList IS NULL THEN name
WHEN @ColumnList IS NOT NULL THEN @ColumnList + '','' + name
END
FROM sys.columns
WHERE object_id = Object_Id(@TableName);'
EXECUTE @sp_executesql @SQL,
N'@ColumnList = nvarchar(max) OUT, @TableName = sysname',
@ColumnList, @TableName
但是当它运行时,它不将@ColumnList
解释为有效的变量。我漏掉了什么?
EXEC sp_executesql @sql
,而不是EXEC @sp_executesql @sql
。 - Aaron BertrandEXEC @sp_executesql @sql
使用嵌套动态 SQL 对@DatabaseName
调用sp_executesql
。这个方法来源于这里。 - Kenneth Cochran@sp_executesql
的地方使用它,而且恰好在存储过程sp_executesql
被期望的地方使用它,这很奇怪。嵌套动态SQL似乎在这里并不需要...你试过我的代码了吗? - Aaron Bertrand