我正在尝试创建一个 SQL 脚本,该脚本将创建一个易于更新的脚本,其中另一个人只需要更新所涉及的常量然后运行查询,但是在子选择中使用声明的变量时我遇到了麻烦。
我知道这是因为声明的变量不在子选择的范围内,但似乎无法找到解决方法。
这是当前的代码:
DECLARE @_logdb varchar(30) = 'nb_tablename';
DECLARE @_sitedb varchar(30) = 'nb_tablename_site';
DECLARE @_backtodate varchar(30) = '2012-10-10';
DECLARE @_sitename varchar(50) = 'bikehaven';
UPDATE
[@_sitedb].[dbo].[bike]
SET [bikeStatus] = 'active'
WHERE bikeID in (
SELECT
substring(
[event],
CHARINDEX('bike ID' , [event]) + LEN('bike ID '),
CHARINDEX(
')',
[event],
CHARINDEX('bike ID' , [event])
) - (CHARINDEX('bike ID' , [event]) + LEN('bike ID '))
) as 'ID'
from [@_logdb].[dbo].[logs]
where
user_name = 'john' AND
event_type = 'Deleted bike' AND
CHARINDEX('bike ID' , [event]) > 0 AND
date_time > @_backtodate AND
siteID = (
SELECT id
from [@_logdb].[dbo].[sites]
WHERE site_name = @_sitename
)
)
实际上造成麻烦的两个变量是@_backtodate
& @_sitename
,但我也知道如果我用真正的字符串替换这些变量,我会得到错误,说这[@_sitedb].[dbo].[bike]
也是一个问题。
我做了一些谷歌搜索,尝试使用临时表进行子查询以及将 SQL 定义为变量本身,然后EXEC
在其上运行命令,但无济于事。
编辑:我已经按照Andomar的指示应用了更改,方法是将查询本身拉出到声明变量中,然后运行它,这确实是对其中一个错误的修复,但是即使有了这个修复,我仍然得到 Must define scalar @_back to date
&的变量错误@_sitename
。
解决方案:Alexander Fedorenko 建议的更改最终给了我最后一点难题。在动态 SQL 中,不能通过参数将表名用作显式替换,因为这些参数非常适合实际变量值。
简而言之: - 使查询成为字符串变量。- 任何需要发生的表名替换,您可以通过字符串连接添加(意味着输出字符串需要是一个有效的查询) - 将任何变量参数传递给存储过程以进行替换SP_executesql
最终的工作代码由Alexander Fedorenko指定。