simpleJdbcCall调用Pl / SQL过程 - ORA-22922不存在LOB值

时间:2014-05-02 01:50:31

标签: java oracle jdbctemplate clob

我收到此SQLException - ORA-22922不存在LOB值。

我的情景是:

  1. 我正在调用一个带有一系列结构的过程,
  2. 结构包含三种类型,两种是日期,一种是Clob
  3. 当我使用Spring的simpleJdbcCall设置null而不是clob执行该过程时,语句被执行并且数据被写入数据库。
  4. 这表示我的simpleJdbcCall设置正确。
  5. 这是我创建clob,数组和结构以及执行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();
      }
    

    评论和解决方案......

    更新:2014年5月5日(调试SQL语句日志记录输出):

    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 个答案:

答案 0 :(得分:0)

我在这里面临同样的问题,但只有在尝试使用StoredProcedure

时才会这样做

但是这样

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

工作正常。

答案 1 :(得分:0)

Clob实例与用于创建它的'oracleConnection'绑定,SimpleJDBCCall使用另一个连接进行数据库调用。从DB的角度来看,有两个独立的会话,这就是为什么在SimpleJDBCCall使用的会话中不存在clob的原因。

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);
        ...
    }
    ...
}

答案 2 :(得分:-1)

我有类似的问题。您可以更正它。我做出了自己的贡献,希望它能为您服务。

atexit