【问题标题】:I am getting 'Invalid syntax error near +' , in stored procedures我在存储过程中收到“+ 附近的无效语法错误”
【发布时间】:2021-07-11 08:01:46
【问题描述】:

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

【问题讨论】:

  • sol_id='''''+ 看起来不正确,但第二个是 acct_crncy_code='''+
  • 我最初有'''+,在我决定添加'''''+之前给了我错误
  • 你不应该将它用于两个变量,而不仅仅是第一个变量吗?
  • 我现在编辑了它。请查看修改。
  • openquery() 不支持使用表达式作为查询参数。它必须是一个常量字符串。对于您的情况,您需要动态生成整个openquery() 语句

标签: sql-server stored-procedures


【解决方案1】:

正如评论中提到的,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

注意:未经测试

【讨论】:

    【解决方案2】:

    @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 变量替换为构建的字符串来进行测试

    【讨论】:

    • 仍然是相同的错误消息 102,级别 15,状态 1,过程 FindBranchVaultBalance,第 8 行 '+' 附近的语法不正确。
    • 已编辑并添加了进一步的建议以打印和检查动态 sql 查询的结果。
    【解决方案3】:

    正如其他人所建议的,您可以使用动态 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 2022-01-06
      • 1970-01-01
      相关资源
      最近更新 更多