Oracle数据库中in()参数超过一千报错代码报错

转载请注明出处: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( ?))

 

posted @ 2018-03-14 22:37  寻找任大侠  阅读(2201)  评论(0编辑  收藏  举报