它告诉我在+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