最近有位朋友问我:开发中向CLOB字段存储string时报了ORA-01704的错误不知道怎么解决。首先造成这个问题的原因相信大家都明白,就是因为插入的字符串过长导致,因为oracle在插入CLOB的数据默认会以varchar2的类型插入,所以当超过4000个字符时就会报ORA-01704的错误了(varchar2类型的字符长度是4000,注意:oracle对汉字的存储占3个字符)
在这里我分享下对于这个问题解决方法(持久层基于mybatis开发):
创建库:
create table test(
id varchar2(200),
text clob
);
创建JavaBean
package cn.com;
public class test{
private String id;
private String text;
.......//省略get/set方法
}
解决方式:使用变量,通过PL/SQL将数据赋予CLOB变量,通过引用变量将数据插入
mybatis具体XML内容如下:
<insert id="insert" parameterType="cn.com.test">
DECLARE
V_LANG CLOB := #{text,jdbcType=CLOB};
BEGIN
INSERT INTO test(ID, TEXT) VALUES(#{id,jdbcType=VARCHAR}, V_LANG);
END;
</insert>
对于以上方法,在插入,查询以及更新CLOB字段时这种方式会影响程序的性能;对于性能要求不高时可以一试。
那么要提高性能又应该怎么做呢?这里有2中方法可以参考:
第一种方式:使用文件存储数据
当数据量特别大达到几M甚至几十M的时候,虽然CLOB也能存下但不建议直接存ORACLE,最好的方式将数据存自盘上,在ORACLE中只留下数据文件的地址信息这样我们在插入与查询上性能会快很多,对网络的开销也小。当我们需要读取数据时在从文件中读取数据。相对于前者直接获取存储在内存中,这种方式要灵活得多。
第二种方式:将数据切分成一段一段分散到表中存储
新建一张表用作CLOB内容存储,test中的CLOB字段就可以删除不要了
create table text(
test_id varchar2(200),//test表的id,用作外键关联
text varchar2(3000),//CLOB的分段数据,以1000个汉字作为存储单元
sort number(8)//text的显示顺序,在展示内容是按此顺序依次展示出来
);
这其实是就是一种分页的思想,很多大的企业都有自己一套存储数据的规则,他们处于对系统性能的考虑都会禁止使用CLOB,BLOB,LONG这样的大容量存储的字段类型,有些更甚者已经放弃使用varchar,并且对于varchar2字段存储的长度也有限制。使用这种方式就可以完美解决以上的问题,同时在你使用也可以有选择性的获取相关数据,其灵活性有了更好的保证。
说到这里相信大家都明白怎么回事了吧,具体的代码实现就不贴出来了,请根据开发需求自行斟酌使用。
希望有更好解决方案的朋友多多分享,谨诚拜谢!!!