[英]Must declare the scalar variable error in subselect SQL
我正在尝试创建一个SQL脚本,它将创建一个很好的易于更新的脚本,其中另一个人只需要更新所涉及的常量然后运行查询,但是当在子选择中使用声明的变量时我遇到了麻烦。
我知道这是因为声明的变量不在sub select的范围内,但似乎无法解决变通方法。
这是目前的代码:
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的指示应用了更改,将查询本身拉出到声明变量然后运行它,这确实是其中一个错误的修复,但即使使用该修复,我仍然得到必须定义标量@_back to date
和@_sitename
变量错误。
解决方案: Alexander Fedorenko提出的改变最终给了我最后一点难题。 表名不能用作动态SQL中的参数的显式替换,这些参数完全适用于实际的变量值。
简而言之: - 使查询成为字符串变量。 - 需要发生的任何表名替换,您可以通过字符串连接添加(意味着输出字符串需要是有效的查询) - 将任何变量参数传递给存储过程SP_executesql
最终的工作代码由Alexander Fedorenko指定。
您不能将变量用作表名。 所以这不起作用:
from [@_logdb].[dbo].[logs]
如果您真的想要变量表名,唯一的选择是动态SQL。 使用SQL创建nvarchar(max)
变量,并使用sp_executesql
或exec
运行它。
declare @sql nvarchar(max)
set @sql = 'select * from ' + @tablename
exec (@sql)
过程sp_executesql允许使用参数。 使用sp_executesql
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';
DECLARE @_SQL nvarchar(max)
SET @_SQL = '
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
)
)'
EXEC sp_executesql @_SQL, N'@_backtodate varchar(30), @_sitename varchar(50)', @_backtodate, @_sitename
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.