使用 REF CURSOR 通过 java 程序检索 ResultSet 会引发错误

Posted

技术标签:

【中文标题】使用 REF CURSOR 通过 java 程序检索 ResultSet 会引发错误【英文标题】:Using a REF CURSOR to retrieve a ResultSet with java program is throwing an error 【发布时间】:2019-05-24 08:48:08 【问题描述】:

我正在尝试关注this guide,以便从存储过程中检索结果集。

存储过程(Oracle 12c):

CREATE OR REPLACE PROCEDURE GetLastActions
(
  p_actions IN OUT SYS_REFCURSOR
)
IS
BEGIN
  OPEN p_actions FOR SELECT ACTION_ID, ACTION_DATE FROM ACTIONS FETCH NEXT 10 ROWS ONLY;
END;

Java 中的调用(我使用的是 JDK 1.6):

String qLoadTmpData = "call GetLastActions(?)";
Connection con;
try 
    Connection con = getConnection();
    con.setAutoCommit(false);
    CallableStatement stmt = con.prepareCall(qLoadTmpData);
    stmt.setNull(1, Types.REF);
    stmt.registerOutParameter(1, Types.REF);
    stmt.execute();
    ResultSet rs = (ResultSet)stmt.getObject(1);
    System.out.println("Last actions:");
    while(rs.next()) 
        System.out.println(rs.getString(1) + "  => " rs.getDate(2));
    
 catch (Exception e) 
    e.printStackTrace();
    throw new DaoException("Erreur lors de la recuperation des donnees !", e);
 finally 
    closeConnection(con);

错误:

java.sql.SQLException: Invalid column type: sqlType=2006
    at oracle.jdbc.driver.OraclePreparedStatement.setNullCritical(OraclePreparedStatement.java:4696)
    at oracle.jdbc.driver.OraclePreparedStatement.setNull(OraclePreparedStatement.java:4578)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setNull(OraclePreparedStatementWrapper.java:1285)
    at com.company.project.documents.report1.dao.ReportDAO.getRapportResultat(ReportDAO.java:59)
    at com.company.project.documents.report1.service.Service.getResultat(Service.java:40)
    at com.company.project.documents.report1.generator.Generator.generate(Generator.java:20)
    at com.company.project.documents.DocumentsGeneratorMain.main(DocumentsGeneratorMain.java:47)

现在真正的查询比我上面测试的例子复杂得多,这就是我使用游标和存储过程来获取结果的原因。

我错过了什么?

更新

我所指的链接描述了一种与 en EnterpriseDB 相关的方法,这里是 the same approach for Oracle,我测试并得到了同样的错误。

【问题讨论】:

@APC,我的错 :( 我用正确的方法链接编辑了我的问题。感谢您注意到这一点。 【参考方案1】:

我错过了什么?

我认为您错过了尝试将 PostgreSQL 的文档/示例与 Oracle 数据库一起使用。这行不通。不同的数据库和 SQL 方言对游标的支持不同。

这里有一些问答展示了如何将 REF CURSOR 与 Oracle DB 一起使用。

CURSOR and REF CURSOR as a JDBC data type Using cursors and getting result in Oracle PL/SQL with Java/JDBC

(我使用的是 JDK 1.6)

也许您还想念您真的非常需要升级您的 Java 平台。

对于没有支持合同的人来说,Java 6 已经结束了六年多的生命周期。截至 2018 年 12 月,即使对于拥有 Oracle Java SE 扩展支持合同的人来说,它的生命周期也将结束:

Oracle Java SE Support Roadmap

【讨论】:

以上是关于使用 REF CURSOR 通过 java 程序检索 ResultSet 会引发错误的主要内容,如果未能解决你的问题,请参考以下文章

REF CURSOR 总结

未知方言支持 REF_CURSOR 参数

使用 SqlAlchemy 执行返回 REF CURSOR 的 Oracle 存储过程

使用 DBFactory 和 Oracle 存储过程 sys ref cursor 返回数据集

CURSOR 和 REF CURSOR 作为 JDBC 数据类型

让 .NET 了解返回的 REF_CURSOR 中的 Oracle 对象