我有以下SQL Server存储过程:
CREATE PROCEDURE ispsDcOhcAgg @TmpTableName NVARCHAR(50), @ListItem NVARCHAR(50)
AS
IF EXISTS (SELECT name
FROM sys.tables
WHERE name = @TmpTableName)
DROP TABLE @TmpTableName; -- This will not work.
GO
这显然不起作用(参见上面的snippit中的评论)。我发现解决这个问题的唯一(也是非常丑陋的)方法是执行以下操作
CREATE PROCEDURE ispsDcOhcAgg @TmpTableName NVARCHAR(50), @ListItem NVARCHAR(50)
AS
DECLARE @SQL NVARCHAR(4000)
SET @SQL = N'IF EXISTS (SELECT name ' +
N'FROM sys.tables ' +
N'WHERE name = N' + N'''' + @TmpTableName + N''') ' +
N'DROP TABLE ' + @TmpTableName + N';'
EXEC sp_executesql @SQL;
GO
真正发臭,对于大型存储过程来说,这太可怕了!
还有另一种我不知道的方法吗?
感谢您的时间。
答案 0 :(得分:6)
不,如果要像这样动态使用表名,则需要使用动态SQL。
所以你应该确保你没有打开令人讨厌的SQL注入风险!
尝试这样的事情:
SET @SQL = 'IF EXISTS (SELECT name ' +
N'FROM sys.tables ' +
N'WHERE name = @TableName) ' +
N'DROP TABLE ' + QUOTENAME(@TmpTableName) + ';'
EXEC sp_executesql @SQL, N'@TableName sysname', @TmpTableName;
答案 1 :(得分:2)
不,如果要确定要在运行时删除的表,除了动态SQL之外别无选择。
有一种略微不那么丑陋的方式:你只需要动态SQL用于需要动态的命令(DROP
命令):
DECLARE @SQL NVARCHAR(100)
IF EXISTS (SELECT name
FROM sys.tables
WHERE name = @TmpTableName)
BEGIN
SET @SQL = N'DROP TABLE ' + @TmpTableName + N';'
EXEC sp_executesql @SQL;
END