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

问题描述 投票:3回答:2

我得到这个SQLException - ORA-22922不存在的LOB值。

我的情况是:

  1. 我正在调用一个采用一系列结构的过程,
  2. 该结构包含三种类型,两种是日期,一种是Clob
  3. 当我使用Spring的simpleJdbcCall设置null而不是clob执行该过程时,语句被执行并且数据被写入数据库。
  4. 这告诉我的simpleJdbcCall设置正确。

这是我创建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();
  }

评论和解决方案plz ...

更新: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
java oracle jdbctemplate clob
2个回答
0
投票

我在这里面临同样的问题,但只有在尝试使用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使用另一个连接进行DB调用。从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);
        ...
    }
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.