2012-07-19 68 views
1

所有,我有以下動態SQL查詢奇數動態SQL錯誤

DECLARE @TableName NVARCHAR(255); 
SET @TableName = 'BadCodesErrSumm'; 
DECLARE @DropSql NVARCHAR(MAX); 
SET @DropSql = 
    'IF EXISTS (SELECT * 
       FROM Report.sys.objects 
       WHERE name = ''' + @TableName + ''' AND type = ''U'') 
    DROP TABLE [IPAReport]..[' + @TableName + '];' 
PRINT @DropSql; 
EXEC @DropSql; 

這將產生以下錯誤

Msg 203, Level 16, State 2, Line 11 
The name 'IF EXISTS (SELECT * 
       FROM Report.sys.objects 
       WHERE name = 'BadCodesErrSumm' AND type = 'U') 
      DROP TABLE [Report]..[BadCodesErrSumm];' is not a valid identifier. 

然而,打印輸出

IF EXISTS (SELECT * 
      FROM Report.sys.objects 
      WHERE name = 'BadCodesErrSumm' AND type = 'U') 
DROP TABLE [Report]..[BadCodesErrSumm]; 

執行精細。 我錯過了什麼?

謝謝你的時間。

+2

不要使用'[ '+ @tablename +']'。總是使用'quotename(@TableName,'[')'。 – GSerg 2012-07-19 15:26:45

+0

我總是懶惰,因爲它是一個相當專業的WinForms應用程序。我認爲不會有注射攻擊的危險,但我認爲我應該始終以最佳做法來做到這一點。感謝您指出了這一點。 – MoonKnight 2012-07-19 15:37:30

+0

以及爲什麼不只是'從Sys.tables中選擇OBJECT_ID其中name ='您的表名'# 以及爲什麼'從IPAReport.tables中選擇OBJECT_ID其中name ='Your Table Name''。抱歉,我無法理解「IPAReport」的含義? – 2012-07-19 17:59:11

回答

5

使用

EXEC sp_executesql @DropSql; 

或者

EXEC(@DropSql); 

也就是說,一對夫婦的建議:

DECLARE @TableName NVARCHAR(255); 

SET @TableName = N'BadCodesErrSumm';  -- always use N prefix on Unicode strings 

DECLARE @DropSql NVARCHAR(MAX); 

SET @DropSql = N'IF EXISTS (SELECT 1  -- again, N prefix 
       FROM IPAReport.sys.tables -- use sys.tables to avoid 'U' check 
       WHERE name = @TableName) -- use a proper parameter 
    DROP TABLE [IPAReport]..' 
     + QUOTENAME(@TableName) + ';'  -- QUOTENAME is safer as @GSerg pointed out 

PRINT @DropSql; 

EXEC sp_executesql @DropSql, N'@TableName NVARCHAR(255)', @TableName; 
+0

因此,在'' - 使用正確的參數'這一行'參數被定義爲什麼? – MoonKnight 2012-07-19 15:44:45

+0

@Killercam它在腳本的最後一行定義,作爲sp_executesql的第二個參數的一部分。 – 2012-07-19 15:48:38