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

JPA SpEL可选List参数传多值触发SQLServer语法异常求助

问题原因

抛出SQLServerException的核心原因是IN子句的集合参数缺少括号包裹:

  • 当status参数只传入单个值时,JPA的SpEL解析后会生成类似e.distrstttypecode in 'VALID'的合法SQL,所以查询可以正常运行
  • 当status传入多个值的集合时,SpEL直接将集合展开为逗号分隔的字面量,但你写的in ?#{#requestdto.getStatus}没有给参数加括号,最终生成的SQL为e.distrstttypecode in 1,2,3,不符合SQL Server语法要求(IN后的多值列表必须放在括号内),数据库解析到逗号位置时就会抛出「需要布尔类型表达式、出现非布尔类型」的错误。

另外你贴的代码存在一处笔误:@Query(value = select distinct开头的SQL语句缺少起始双引号,实际运行时会直接编译报错,需要补上。

修复方法
  1. 给IN子句的集合参数外层补充括号,修正语法问题
  2. 补充空集合判断,避免传入空列表时生成IN ()的非法SQL
  3. 建议将参数占位符的?#写法替换为JPA更兼容的:#命名参数写法,减少SpEL解析异常

修正后的完整查询代码如下:

@Query(value = "select distinct a.invn, a.accid, ac.accountCode, b.Fbusinesscode" +
            ", b.scode, i.invtype, d.dtid,  d.did " +
            " from INV.BINv a " +
            "join READONLY.Fbusiness b on a.FbusinessId =b.FbusinessId " +
            "join READONLY.Acc ac on a.accid=ac.accid " +
            "join INV.Doc c on a.invid = c.invid " +
            "join INV.Dstreq d on c.docid = d.docid " +
            "join INV.dassoc e " +
            "on d.dassocId = e.dassocId " +
            "join BLNG.InvMType AS i on e.invtypeId = i.invtypeId "+
            "where (:#{#requestdto.invoiceNumber} is null OR a.InvoiceEntityNumber = :#{#requestdto.invoiceNumber}) and " +
            " (:#{#requestdto.mod} is null OR i.InvTypeName = :#{#requestdto.mod}) and " +
            " (:#{#requestdto.getStatus() == null || #requestdto.getStatus().isEmpty()} OR e.distrstttypecode in (:#{#requestdto.getStatus()})) "
)
补充说明

如果你的DTO中status字段是public属性可直接访问,把上面代码里的#requestdto.getStatus()替换成#requestdto.status即可,核心要保证IN后面的集合参数被括号包裹。

内容的提问来源于stack exchange,提问作者ramkr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:36:21