代码解决Oracle in列表过长问题

来源:互联网 发布:品牌网络销售授权书 编辑:程序博客网 时间:2024/04/28 09:09

  最近在修改产品bug时碰到了Oracle in列表过长问题。Google了一下原来是Oracle Sql语句中in列表不能超过1000项。网上的解决办法有很多,比较好的就是将in列表用or分开。我也采用这种方法,只不过我面对的只是in列表中的String,生成的String由外部程序加入in列表中。因此采用了特殊的处理方法。

  主程序中加入以下分支

                if(iLen >= 1000
                
{
                    sql 
= getSql4LongCorps(corps);
                }

                
else
                
{
                                                                                           
//正常处理
                }

 其中新增了两个方法:

 

/**
     * 对超长的下级公司数组特殊处理,并返回拼接后的in部分
     * 
@author: yza
     * 
@param:下级公司数组
     * 
@return:用or拼接的in语句
     
*/

    
private String getSql4LongCorps(CorpVO[] corps)
    
{
        
try
        
{
        StringBuilder strAll 
= new StringBuilder("select pk_corp from bd_corp where pk_corp ");
        String sqlPart 
= "";
        
//in特殊处理
        List<List<CorpVO>> corpList = splitArray(corps,500);
        
for(int k = 0;k<corpList.size();k++)
        
{
            List
<CorpVO> arr = corpList.get(k);
            
for (int i = 0; i < arr.size(); i++
            
{
                sqlPart 
+= "'" + arr.get(i).getPrimaryKey() + "'";
                
if (i < arr.size() - 1)
                    sqlPart 
+= ",";
            }

            strAll.append( 
" in (" + sqlPart + ")");
            sqlPart 
= "";
            
            
if(k<corpList.size()-1)
            
{
                strAll.append(
" or pk_corp ");
            }

        }

        
return strAll.toString();
        }

        
catch(Exception e)
        
{
            e.printStackTrace();
            
return "";
        }


    }



/**
     * 将大数组拆成小数组并返回存放数组的列表
     * 
@author:yza
     * 
@param:下级公司数组
     * 
@param:分割后数组大小
     * 
@return:包含分割后数组的List<T>
     
*/

    
private List<List<CorpVO>> splitArray(CorpVO[] corps,int perLength)
    
{
        
int arrayNum = (corps.length/perLength) + 1;
        List
<List<CorpVO>> corpArrays = new ArrayList<List<CorpVO>>();
        List
<CorpVO> corpList = Arrays.asList(corps);
        
        
        
int start = 0;
        
int end = perLength;
        
        
for(int i = 0; i<arrayNum;i++)
        
{
            
if(i == arrayNum -1)
            
{
                perLength 
= corps.length % perLength;
            }

            end 
= start + perLength;
            List
<CorpVO> part = corpList.subList(start, end);
            
//CorpVO[] a = part.toArray(new CorpVO[part.size()]);
            corpArrays.add(part);
            start 
= end;
        }

        
return corpArrays;
    }

  其中getSql4LongCorps方法是主体,作用就是拼in中的超长Sql。参数 corps是集团下级分公司数组,就是这个数组长度超过了1000项,所以主程序中的else按常规拼出来的Sql才会报错。

  splitArray函数是个通用方法。作用是将指定的数组拆成几个小数组,并允许调用者指定小数组的长度。搜遍整个Java类库也没有找到直接可用的方法(好像C#里也没有相关的方法)。以后会将它写成扩展方法放到框架中。(这里指.Net领域)。

 

原创粉丝点击