3

我有以下 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

这显然行不通(请参阅上面的代码片段中的评论)。我发现解决这个问题的唯一(也是非常丑陋的)方法是执行以下操作

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

这真的很臭,对于大型存储过程来说,这太可怕了!

还有另一种我不知道的方法吗?

谢谢你的时间。

4

2 回答 2

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;
于 2012-07-13T12:03:54.770 回答
2

不,如果您想确定要在运行时删除的表,则没有动态 SQL 的替代方法。

There is a slightly less ugly way: you only use dynamic SQL for the command that needs to be dynamic (the DROP command):

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
于 2012-07-13T12:07:31.797 回答