Mybatis中使用字符串拼接方式insert到一个clob字段的方法

1 篇文章 0 订阅
1 篇文章 0 订阅

在对Oracle数据库插入或者更新CLOB字段的时候,直接拼接INSERT INTO和UPDATE语句,会报一个

ora-01704:字符串文件太长

的异常。那是因为oracle的隐式转换机制,即oracle默认把字符串转换成varchar2类型,而这个字符串的长度又比4000大,所以会报ora-01704错误。说得通俗一点,就是两个单引号之间的字符不能超过4000,但是由于业务需求我又必须使用单引号将其引起来。于是我从网上搜了很多方法,其中有用for update方法解决的。但是mybatis不知该如何获取resultset,因此此方法只能作罢。后来看到网上有使用PL/SQL的方法,我想尝试一下直接在mybatis中使用是否能跑起来,结果一试发现居然可以!……感动……泪奔。具体实现方法如下:

//单独对大字段进行更新
    private void updateClobFields(String tableName,String dataId,List<Map> fieldList,RavFormInstanceMapper mapper){
        for(Map field:fieldList){
            StringBuffer sb=new StringBuffer();
            sb .append(" DECLARE")
                    .append("   clobValue clob;")
                    .append(" BEGIN")
                    .append("   clobValue := '"+field.get("value")+"';")
                    .append("   UPDATE "+tableName+" T SET T."+field.get("column")+" = clobValue WHERE T.id='"+dataId+"';")
                    .append("   COMMIT;")
                    .append(" END;");

            mapper.updateInst(sb.toString());
        }
    } 

mapper.updateInst代码为:

@Update("${sql}")
    public void updateInst(@Param(value = "sql") String sql);

后续:这个方法也有问题,超过了某一个5位数(具体忘了)之后仍然会报异常,最后只能采用单独开辟一个JDBC的连接实现。具体做法如下:

public static void updateClobFields(String tableName,String dataId,List<Map> fieldList) {
        try{
            //获得数据库连接
            Connection con = DBAccess.getConnection();
            con.setAutoCommit(false);
            for(Map field:fieldList){
                Statement st = con.createStatement();
                ResultSet rs = st.executeQuery("select "+field.get("column")+" from "+tableName+" where ID='"+dataId+"' for update");
                Writer outputWriter=null;
                if (rs.next())
                {
                    //得到java.sql.Clob对象后强制转换为oracle.sql.CLOB
                    oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob((String)field.get("column"));
                    if(clob!=null){
                        outputWriter=clob.setCharacterStream(0l);
                        char[] charset = ((String) field.get("value")).toCharArray();
                        outputWriter.write(charset, 0, charset.length);
                    }else{
                        logger.error("CLOB类型字段:"+field.get("column")+"为null !");
                    }
                }
                if(outputWriter!=null){
                    outputWriter.flush();
                    outputWriter.close();
                }
            }
            con.commit();
            con.close();
        }catch(SQLException e){
            logger.error("",e);
        }catch (IOException e){
            logger.error("",e);
        }
    }

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值