EXEC sp_executesql无法按预期工作

问题描述 投票:0回答:2

EXEC SP_EXECUTESQL给了我错误

必须声明表变量“@TABLE”

我们怎么解决这个问题?

TESTTABLE包含6个表名。我必须从TESTTABLES获取所有表名,并根据匹配条件从所有6个表中删除记录。

CREATE PROCEDURE TEST_SCHEMA.TEST_SP
@P_DATE   CHAR(10),
@P_TIME   CHAR(8),
@P_MILSEC CHAR(6),
@P_RECORD   CHAR(1),
@P_NODE     CHAR(2)

AS

BEGIN

DECLARE @SQL AS NVARCHAR(MAX);
DECLARE @zTABLE VARCHAR(10);
DECLARE @ParmDefinition NVARCHAR(MAX);

DECLARE TABLES_LIST CURSOR FOR SELECT TBL_NAME FROM TESTTABLE WITH 
(NOLOCK);

OPEN TABLES_LIST

FETCH FROM TABLES_LIST INTO @zTABLE

WHILE @@FETCH_STATUS = 0  

BEGIN

SET @SQL = N'DELETE FROM @TABLE WHERE DATE = @DATE AND TIME = @TIME AND 
MILSEC = @MILSEC AND RECORD = @RECORD AND NODE = @NODE';


SET @ParmDefinition = N'@TABLE varchar(10), @DATE char(10), @TIME char(8), 
@MILSEC char(6), @RECORD char(1), @NODE char(2)';

EXEC SP_EXECUTESQL @SQL, @ParmDefinition, @zTABLE, @P_DATE, @P_TIME, 
@P_MILSEC, @P_RECORD, @P_NODE;

FETCH NEXT FROM TABLES_LIST INTO @zTABLE

END

CLOSE TABLES_LIST;

DEALLOCATE TABLES_LIST; 

END

当我运行它时,它给出了上述错误。我们如何纠正这个错误?

sql sql-server tsql dynamic-sql
2个回答
2
投票

您无法参数化表名。因此,期望参数代替表名的删除查询假定您指的是名为@TABLE的表变量。

相反,您需要在查询本身中附加表名。

其中一种方法是简单地附加到SQL查询:

SET @SQL = N'DELETE FROM ' + @zTABLE + ' WHERE KEY_DATE = @KEY_DATE AND KEY_TIME = @KEY_TIME 
    AND KEY_MILSEC = @KEY_MILSEC AND RECORDCD = @RECORDCD AND CRNODE = @CRNODE';

或者,您可以使用QUOTENAME函数包装它以避免通过该变量进行SQL注入:

SET @SQL = N'DELETE FROM ' + QUOTENAME(@zTABLE) + ' WHERE KEY_DATE = @KEY_DATE AND KEY_TIME = @KEY_TIME 
    AND KEY_MILSEC = @KEY_MILSEC AND RECORDCD = @RECORDCD AND CRNODE = @CRNODE';

确保修改你的@ParmDefinition并调用SP_EXECUTESQL,因为你不再需要提供@TABLE参数。


0
投票

都:

SET @SQL

SET @ParmDefinition

包括@TABLE的定义。如果没有你声明它,SP就无法知道要执行什么。也许你想使用@zTABLE,但你错过了。

© www.soinside.com 2019 - 2024. All rights reserved.