sql 条件in() 中值过多拆分

本文介绍了一种解决Oracle数据库中SQL IN子句因参数过多导致的问题的方法。通过拆分IN子句来避免超过1000个表达式的限制,确保了查询能够正确执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
  * 拆分sql中in值超过1000个的sql 由于oracle现在表达式个数不能超过1000个,所以需要拆分
  *
  * @param sql
  * @param paramMap
  * @return
  * @throws Exception
  */
 protected String splitInSql(String sql, Map<String, Object> paramMap)
   throws Exception {
  String oldSql = sql;
  try {
   Pattern p = Pattern.compile(
     "\\s*(\\w*\\.*\\w+)\\s*in\\s*\\(\\s*\\:(\\w+)\\s*\\)",
     Pattern.CASE_INSENSITIVE);
   Matcher m = p.matcher(sql);
   StringBuffer newSql = new StringBuffer();
   while (m.find()) {
    String group = m.group();
    String fieldVal = m.group(2);
    StringBuffer innerSql = new StringBuffer();
    
    if(paramMap.get(fieldVal) instanceof Collection){
     
     Collection<?> dataCollection = (Collection<?>) paramMap
       .get(fieldVal);
 
     if (null != dataCollection && (dataCollection instanceof List || dataCollection instanceof Set)
       && dataCollection.size() > SQL_IN_NUM) {
      List<?> dataList;
      if(dataCollection instanceof Set){
       dataList = (List<?>) new ArrayList(dataCollection);
      }else{
       dataList = (List<?>) dataCollection;
      }
      int num = dataList.size() / SQL_IN_NUM;
      if (dataList.size() % SQL_IN_NUM > 0) {
       num++;
      }
      innerSql.append("(");
      for (int i = 1; i <= num; i++) {
       int begin = (i - 1) * SQL_IN_NUM;
       int end = ((i * SQL_IN_NUM) > dataList.size()) ? dataList
         .size() : (i * SQL_IN_NUM);
 
       paramMap.put(fieldVal + "_" + i,
         dataList.subList(begin, end));
       if (i != 1) {
        innerSql.append(" or ");
       }
       innerSql.append(group.replace(":"+fieldVal, ":"+fieldVal+ "_" + i));
      }
      innerSql.append(")");
      m.appendReplacement(newSql, innerSql.toString());
 
     }
    }
   }
   m.appendTail(newSql);
   sql = newSql.toString();
  } catch (Exception e) {
   LogUtil.error(this.getClass(), e);
   sql = oldSql;
  }
  return sql;
 }

转载于:https://www.cnblogs.com/dangjianshun/p/5717295.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值