转载请注明出处:http://www.cnblogs.com/xunzhaorendaxia/p/8570604.html

解决方案将select * from tablename where field in(arg1,arg2...arg1001)拆成select * from tablename where field in(arg1,arg2...arg1000) or field in(arg1001);

本案例代码为项目中处理SQL语句中<#in>标签代替in (?,?,?..)的情况;

public class FeildTest {
public static void main(String[] args){
String sql = "select * from id<#in>";
int startSize = 21;
System.out.println(ExtractFeild(sql,startSize));
}
//标签替换
private static String ExtractFeild(String sql, int startSize) { String replaceTag = "<#in>";
if(sql.contains(replaceTag)){
String[] fields = sql.split(" ");
String field = "";
for (int i = 0; i < fields.length; i++) {
String str = fields[i];
if (str.contains(replaceTag)) {
if (str.equals(replaceTag)) {
field = fields[i-1];
break;
} else {
char[] fd = str.toCharArray();
char[] tags = replaceTag.toCharArray();
field = str.substring(0,KMP_Index(fd,tags));
break;
}
}
}
StringBuffer sb = new StringBuffer("("+field+" in(");
for (int i = 0; i < startSize/10; i++) {
for (int j = 0; j < 10; j++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
if (startSize!=(i+1)*10) {
sb.append(" or ");
sb.append(field);
sb.append(" in( ");
}
}
for (int i = 0; i < startSize%10; i++) {
sb.append("?,");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
//额外的括号处理
sb.append(")"); //field<#in>之间空格兼容
String regex = field+"\\s*"+replaceTag;
sql = sql.replaceFirst(regex, sb.toString());
}
return sql;
}

//kmp特征向量
private static int[] next(char[] t) {
int[] next = new int[t.length];
next[0]=-1;
int i=0;
int j=-1;
while (i<t.length-1) {
if (j==-1||t[i]==t[j]) {
i++;
j++;
if (t[i]!=t[j]) {
next[i]=j;
} else {
next[i]=next[j];
}
} else {
j = next[j];
}
}
return next;
}
   //KMP算法
private static int KMP_Index(char[] ss, char[] tt) {
int[] next = next(tt);
int i=0;
int j=0;
while ( i<=ss.length-1 && j<= tt.length -1) {
if (j==-1||ss[i]==tt[j]) {
i++;
j++;
} else {
j = next[j];
}
}
if (j<tt.length) {
return -1;
} else {
return i -tt.length;
}
}
}

其中用到了KMP算法来查找sql中该标签的位置,并作出处理计算出sql中<#in>标签个数;

其实算法逻辑结合网上资料很容易写出来;

不过在代码审查的过程中老大一眼就看出来个问题:

我原有SQL处理完想生成in (?,?,?,?..)or in (?,?,?..)这种结构

但是如果两边不加括号会存在逻辑上的错误;

比如我原计划select * from table where id in(1) or id in(2)and id=3;

是查不出来任何东西的;实际上会查出来select * from table where id in(1)的结果;这也是菜鸟程序员常见错误,

解决方案在处理此类SQL语句的时候多加()保证逻辑正确。

运行结果:

select * from (id in(?,?,?,?,?,?,?,?,?,?) or id in( ?,?,?,?,?,?,?,?,?,?) or id in( ?))

Oracle数据库中in()参数超过一千报错代码报错的更多相关文章

  1. Oracle数据库中字段定义为Char类型,Hibernate用该字段进行动态绑定参数查询,获取不到结果的问题

    一.问题背景 产生环境:oracle数据库,hibernate操作 定义了一个表 create table STORE_INFORMATION ( id CHAR(32) not null, name ...

  2. Oracle数据库中调用Java类开发存储过程、函数的方法

    Oracle数据库中调用Java类开发存储过程.函数的方法 时间:2014年12月24日  浏览:5538次 oracle数据库的开发非常灵活,不仅支持最基本的SQL,而且还提供了独有的PL/SQL, ...

  3. 【转】Oracle数据库中Sequence的用法

    在Oracle数据库中,sequence等同于序列号,每次取的时候sequence会自动增加,一般会作用于需要按序列号排序的地方. 1.Create Sequence (注释:你需要有CREATE S ...

  4. Oracle 数据库中日期时间的插入操作

    Oracle 中如何插入日期时间类型的数据,首先为了演示, 新建数据表如下 create table t( mydate date); 插入日期时间 SQL> insert into t val ...

  5. Oracle GoldenGate中HANDLECOLLISIONS参数使用详解

    Oracle GoldenGate中HANDLECOLLISIONS参数使用详解   HANDLECOLLISIONS 是一个 replicat 进程参数,主要在 initial load 中使用.在 ...

  6. 查找Oracle数据库中的重复记录

    本文介绍了几种快速查找ORACLE数据库中的重复记录的方法. 下面以表table_name为例,介绍三种不同的方法来确定库表中重复的记录 方法1:利用分组函数查找表中的重复行:按照某个字段分组,找出行 ...

  7. Oracle数据库中插入日期型数据(to_date的用法)(转载)

    往Oracle数据库中插入日期型数据(to_date的用法) INSERT  INTO  FLOOR  VALUES  ( to_date ( '2007-12-20 18:31:34' , 'YYY ...

  8. Oracle 数据库中查看表空间的2种方法

    在Oracle数据库中查看表空间使用状况是我们在实际应用中经常涉及到的,以下的内容就就是对Oracle 数据库中查看表空间使用状况时所要用到的SQL的描述,希望你能从中获得自己想要的东西. Oracl ...

  9. oracle 数据库中(创建、解锁、授权、删除)用户

    上文我们已经建立了名为orcl66的数据库. 想要在数据库中创建.修改用户需要我们以管理员权限登录到数据库中. 首先我们通过sqlplus命令登录连接数据库. 输入sqlplus命令--用户名: sy ...

  10. (面试题)如何查找Oracle数据库中的重复记录

    今天做了个面试题:查找Oracle数据库中的重复记录,下面详细介绍其他方法(参考其他资料) 本文介绍了几种快速查找ORACLE数据库中的重复记录的方法. 下面以表table_name为例,介绍三种不同 ...

随机推荐

  1. docker 报错:x509: certificate has expired or is not yet valid

    环境:centos 7 程序:docker 下载镜像报错: # docker pull centos Pulling repository centos FATA[0004] Get https:// ...

  2. IDA学习笔记 函数调用约定

    stdcall和cdecl: stdcall和cdecl 压栈方向都是从右到左 区别在于c约定是调用方在函数返回后add esp,n指令清除堆栈中的参数,而stdcall在被调函数内使用ret n来清 ...

  3. IE兼容swiper

    swiper3能完美运用在移动端,但是运用在PC端,特别是IE浏览器上不能兼容,没有效果,要使IE兼容Swiper的话必须使用swiper2,也就是idangerous.swiper.js, 下载地址 ...

  4. myeclispe中向mysql中插入中文数据出现??问题解决办法

    或许很多人会出现??这种令人头痛的mysql的中文乱码问题:解决如下: 1.先对于新建的数据库要设置默认的字符集为UTF-8 create database mydb default characte ...

  5. Sping Boot入门到实战之入门篇(二):第一个Spring Boot应用

    该篇为Spring Boot入门到实战系列入门篇的第二篇.介绍创建Spring Boot应用的几种方法. Spring Boot应用可以通过如下三种方法创建: 通过 https://start.spr ...

  6. java复习笔记

    本笔记(无异常处理与网络编程部分)整理自<java程序设计>-黄岚 王岩 王康平 编著 java数据     UI     I/O      java线程      数据库操作 Java数 ...

  7. 中小研发团队架构实践之微服务MSA

    一.MSA简介 1.1.MSA是什么 微服务架构MSA是Microservice Architecture的简称,它是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相通讯.互相配合, ...

  8. Spring data mongodb 替换 Repository 实现类,findAll 排除 字段

    因文档比较大,有时候findAll 不想返回所有数据.没有找到默认的findAll 能够include 或者 exclude 的方法,所以想办法扩展一下实现类 query.fields().inclu ...

  9. yaf插件类的使用

    yaf插件类的使用大小写敏感的. "插件名Plugin"为插件类的名字,这样会自动标志着这是一个插件. application.directory string 应用程序的目录,包 ...

  10. ORACLE透明网关访问SQL Server配置总结

      透明网关概念 ORACLE透明网关(Oracle Transparent Gateway)可以解决ORACLE数据库和非ORACLE数据库交互数据的需求.在一个异构的分布式环境中,通过ORACLE ...