以前寫過的一篇博文中提到了出現(xiàn)“ORA-01461: 僅可以為插入 LONG 列的 LONG 值賦值”的原因,并給出了原因和解決方法,在這裡回顧一下。(詳見 當(dāng)遇到“數(shù)據(jù)大小超出此類型的最大值”和“僅可以為插入 LONG 列的 LONG 值賦值”時(shí)...? )
當(dāng)時(shí)的環(huán)境:?
數(shù)據(jù)庫:Oracle 9i
數(shù)據(jù)庫字段類型:varchar2(4000)
輸入漢字:大于1000字
原因:
?? 我的數(shù)據(jù)庫字符集應(yīng)該是UTF-8的,對于UTF-8或歐洲的某些字符集,oracle在存儲時(shí),對于一個(gè)字符需要2個(gè)或3個(gè)字節(jié)的存儲空間,雖然表定義中為varchar2(4000),但是其實(shí)該字段的data_length為其2倍或3倍長。這種情況下oracle會把data_length長度超過4000的當(dāng)做LONG型處理,你的表中有兩個(gè)這樣的字段,插入數(shù)據(jù)時(shí)相當(dāng)于同時(shí)操作2個(gè)LONG字段,所以報(bào)錯(cuò)。
當(dāng)時(shí)的解決辦法:建議減小字段長度或拆分。實(shí)在需要的,可以轉(zhuǎn)而采用CLOB字段類型。
現(xiàn)在的環(huán)境:
數(shù)據(jù)庫字段類型:CLOB
輸入字節(jié):1000 ~ 2000
現(xiàn)在的問題:
解決方法:
方法1:
采用Oracle 10g最新的ojdbc14.jar驅(qū)動(dòng)替換原有的驅(qū)動(dòng)即可。試過了這種方法,但是并沒有生效。
方法2:
1. Hibernate實(shí)體對象中的數(shù)據(jù)成員類型為String,映射的數(shù)據(jù)庫字段類型為org.springframework.orm.hibernate.support.ClobStringType。實(shí)例如下:














2. 如果使用Spring的這個(gè)Clob類型就需要在applicationContext.xml中的sessionFactory bean里注入oracleLobHandler bean。下面給出Oracle數(shù)據(jù)庫的LobHandler配置:


























大家可能已經(jīng)注意到 nativeJdbcExtractor 和 oracleLobHandler Bean 都設(shè)置為 lazy-init="true",這是因?yàn)?nativeJdbcExtractor 需要通過運(yùn)行期的反射機(jī)制獲取底層的JDBC 對象,所以需要避免在 Spring 容器啟動(dòng)時(shí)就實(shí)例化這兩個(gè)Bean。








DefaultLobHandler 只是簡單地代理標(biāo)準(zhǔn) JDBC 的 PreparedStatement 和 ResultSet 對象,由于并不需要訪問數(shù)據(jù)庫驅(qū)動(dòng)本地的 JDBC 對象,所以它不需要 NativeJdbcExtractor 的幫助。
??? 采用第二種方法即可解決我所遇到的問題,如果再見到“ORA-01461: 僅可以為插入 LONG 列的 LONG 值賦值”時(shí),希望這個(gè)方法能夠幫您順利拿下ORA-01461。
PS:給出Oracle下幾種大容量字段類型的解釋
LONG RAW: 可變長二進(jìn)制數(shù)據(jù),最長2G
CLOB:? 字符大對象Clob 用來存儲單字節(jié)的字符數(shù)據(jù)
NCLOB: 用來存儲多字節(jié)的字符數(shù)據(jù)
BLOB: 用于存儲二進(jìn)制數(shù)據(jù)
BFILE: 存儲在文件中的二進(jìn)制數(shù)據(jù),這個(gè)文件中的數(shù)據(jù)只能被只讀訪。但該文件不包含在數(shù)據(jù)庫內(nèi)。bfile字段實(shí)際的文件存儲在文件系統(tǒng)中,字段中存儲的是文件定位指針.bfile對oracle來說是只讀的,也不參與事務(wù)性控制和數(shù)據(jù)恢復(fù)。
其中CLOB,NCLOB,BLOB都是內(nèi)部的LOB(Large Object)類型,最長4G,沒有LONG只能有一列的限制。要保存圖片、文本文件、Word文件各自最好采用那種數(shù)據(jù)類型呢?BLOB最好,LONG RAW也不錯(cuò),但Long是oracle將要廢棄的類型,因此建議用BLOB。
??????????????????????????????????????????????????????????????????????????? THE END