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( ?))

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM