You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server动态SQL报错(疑单引号问题):请求协助排查修正

排查动态SQL中的语法错误(Msg 156)

嘿,我一眼就瞅出你代码里的问题啦——你猜的没错,就是单引号惹的祸!咱们一步步来拆解和修复:

错误根源

你的动态SQL拼接时犯了两个小问题:

  • 单引号缺失:@policy是带通配符的字符串值('TTY%'),但直接拼接后,SQL语句里会变成like TTY%——没有单引号包裹的话,SQL会把TTY当成列名/标识符,而非字符串常量,这直接触发了Incorrect syntax near the keyword 'or'的语法错误。
  • 笔误:第二个when分支里的第三个条件写成了[policy2] like,应该是[policy3] like,虽然这不会触发当前错误,但会导致逻辑判断不准确。

修复方案

方案1:快速修复字符串拼接(不推荐,存在SQL注入风险)

给@policy的前后加上转义的单引号(SQL里用两个单引号表示一个实际的单引号),同时修正笔误:

Declare @policy NVARCHAR(MAX);
Declare @account_list NVARCHAR(MAX);
Declare @sql NVARCHAR(MAX);

Set @policy ='TTY%';
Set @account_list='18000,19000';

Set @sql = 'Select case 
            when [Debit_Account] in ('+@account_list+') and ([policy1] like '''+@policy+''' or [policy2] like '''+@policy+''' or [policy3] like '''+@policy+''') 
            then -[Amount] 
            when [Credit_Account] in ('+@account_list+') and ([policy1] like '''+@policy+''' or [policy2] like '''+@policy+''' or [policy3] like '''+@policy+''') 
            then [Amount] 
            else 0 end as [Amount] 
            from CTGS 
            where [Debit_Account] in ('+@account_list+') or [Credit_Account] in ('+@account_list+')';

EXEC sp_executesql @sql;

方案2:参数化动态SQL(强烈推荐,安全且易维护)

直接拼接字符串不仅容易出语法错误,还会带来SQL注入风险(比如恶意用户传入18000); drop table CTGS;--作为@account_list值)。用参数化查询可以彻底解决这些问题:

Declare @policy NVARCHAR(MAX);
Declare @account_list NVARCHAR(MAX);
Declare @sql NVARCHAR(MAX);

Set @policy ='TTY%';
Set @account_list='18000,19000';

-- 使用STRING_SPLIT拆分逗号分隔的账号列表,同时将@policy作为参数传入
Set @sql = 'Select case 
            when [Debit_Account] in (select value from string_split(@account_list, '','')) and ([policy1] like @policy or [policy2] like @policy or [policy3] like @policy) 
            then -[Amount] 
            when [Credit_Account] in (select value from string_split(@account_list, '','')) and ([policy1] like @policy or [policy2] like @policy or [policy3] like @policy) 
            then [Amount] 
            else 0 end as [Amount] 
            from CTGS 
            where [Debit_Account] in (select value from string_split(@account_list, '','')) or [Credit_Account] in (select value from string_split(@account_list, '',''))';

-- 传递参数给sp_executesql
EXEC sp_executesql @sql, 
                   N'@policy NVARCHAR(MAX), @account_list NVARCHAR(MAX)',
                   @policy = @policy,
                   @account_list = @account_list;

注:STRING_SPLIT适用于SQL Server 2016及以上版本,如果你的版本更低,可以用自定义的字符串拆分函数代替。

内容的提问来源于stack exchange,提问作者Dinh Quang Tuan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:47:39