2015年8月12日 星期三

ORA-22922: nonexistent LOB value

ORA-22922: nonexistent LOB value

最近處理了一個原本以為是Java端控制JDBC資料有問題而導致的ORA錯誤,找了半天終於找到可能的原因,紀錄一下免得下次再找半天....

環境敘述

Database : Oracle 10G
Program Language : Java
Application Server : weblogic
Framework : spring 4


錯誤訊息

org.springframework.jdbc.UncategorizedSQLException: StatementCallback;
uncategorized SQLException for SQL [ 
  SELECT *
  FROM (SELECT a.*, ROWNUM r__
          FROM (SELECT *
                  FROM DUMMY_V
                 WHERE (1 = 1)) a
         WHERE ROWNUM < ( (1 * 100) + 1))
  WHERE r__ >= ( ( (1 - 1) * 100) + 1)
];
SQL state [99999]; error code [22922]; ORA-22922: nonexistent LOB value;
nested exception is java.sql.SQLException: ORA-22922: nonexistent LOB value


錯誤分析

其中DUMMY_V是一個View,透過WMSYS.WM_CONCAT將多筆資料合成一筆,為了避免處理CLOB資料型態,所以公司習慣補上to_char將資料轉成varchar,因此寫成了

... select key, to_char(WMSYS.WM_CONCAT(column1 )) from table ...

因此在某些狀況下(可能是資料筆數少),會出現錯誤訊息。原因可能是因為google上找到的某段訊息....

to_char and WM_CONCAT allocated memory size is inconsistent

所以將to_char拿掉後老實處理就解決了.....

資料參考
http://www.javaproblemstips.com/160064/

更新(2015/9/25):
拿掉之後仍在資料較多的情況發生了同樣的訊息,因此後來將本來透過wm_concat將資料串接改成透過trigger串街後存入其他的資料表在查詢的方式處理,因此上述的方法可能沒有完全解決問題,透過11G的LISTAGG會是較好的處理方式(若只有10G以前的版本就.....)