2012-07-13 43 views
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 

从而真正太臭和大型存储过程,这是可怕的!

有没有另一种方法做到这一点,我不知道?

感谢您的时间。

+1

没有,比使用动态SQL没有其他办法为了达成这个。 – 2012-07-13 12:03:56

+0

if exists部分工作正常,因为内联语句带有一个变量,它只是一个'where'子句,如果条件满足需要动态执行'drop' – 2012-07-13 12:05:46

回答

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

+1对于'sysname'和'QUOTENAME ' – 2012-07-13 12:10:57

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