在动态SQL中使用局部变量不起作用

Fre*_*ers 4 sql sql-server dynamic-sql

这个使用参数的静态查询返回一行:

DECLARE @sqltext nvarchar(max)
DECLARE @status varchar(100)
SET @status = 'Active: Complete'

select * from status where StatusTitle = @status and type_id = 800
Run Code Online (Sandbox Code Playgroud)

但是,如下所示在动态SQL查询中使用该参数不会返回任何行:

SET @sqltext = 'SELECT s.StatusID
FROM   [Status] s
WHERE  (
( s.StatusTitle ='' + @status + '' )
AND s.[type_id] = 800  )'

EXECUTE sp_executesql @sqltext
Run Code Online (Sandbox Code Playgroud)

我知道WHERE子句有问题.我无法弄清楚如何纠正它.

TT.*_*TT. 5

您需要格式化@status为语句.使用sp_executesql从另一个范围创建新范围和局部变量来执行语句将不可见.

在您的陈述中,您可以通过添加额外的引号来解决此问题@status.但是为了防止SQL注入,首先需要用两个单引号替换单引号@status.

SET @status=REPLACE(@status,'''','''''');
SET @sqltext = 'SELECT s.StatusID
FROM   [Status] s
WHERE  (
( s.StatusTitle =''' + @status + ''' )
AND s.[type_id] = 800  )'

EXECUTE sp_executesql @sqltext;
Run Code Online (Sandbox Code Playgroud)

更好的是提供sp_executesqlINPUT参数.这样就不需要额外的引号和内容,并且这种方式可以保证防止SQL注入.

SET @sqltext = 'SELECT s.StatusID
FROM   [Status] s
WHERE  (
( s.StatusTitle = @status )
AND s.[type_id] = 800  )'

EXECUTE sp_executesql @sqltext, N'@status VARCHAR(100)', @status;
Run Code Online (Sandbox Code Playgroud)

  • 如果您有多个参数,您可能会发现这很有帮助 /sf/answers/1993689421/ (2认同)