ORA-29481:从JDBC调用Oracle 12c过程时,无法将隐式结果返回给客户端

时间:2017-02-07 11:12:57

标签: java oracle jdbc plsql cursor

我写了一个像这样的PL / SQL程序:

const asyncReduce = Promise.coroutine(function* () {
    const sum = yield Promise.reduce([1, 2, 3, 4, 5], Promise.coroutine(function* (m, n) {
        return m + (yield delayed(n));
    }), 0);

    console.log(sum);
});

现在,我想使用JDBC从Java调用上述过程,如下所示(algorithm inspired by this articlethis one):

CREATE OR REPLACE PROCEDURE p_5666 (
  id1 NUMBER := NULL, 
  id2 NUMBER := NULL, 
  id3 NUMBER := NULL
) IS
  c1 SYS_REFCURSOR;
  c2 SYS_REFCURSOR;
  c3 SYS_REFCURSOR;
BEGIN
  IF id1 IS NOT NULL THEN
    OPEN c1 FOR SELECT first_name, last_name FROM t_author WHERE id = id1;
    dbms_sql.return_result (c1);
  END IF;

  IF id2 IS NOT NULL THEN
    OPEN c2 FOR SELECT title FROM t_book WHERE id = id2;
    dbms_sql.return_result (c2);
  END IF;

  IF id3 IS NOT NULL THEN
    OPEN c3 FOR SELECT id3 AS id FROM dual;
    dbms_sql.return_result (c3);
  END IF;
END;

不幸的是,上面引发了以下异常:

try (Connection cn = new oracle.jdbc.OracleDriver().connect(url, properties);
     Statement s = cn.createStatement()) {
    boolean result = s.execute("begin p_5666(1, 2, 3); end;");

    fetchLoop:
    for (int i = 1;; i++) {

        // Note, this call seems to be required in Oracle even for the first result set.
        // In other JDBC drivers (e.g. MySQL, SQL Server), this would skip the first result
        result = s.getMoreResults();

        if (result)
            try (ResultSet rs = s.getResultSet()) {
                System.out.println("\nResult " + i + ":");
                ResultSetMetaData meta = rs.getMetaData();

                while (rs.next())
                    IntStream.rangeClosed(1, meta.getColumnCount())
                    // Using jOOλ's wrapper for lambdas throwing checked exceptions
                             .mapToObj(Unchecked.intFunction(
                                  j -> meta.getColumnName(j) + ": " + rs.getObject(j)))
                             .forEach(System.out::println);
            }
        else if ((s.getUpdateCount()) == -1)
            break fetchLoop;
    }
}

原因是什么?

1 个答案:

答案 0 :(得分:2)

我还在使用11g版本的ojdbc驱动程序。升级到12c版本的ojdbc修复了问题并产生了预期的结果:

  

结果1:
  FIRST_NAME:乔治
  LAST_NAME:Orwell

     

结果2:
  标题:动物农场

     

结果3:
  ID:3

This is also explained in this article