SimpleJdbcCall calls Pl / SQL procedure - ORA-22922 nonexistent LOB value

I get this SQLException - ORA-22922 non-existent LOB value.

My scenario:

  • I call a procedure that takes an array of structures,
  • The structure contains three types, two - date, and one - Clob
  • When I execute the procedure using Spring simpleJdbcCall, setting it to null instead of clob, the statement starts and the data is written to the database.
  • This suggests that my simpleJdbcCall is configured correctly.

Here is my code to create clob, array and struct and execute simpleJdbCall.

  public void insertRecords(List<MyObject> objectList) throws Exception {
    Array array = null;
    Connection connection = jdbcTemplate.getDataSource().getConnection();
    OracleConnection oracleConnection = connection.unwarp(OracleConnection.class);

    Object[] arrObj = new Object[objectList.size()];
    Object[][] structObj = new Object[objectList.size()][3];

    Clob clob = connection.createClob();
    for(int loop = 0; loop < objectList.size(); loop++) {
       clob.setString(objectList.get(loop).getData);

       structObj[loop][0] = objectList.getDate1();
       structObj[loop][1] = objectList.getDate2();
       structObj[loop][2] = clob; //null; 

       arrObj[loop] = oracleConnection.createStruct(structName, structObj[loop]);
     }

     array = oracleConnection.createOracleArray(collectionName, arrObj);

     Map<String, Array> inparam = new HashMap<~>;

     inparam.put(arrayParamString, array);

     //procInsertData is a SimpleJdbcCall
     procInsertData.exexute(inparam);
     clob.free();
  }

Comments and solutions plz ...

Update: May 5, 2014 (output from Debug SQL report log):

2014-05-05 11:30:18,126 [main] DEBUG  SimpleJdbcCall - JdbcCall call not compiled    before execution - invoking compile
2014-05-05 11:30:18,296 [main] DEBUG  SimpleJdbcCall - Compiled stored procedure. Call string is [{call MY_DB.WRITE(?)}]
2014-05-05 11:30:18,357 [main] DEBUG  SimpleJdbcCall - SqlCall for procedure [write] compiled
2014-05-05 11:30:18,367 [main] DEBUG  SimpleJdbcCall - The following parameters are used for call {call MY_DB.WRITE(?)} with:  {in_my_objects=org.springframework.jdbc.core.SqlParameterValue@7e4034bd}
2014-05-05 11:30:18,367 [main] DEBUG  SimpleJdbcCall - 1: in_my_objects SQL Type 2003 Type Name MY_OBJECT_COLL org.springframework.jdbc.core.SqlParameter
2014-05-05 11:30:18,388 [main] DEBUG  StatementCreatorUtils - Overriding type info with runtime info from SqlParameterValue: column index 1, SQL type 2003, type name null
2014-05-05 11:30:18,388 [main] TRACE  StatementCreatorUtils - Setting SQL statement parameter value: column index 1, parameter value [oracle.sql.ARRAY@61d6687a], value class [oracle.sql.ARRAY], SQL type 2003
2014-05-05 11:30:18,447 [main] INFO   XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml]
2014-05-05 11:30:18,623 [main] INFO   SQLErrorCodesFactory - SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
Exception in thread "main" org.springframework.jdbc.UncategorizedSQLException: CallableStatementCallback; uncategorized SQLException for SQL [{call MY_DB.WRITE(?)}]; SQL  state [99999]; error code [22922]; ORA-22922: nonexistent LOB value
ORA-06512: at "PKG.MY_DB", line 30
ORA-06512: at line 1
; nested exception is java.sql.SQLException: ORA-22922: nonexistent LOB value
ORA-06512: at "PKG.MY_OBJ", line 30
ORA-06512: at line 1
+3
source share
2

, StoredProcedure

        conn = datsource.getConnection();
        cstmt = conn.prepareCall("{? = call schema.package.function(?)}");
        cstmt.registerOutParameter(1, Types.CLOB);
        cstmt.setClob(2, clob);
        cstmt.execute();

.

0

Clob "oracleConnection", , SimpleJDBCCall . , clob , SimpleJDBCCall.

, SimpleJDBCCall, Clob.

, SQLData :

Map<String, Object> values = new HashMap<>();
values.put("IN_bean_type", new MyBean());
simpleJdbcCallOperations.execute(values);

MyBean:

class MyBean implements SQLData {
    ...
    @Override
    public void writeSQL(SQLOutput stream) throws SQLException {
        ...
        Clob clob = ((OracleSQLOutput)stream).getSTRUCT().getJavaSqlConnection().createClob(); //hack to get the current connection
        clob.setString(1, "stringValue");
        stream.writeClob(clob);
        ...
    }
    ...
}
0

Source: https://habr.com/ru/post/1538939/


All Articles