我在存储过程中收到"+附近的无效语法错误"



它告诉我在+sol_id+附近有一个不正确的语法。我不知道我做错了什么。

我正在尝试为存储过程建模,但它给我带来了一些问题,而不是完成整个工作。代码看起来像这个

CREATE PROCEDURE FindBranchVaultBalance
@sol_id varchar(50),
@acct_crncy_code varchar(50)
AS 
SELECT * 
FROM OPENQUERY (LINKEDSERVER,
'select foracid, acct_crncy_code, clr_bal_amt 
from dummy_table  
where bacid=''1010000001'' and sol_id='''''+@sol_id +''''' and acct_crncy_code='''+@acct_crncy_code+''' and del_flg=''N'' and acct_cls_flg=''N''')
GO;

我做错了什么?

编辑

我把它编辑成这个

CREATE PROCEDURE FindBranchVaultBalance
@sol_id varchar(50),
@acct_crncy_code varchar(50)
AS 
SELECT * 
FROM OPENQUERY (LINKEDSERVER,
'select foracid, acct_crncy_code, clr_bal_amt 
from dummy_table  
where bacid=''1010000001'' and sol_id='''+@sol_id+''' and acct_crncy_code='''+@acct_crncy_code+''' and del_flg=''N'' and acct_cls_flg=''N''')
GO;

正如注释中提到的,OPENQUERY()不支持使用表达式作为输入,它必须是字符串常量。

对于您的情况,查询是动态的,您需要为OPENQUERY()创建一个完整的动态查询


DECLARE @SQL NVARCHAR(MAX)
SELECT @SQL = '
select * 
from  openquery (LINKEDSERVER, 
''select foracid,acct_crncy_code,clr_bal_amt 
from  dummy_table  
where bacid  = ''''1010000001'''' 
and   sol_id = ''''' + @sol_id + ''''' 
and   acct_crncy_code = '''' + @acct_crncy_code + '''' 
and   del_flg = ''''N'''' 
and   acct_cls_flg = ''''N'''')'''
PRINT @SQL    -- print out to verify
EXEC sp_executesql @SQL    -- execute it

注:未经测试的

围绕@sol_id变量的引号太多。

该语句起的作用

select * from openquery(LINKEDSERVER,'select foracid,acct_crncy_code,clr_bal_amt from dummy_table  where bacid=''1010000001'' and sol_id=''' 
+ @sol_id + ''' and acct_crncy_code=''' 
+ @acct_crncy_code + ''' and del_flg=''N'' and acct_cls_flg=''N''')

为了诊断和调试动态SQL错误,可以使用变量并打印它来检查格式。

尝试以下构造

create procedure FindBranchVaultBalance
@sol_id varchar(50),
@acct_crncy_code varchar(50)
as 
declare @sql nvarchar(max)
set @sql=Concat('select foracid,acct_crncy_code,clr_bal_amt from dummy_table  where bacid=''1010000001'' and sol_id=''',
@sol_id, ''' and acct_crncy_code=''',
@acct_crncy_code, ''' and del_flg=''N'' and acct_cls_flg=''N''');
print @sql;
select * from OpenQuery(LINKEDSERVER, @sql);

检查Print语句的结果,如果结果正确,请尝试用@Sql变量代替构建的字符串进行测试

正如其他人所建议的,您可以使用动态SQL。

但是,必须正确地转义变量为此使用QUOTENAME。您需要使用它两次,一次用于本地动态SQL,另一次用于远程端。

CREATE PROCEDURE FindBranchVaultBalance
@sol_id varchar(50),
@acct_crncy_code varchar(50)
AS
DECLARE @query nvarchar(max) = N'
select foracid, acct_crncy_code, clr_bal_amt 
from dummy_table  
where bacid = ''1010000001'' and sol_id = ' + QUOTENAME(@sol_id, '''') + N' and
acct_crncy_code = ' + QUOTENAME(@acct_crncy_code, '''') + N' and
del_flg = ''N'' and acct_cls_flg = ''N''
';
DECLARE @sql nvarchar(max) = N'
SELECT * 
FROM OPENQUERY (LINKEDSERVER, N' + QUOTENAME(@query, '''') + N'  )
';
EXEC @sp_executesql @sql;
GO

如果可能的话,我建议您考虑将此操作作为标准的链接服务器查询它要简单得多,不需要动态查询,而且不太容易出错。

CREATE PROCEDURE FindBranchVaultBalance
@sol_id varchar(50),
@acct_crncy_code varchar(50)
AS
select foracid, acct_crncy_code, clr_bal_amt 
from LINKEDSERVER.yourdb..dummy_table  
where bacid = '1010000001' and sol_id = @sol_id and
acct_crncy_code = @acct_crncy_code and
del_flg = 'N' and acct_cls_flg = 'N';
GO

最新更新