最近有位朋友問我:開發中向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這樣的大容量存儲的字段類型,有些更甚者對於varchar2字段存儲的長度也有限制。使用這種方式就可以完美解決以上的問題,同時在你使用也可以有選擇性的獲取相關數據,其靈活性有了更好的保證。
說到這里相信大家都明白怎么回事了吧,具體的代碼實現就不貼出來了,請根據開發需求自行斟酌使用。
希望有更好解決方案的朋友多多分享,謹誠拜謝!!!