【发布时间】:2017-04-13 06:25:24
【问题描述】:
由于等级较高的论坛用户建议我将我的问题作为与此相关的新问题发布:declare variable for query string。
我在这里使用动态查询是因为我希望能够使用变量(我在涉及参数嗅探的实验中需要它)。我的查询如下所示:
DECLARE @i NVARCHAR(10)
SET @i = 'POL'
DECLARE @sql VARCHAR(MAX)
SET @sql = 'SELECT
a.something1,
b.something2,
c.something3
FROM
aaa a WITH(NOLOCK)
LEFT JOIN bbb b WITH(NOLOCK) ON....
LEFT JOIN ccc c WITH(NOLOCK) ON....
WHERE
a.somethingelse = ''aa''
AND
((a.entirelysomethingelse=''aaa'') OR (a.entirelysomethingelse=''aaaa''))
AND
b.anotherdifferentsomething != 41
AND
c.yetanotherdifferentthing LIKE(''%@%'')
AND
c.datafromvariablewannabe = (@i)
GROUP BY
...
ORDER BY
...'
EXECUTE (@SQL)
当我想执行查询时,出现如下错误:
'Msg 137, Level 15, State 2, Line 28
Must declare the scalar variable "@i".'
当我将变量@i 的声明移到@sql 中时,它就可以工作了。仍然我不认为这是我想要的。我做错了什么还是必须看起来像这样?:
DECLARE @sql VARCHAR(MAX)
SET @sql = '
DECLARE @i NVARCHAR(10)
SET @i = 'POL'
SELECT
a.something1,
b.something2,
c.something3
FROM
aaa a WITH(NOLOCK)
LEFT JOIN bbb b WITH(NOLOCK) ON....
LEFT JOIN ccc c WITH(NOLOCK) ON....
WHERE
a.somethingelse = ''aa''
AND
((a.entirelysomethingelse=''aaa'') OR (a.entirelysomethingelse=''aaaa''))
AND
b.anotherdifferentsomething != 41
AND
c.yetanotherdifferentthing LIKE(''%@%'')
AND
c.datafromvariablewannabe = (@i)
GROUP BY
...
ORDER BY
...'
EXECUTE (@SQL)
我的代码中是否有任何错误,所以我收到 MSG137 错误,或者这只是我想在这里做的不可能完成的任务。
我不想从此查询创建存储过程。我希望能够使用变量但不依赖存储过程。
对于涉及我之前在超链接问题中的问题的问题,我向管理员/论坛用户道歉。
【问题讨论】:
-
这是什么意思
When I moved declaration of variable @i into the @sql then it sorta works. Still I don't think It's what I wanted -
变量的作用域是一个批次,而 exec 在单独的批次中运行,所以你必须将它包含在同一个 @sql 中
-
我的意思是我得到了很好的结果,但获得这些结果的方法不是我正在寻找的方法。我不知道我必须“打破”查询字符串(正如@mortb 所建议的那样),这样我的变量才能被“加载”?在那里。
-
离题但值得一读:the downside of using NoLock。我相信您有自己的理由,但值得强调的是,NoLock 可以返回重复项、已删除记录以及您在生产查询中最可能不想要的其他内容。有关将变量传递到动态 SQL 的替代方法,请参阅此 question。
-
我知道 nolock 有它的缺点,但在这里使用它是我的主管的命令,在这种情况下它不会造成任何伤害。不过还是有用的评论。
标签: sql sql-server tsql dynamic-sql