如何解决java.sql.SQLSyntaxErrorException: ORA-01795异常?
解决ORA-01795及字符串越界问题的方案
先排查分片逻辑有效性
首先确认分片后的每个批次确实不超过100个元素——在循环中打印每个deal_no列表的长度,排查是否存在分片失效的情况(比如Lists.partition的参数顺序写反,或原列表元素类型不匹配导致分片异常):
for(List<String> deal_no : dealNoChunkList) { System.out.println("当前批次大小:" + deal_no.size()); // 确认每个批次≤100 List<Deal> chunkUFList = underlyingFundsRepo.findByItemIdList(deal_no); ufList.addAll(chunkUFList); }
方案1:替换手写JPQL为Criteria Query
手写@Query可能因字符串拼接逻辑触发长度异常,改用JPA Criteria API构建查询,能更可靠地处理IN列表:
// 在AppRepo中实现(需注入EntityManager) @Repository public class AppRepoImpl implements AppRepo { @PersistenceContext private EntityManager entityManager; @Override public List<Deal> findByItemIdList(List<String> dealNumberList) { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Deal> cq = cb.createQuery(Deal.class); Root<Deal> root = cq.from(Deal.class); cq.where(root.get("itemId").in(dealNumberList)); return entityManager.createQuery(cq).getResultList(); } }
方案2:处理字符串越界问题
报错中的StringIndexOutOfBoundsException提示存在超长字符串,检查dealNoList中的元素:
- 确认
itemId字段在数据库中的长度限制(比如Oracle中是否为VARCHAR2(255)) - 过滤或截断超过长度限制的
deal_no元素,避免插入/查询时触发异常
方案3:临时表关联查询(适合超大量数据)
如果deal_no数量极大,分片查询仍繁琐,可通过临时表+JOIN彻底规避IN列表1000条限制:
- 创建Oracle临时表:
CREATE GLOBAL TEMPORARY TABLE DEAL_TEMP (DEAL_ID VARCHAR2(255)) ON COMMIT DELETE ROWS;
- 批量插入
deal_no到临时表:
@Transactional public void batchInsertToTempTable(List<String> dealNoList) { String sql = "INSERT INTO DEAL_TEMP (DEAL_ID) VALUES (?)"; for(String dealId : dealNoList) { entityManager.createNativeQuery(sql) .setParameter(1, dealId) .executeUpdate(); } }
- 关联查询获取结果:
@Query("SELECT uf FROM Deal uf JOIN DEAL_TEMP dt ON uf.itemId = dt.DEAL_ID") public List<Deal> findByTempTable();
方案4:排查嵌套IN查询
检查Deal实体的关联映射或其他查询逻辑,是否存在嵌套的IN查询导致整体IN表达式数量超过1000——比如关联的子实体查询中也使用了IN列表,叠加后触发Oracle限制。
内容的提问来源于stack exchange,提问作者PersonuNique
相关产品推荐
相关产品推荐

