一、简介
最近在项目中,遇到一个比较奇怪的问题,就是当我使用Mybatis批量保存Clob长文本的时候,报错can bind a LONG value only for insert into a LONG column,大概意思就是 "仅能绑定要插入LONG列的LONG值" ,更奇怪的是,这个错误是在部署到测试环境中才遇到,在开发环境中根本没出现这个问题,正常保存,两个环境连的都是同一个内网的数据库,当时我们曾经怀疑是不是Clob太长了导致的,但是在开发环境正常保存无问题,打消了我们这个猜想。报错日志如下:
于是度娘了一波,看到一些说是Mybatis批量保存方法的问题,如下:
<insert id="insertPOBatch" parameterType="java.util.List">
insert into ZHXG_ZHCP_HJDFXQB(PKID,XSID,CPHJID,RWID,CPXQXX)
(
<foreach collection="list" item="row" index="index" separator="union all">
(select
#{row.pkid,jdbcType=VARCHAR},
#{row.xsid,jdbcType=VARCHAR},
#{row.cphjid,jdbcType=VARCHAR},
#{row.rwid,jdbcType=VARCHAR},
#{row.cpxqxx,jdbcType=CLOB}
from dual)
</foreach>
)
</insert>
以上代码中,cpxqxx字段是Clob类型,很大一部分都说有可能问题是出现在当从dual中取数据时,会将Clob对象的字段转为Long型,于是就有了can bind a LONG value only for insert into a LONG column这个报错。
二、解决方法
针对解决方法,我们可以使用begin..end(个人感觉像是存储过程的用法),同时这也是Oracle对Mybatis批量保存的另外一种方法,代码如下:
<!-- 此处批量插入暂时解决ORA-01461: can bind a LONG value only for insert into a LONG column问题 -->
<insert id="insertPOBatch" parameterType="java.util.List">
begin
<foreach collection="list" item="row" index="index" separator=";">
insert into ZHXG_ZHCP_HJDFXQB(PKID,XSID,CPHJID,RWID,CPXQXX)
values( #{row.pkid,jdbcType=VARCHAR},
#{row.xsid,jdbcType=VARCHAR},
#{row.cphjid,jdbcType=VARCHAR},
#{row.rwid,jdbcType=VARCHAR},
#{row.cpxqxx,jdbcType=CLOB}
)
</foreach>
;end;
</insert>
记住,;end;前后的分号不能忘了。抱着试一下的心态,结果居然成功了,特此记录一下,以防后面再次遇到,希望能对遇到相同问题的小伙伴,提供一下解决思路和方法。