JDBC 中的 Pl/sql %RowType

Posted

技术标签:

【中文标题】JDBC 中的 Pl/sql %RowType【英文标题】:Pl/sql %RowType in JDBC 【发布时间】:2011-09-13 22:52:49 【问题描述】:

我一直在尝试执行一个使用 JDBC 返回 %ROWTYPE 的 Oracle 存储过程,如下所述

  OracleCallableStatement ocs = (OracleCallableStatement)conn.prepareCall("begin <PackageName>.procedureName(?,?,?,?); end; ");
  ocs.setString(1, "001");
  ocs.registerOutParameter(2,java.sql.Types.VARCHAR);
  ocs.registerOutParameter(3,java.sql.Types.VARCHAR);
  ***ocs.registerOutParameter(4,java.sql.Types.OTHER);*** /*here What do i need to put, i didn't find Wrapperclass which is compatible for %ROWTYPE*/

 ocs.executeUpdate(); 

 String newerrorcode =  ocs.getString(2);

System.out.println("\n ErrorCode = " + newerrorcode );
String newErrorDesc =  ocs.getString(3);

System.out.println("\n ErrorDesc = " + newErrorDesc );
ResultSet rs = (ResultSet) ocs.getObject(4);

异常:我们得到如下

Exception in thread "main" java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'PR_APP_DATE'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
at oracle.jdbc.driver.T4CCallableStatement.doOall8(T4CCallableStatement.java:202)
at oracle.jdbc.driver.T4CCallableStatement.executeForRows(T4CCallableStatement.java:1005)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530)
at oracle.jdbc.driver.OracleCallableStatement.executeUpdate(OracleCallableStatement.java:4735)
at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
at testSysBusinessDts.main(testSysBusinessDts.java:62)

【问题讨论】:

【参考方案1】:

我已经完成了与您所要求的类似的事情。诀窍是声明行类型的引用并将返回声明为游标。 I've found the same result elsewhere, hope it helps you.

【讨论】:

【参考方案2】:

简单的答案:使用JPublisher,并将JPublisher 创建的类型映射到JDBC Connection 类型映射。

长答案:JDBC 规范和 Oracle JDBC 驱动程序都不允许将自定义(用户定义的)类型自动转换为 Java 对象,反之亦然。必须为此建立类型映射,以便驱动程序可以以适当的方式读取和写入连接。虽然 Oracle JDBC 驱动程序确实允许读取和写入某些 SQL 类型,但使用 oracle.sql.* 类,它不能应用于 UDT,因为无法预先知道 UDT 的结构。使用 JPublisher 解决了这个问题,因为它创建了反映 UDT 结构的类;一旦 Oracle JDBC 驱动程序考虑了这些类,它就可以从结果集中读取适当的类型,或者可以将这些类型的对象写入连接流。

【讨论】:

以上是关于JDBC 中的 Pl/sql %RowType的主要内容,如果未能解决你的问题,请参考以下文章

通过 JDBC 运行 PL/SQL 和 T-SQL

JDBC:调用外部 SQL 脚本,它声明一个 PL/SQL 包

使用 JDBC 从 PL/SQL 存储函数中获取表返回值

远程调试 PL/SQL 包

带有输入参数的 Oracle JDBC 调用 PL/SQL 过程记录表

是否可以从 jdbc 调用 pl/sql 函数并按名称注册返回值?