美文网首页数据库
fixed Oracle SQL报错 #ORA-01460: 转

fixed Oracle SQL报错 #ORA-01460: 转

作者: smileNicky | 来源:发表于2019-01-13 16:52 被阅读0次

    最近遇到一个oracle错误,之前并没有遇到过,并不是select in超过1000个导致的,通过网上资料说是oracle版本导致,也有的说是oracle SQL过长导致。

    然后通过自己实践应该说是oracle SQL过长导致,看了一下SQL并不是很长,主要还是select in,因为主键换成uuid之后,来几百个uuid的数据,select in就导致SQL过长报错,我觉得网上所说的换oracle版本,也有可能是oracle版本对SQL过长支持不同。不过我还是通过改写业务SQL解决问题的。项目中也不可能随便就换oracle版本。

    原来的代码,主要是select in 然后itemCode就是用;分隔的一大串的主键字符串,然后又换成uuid的了,所以导致sql过长

    /**
         * 获取信息模板
         * @return
         */
        private List<ApprSmsItemSettingVo> getSettingTemplate(String itemCode)
                throws SQLException {
            PreparedStatement pst = null;
            StringBuffer sb = new StringBuffer();
                sb.append("select a.itemCode, ");
                     sb.append("a.type, ");
                     sb.append("b.warn_days, ");
                     sb.append("c.proj_name, ");
                     sb.append("c.cust_name, ");
                     sb.append("a.is_send ");
                     sb.append("from t_item_setting a ");
                     sb.append("left join t_itm_define b on b.itemCode= a.itemCode ");
                             sb.append("b.itemCode where a.is_send in (1) and a.itemCode in (?) ");
            pst = this.connection.prepareStatement(sb.toString());
        
            pst.setString(1, itemCode);
            ResultSet rs = pst.executeQuery();
            List<ItemSettingVo> list = new ArrayList<ItemSettingVo>();
            while(rs.next()){
                ItemSettingVo vo = new ItemSettingVo();
                vo.setItemCode(rs.getString("itemCode"));
                vo.setType(rs.getLong("type"));
                vo.setSmsTemplet(rs.getString("sms_templet"));
                vo.setWarnDays(rs.getLong("warn_days"));
                vo.setIsSend(rs.getLong("is_send"));
                list.add(vo);
            }
            rs.close();
            pst.close();
            return list;
        }
    

    解决方法:用分组遍历再拼装为一个List的方法,这样就可以避免select in,然后in里面又是一大堆uuid的数据,然后就导致sql执行过长报错了

    /**
         * 获取信息模板
         * fixed #ORA-01460: 转换请求无法实施或不合理
         * ps:主键换成uuid之后,原来的方法会出现ORA-01460出错,sql太长导致
         * @param itemCode
         * @return
         * @throws Exception
         */
        public List<ItemSettingVo> getItemSettingVos(String itemCode)throws Exception{
            List<ItemSettingVo> templateList = new ArrayList<ItemSettingVo>();
            StringBuffer itmStr = new StringBuffer();
            //XXX fixed Exception#ORA-01460: 转换请求无法实施或不合理 modify on 20190109
            //暂时用分组遍历再拼装为一个List的方法,原来的方法放在getSettingTemplate
            if(StringUtils.isNotBlank(itemCode)){
                //itemCode = itemCode.replace("(", "").replace(")", "");
                String[] itemCodeArr = StringUtils.split(itemCode,",");
                int len = itemCodeArr.length;
                if (len < 100) {//没超过100个事项编码的情况,按照原来的方法
                    templateList = this.getSettingTemplate(itemCode);
                } else {//超过100个事项编码的情况,分组遍历,然后再拼装list,避免Exception#ORA-01460: 转换请求无法实施或不合理
                    List<Collection<String>> itms =CollectionUtils.splitCollection(Arrays.asList(itemCodeArr), 100);
                    for (Collection<String> colle: itms) {
                        for (String str : colle) {
                            itmStr.append("'").append(str).append("'").append(",");
                        }
                        itemCode = itmStr.toString().substring(0, itmStr.toString().length()-1);
                        templateList.addAll(this.getSmsSettingTemplate(itemCode));
                        itmStr.delete(0, itmStr.length());
                    }
                    System.out.println("get apprTemplateList:{}"+templateList.size());
                }
            }
            
            return templateList;
        }
    

    集合拆分工具类,工具类复制公司同事写的代码

    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    public class CollectionUtils {
        public static List<Collection<String>> splitCollection(Collection<String>values , int size) {
            List<Collection<String>> result = new ArrayList<Collection<String>>();
            if(values.size() == size ){
                result.add(values);
            }else{
                    int count =0;
                    Collection<String> subCollection= null;
                    for(String s:c){
                        if(subCollection == null){
                            subColletion = new ArrayList<String>();
                            result.add(subColletion);
                        }
                        subCollection.add(s);
                        count++;
                        if(count == size){
                            count =0;
                            subCollectiion = null;
                        }
                    }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:fixed Oracle SQL报错 #ORA-01460: 转

        本文链接:https://www.haomeiwen.com/subject/lvkldqtx.html