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

标签 java oracle jdbctemplate clob

我收到此 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();
  }

请提出意见和解决方案...

更新: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

最佳答案

Clob 实例与您用来创建它的“oracleConnection”相关联,并且 SimpleJDBCCall 使用另一个连接进行数据库调用。从数据库的角度来看,有两个独立的 session ,这就是 SimpleJDBCCall 使用的 session 中不存在 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);
        ...
    }
    ...
}

关于java - simpleJdbcCall 调用 Pl/SQL 过程 -- ORA-22922 不存在的 LOB 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23419567/

相关文章:

java - GWT 从 UiBinder 自动创建 Java 类

Oracle存储过程: return both result set and out parameters

java - 我想从 jdbctemplate 调用存储过程并需要在存储过程中生成的 pk

java - 如何调用 Oracle 函数返回记录表

java - 设置 java 系统属性,-D 或 System.setProperty() 的最佳实践是什么?

java - 我如何创建一个由 3 个已经存在的类似子类组成的 super 抽象类,其构造函数中具有不同数量的参数

C# 在 refcursor(Oracle) 中读取游标

sql-server - 无法将类型 'net.sourceforge.jtds.jdbc.ClobImpl' 的属性值转换为所需类型 'java.lang.String'

java - Spring Integration LoggingHandler 中的 NPE

SQL Insert 大数据集