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

如何在Java StringBuilder中使用Oracle REGEXP_SUBSTR构建动态SQL并解决HQL报错

问题:用StringBuilder构建含REGEXP_SUBSTR的IN子查询时HQL报错

我在Java代码中用StringBuilder构建动态查询,需要在IN子句里追加包含REGEXP_SUBSTR表达式的SELECT子查询,代码如下:

StringBuilder criteria = new StringBuilder();

criteria.append(" IN (SELECT REGEXP_SUBSTR((select tableA.mdn_list from tableA where tableA.id = '1'), '[^,]+', 1, level)  FROM dual CONNECT BY REGEXP_SUBSTR((select tableA.mdn_list from tableA where tableA.id = '1'), '[^,]+', 1, level) IS NOT NULL))");

运行后终端报错:

Caused by: org.hibernate.hql.ast.QuerySyntaxException: unexpected token: BY near line 3, column 19 .....

请问如何在代码中正确添加REGEXP_SUBSTR?

关联问题内容:如何将逗号分隔的字符串值作为项列表添加到SQL的IN子句中(使用子查询)?


解决方案

报错原因

你使用的是HQL(Hibernate查询语言),但HQL不支持Oracle原生的CONNECT BY语法,这是导致语法解析错误的核心原因。REGEXP_SUBSTR本身是Oracle的函数,但HQL在解析时无法识别原生SQL的特定扩展语法。

方法1:改用原生SQL查询

直接使用Hibernate的原生SQL查询API,完全兼容Oracle的语法规则:

// 构建完整的原生SQL语句
StringBuilder sql = new StringBuilder();
sql.append("SELECT t.* FROM your_target_table t ");
sql.append("WHERE t.mdn IN (");
sql.append("    SELECT REGEXP_SUBSTR((SELECT mdn_list FROM tableA WHERE id = '1'), '[^,]+', 1, level) ");
sql.append("    FROM dual ");
sql.append("    CONNECT BY REGEXP_SUBSTR((SELECT mdn_list FROM tableA WHERE id = '1'), '[^,]+', 1, level) IS NOT NULL");
sql.append(")");

// 执行原生SQL查询,如需映射实体类可调用addEntity(YourEntity.class)
SQLQuery query = session.createSQLQuery(sql.toString());
List<?> results = query.list();

方法2:先拆分字符串再传入HQL的IN子句

如果必须使用HQL,可以先通过原生SQL拆分逗号分隔的字符串为列表,再将列表作为参数传入HQL:

// 第一步:用原生SQL拆分MDN列表
String splitSql = "SELECT REGEXP_SUBSTR((SELECT mdn_list FROM tableA WHERE id = '1'), '[^,]+', 1, level) " +
                  "FROM dual " +
                  "CONNECT BY REGEXP_SUBSTR((SELECT mdn_list FROM tableA WHERE id = '1'), '[^,]+', 1, level) IS NOT NULL";
SQLQuery splitQuery = session.createSQLQuery(splitSql);
List<String> mdnList = splitQuery.list();

// 第二步:构建HQL并传入列表参数
String hql = "FROM YourTargetEntity WHERE mdn IN (:mdnList)";
Query hqlQuery = session.createQuery(hql);
hqlQuery.setParameterList("mdnList", mdnList);
List<YourTargetEntity> results = hqlQuery.list();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:02:00