首先,我知道之前已经解决了这个问题 - 我已经完成了我的研究,正如您将在下面看到的那样,我尝试了多个版本来实现这一目标。
我正在尝试设置一个查询,其中可以设置变量并且查询使用该变量。这是我的代码:
-- Set to the category you want to check
DECLARE @validationCategory varchar = 'Dept'
DECLARE @validationTable varchar = (SELECT ValidationTable FROM MasterFiles..Categories WHERE Category = @validationCategory AND TableToValidate = 'xref')
DECLARE @validationField varchar = (SELECT ValidationField FROM MasterFiles..Categories WHERE Category = @validationCategory AND TableToValidate = 'xref')
EXEC('
SELECT DISTINCT Category
FROM MasterFiles.dbo.xref
WHERE Category = ''' + @validationCategory + '''
AND (new_value NOT IN (SELECT ''' + @validationField + '''
FROM ' + @validationTable + ')
AND old_value NOT LIKE ''%New%''
OR (new_value IS NULL OR new_value = ''''))
)'
)
当我运行它时,我收到此错误:
Msg 102,Level 15,State 1,Line 6
')'附近的语法不正确。
我能够从错误中收集到的最多的是15级意味着用户可以纠正错误。大!现在,如果我能确切地找出语法问题是什么......
我怀疑这可能是因为@validationTable
是表,而不是字符串,但我不确定如何解决这个问题。
经过一些研究后,我尝试将查询放入变量中,然后对变量运行EXEC:
--...
DECLARE @Query nvarchar
SET @Query = '
SELECT DISTINCT Category
FROM MasterFiles.dbo.xref
WHERE Category = ''' + @validationCategory + '''
AND (new_value NOT IN (SELECT ''' + @validationField + '''
FROM ' + @validationTable + ')
AND old_value NOT LIKE ''%New%''
OR (new_value IS NULL OR new_value = ''''))
)'
EXEC(@query)
运行没有错误,但我没有得到任何输出 - 只是它成功运行。
在进行了一些关于将查询的输出作为EXECuted变量的研究之后,我想出了这个(从我在SO上找到的一个例子):
--...
DECLARE @vQuery nvarchar
SET @vQuery = '
SELECT DISTINCT Category
FROM MasterFiles.dbo.xref
WHERE Category = ''' + @validationCategory + '''
AND (new_value NOT IN (SELECT ''' + @validationField + '''
FROM ' + @validationTable + ')
AND old_value NOT LIKE ''%New%''
OR (new_value IS NULL OR new_value = ''''))
)'
DECLARE @vi int
--DECLARE @vQuery varchar(1000)
EXEC SP_EXECUTESQL
@query = @vQuery
, @params = '@vi int output'
, @vi = @vi output
SELECT @vi
导致此错误:
Msg 214,Level 16,State 3,Procedure sp_executesql,Line 1
过程需要'ntext / nchar / nvarchar'类型的参数'@parameters'。
那么正确的方法是什么呢?在我对此的研究中,我看到了使用存储过程的示例。我希望能够在没有存储过程的情况下执行此操作,因为将通过将查询复制/粘贴到客户端的SSMS中的查询窗口,设置表变量并运行查询来使用此查询。然后转到下一个客户端做同样的事情。
我需要能够在安装了SQL Server 2008或2012的服务器上运行它。
答案 0 :(得分:1)
这是你的第一次尝试......
SELECT DISTINCT Category
FROM MasterFiles.dbo.xref
WHERE Category = 'D'
AND (new_value NOT IN (SELECT 'M' FROM M)
AND old_value NOT LIKE '%New%'
OR (new_value IS NULL OR new_value = '')
)
) -- extra
这有一个额外的)
,并没有多大意义
除此之外......你将变量声明为VARCHAR,长度不等于1个字符
DECLARE @validationCategory varchar = 'Dept'
DECLARE @validationTable varchar = (SELECT ValidationTable FROM MasterFiles..Categories WHERE Category = @validationCategory AND TableToValidate = 'xref')
DECLARE @validationField varchar = (SELECT ValidationField FROM MasterFiles..Categories WHERE Category = @validationCategory AND TableToValidate = 'xref')
在这种情况下, @validationCategory
等于'D'。确保为varchars添加适当的长度
答案 1 :(得分:0)
首先测试,打印查询变量(@vQuery),将其复制并粘贴到新的查询窗口中并执行它。你要确定错误的确切位置。
我认为您需要这样做,就像使用@validationTable一样:
DECLARE @vQuery nvarchar
SET @vQuery = '
SELECT DISTINCT Category
FROM MasterFiles.dbo.xref
WHERE Category = ''' + @validationCategory + '''
AND (new_value NOT IN (SELECT ' + @validationField + '
FROM ' + @validationTable + ')
AND old_value NOT LIKE ''%New%''
OR (new_value IS NULL OR new_value = ''''))
)'
答案 2 :(得分:0)
如果@validationTable是一个表变量而不是一个字符串,那么你需要以不同的方式与它进行交互。
而不是
(
SELECT ''' + @validationField + '''
FROM ' + @validationTable + '
)
尝试
(
SELECT ''' + QUOTENAME(@validationField) + '''
FROM @validationTable
)
SQL Server现在将@validationTable识别为对象。我怀疑,阅读错误消息,您的查询有其他问题。尝试输出所有动态SQL语句并在调试时直接测试它们。
我添加了QUOTENAME功能,因为这有助于保护您免受SQL Injection Attacks的攻击。这是一个很大的话题,但非常值得一读。