如何从 Java 存储过程将 JDBC ResultSet 作为 Ref Cursor 返回
日期:2003 年 3 月 3 日
在阅读此方法文档以后,您应该能够:
简介
本文档演示如何从 Java 存储过程将 JDBC ResultSet 作为 REF CURSOR 返回。JDBC ResultSet 是一个表示数据库的数据表,通常通过执行查询数据库的语句产生该表。REF CURSOR 是 PL/SQL 中相应的类型。Java 存储过程的调用规范将 ResultSet 映射到 REF CURSOR。在 Oracle9i 之前,不可能从 Java 存储过程直接返回一个 ResultSet,因为没有定义表单 ResultSet->REF CURSOR 的映射。Oracle9i 增加了此映射,允许从函数返回 ResultSet 或将其作为 OUT 参数传到某个过程。但它仍不支持逆向映射 (REF CURSOR->ResultSet),因此当前版本的数据库仍然不支持 IN 和 IN OUT 参数。
在本方法指南中,我们拥有两个 Java 存储过程。Java 存储过程 getEmployees() 将 SCOTT 模式中 EMP 表的所有列装入 ResultSet 中并将其返回。Java 存储过程 getDepartments(ResultSet[] rout) 将 ResultSet 对象作为 OUT 参数并将 DEPT 表的所有列装入此 ResultSet 对象中。
软件需求
说明
首先必须创建 Java 存储过程。以下为代码段。单击此处查看完整的 java 代码。
在 Java 存储过程中,可获得默认的服务器端对数据库的连接。默认情况下,由服务器端 JDBC 驱动程序创建的语句产生不能转换为 REF CURSOR 的 ResultSet 对象。要将 ResultSet 作为 REF CURSOR 返回,必须以特殊方式创建 Statement 或 PreparedStatement,即必须在创建该语句之前对 Connection 调用 setCreateStatementAsRefCursur(true)。如果不能在创建 ResultSet 并将其作为 REF CURSOR 返回之前调用 setCreateStatementAsRefCursor(true),则在执行 Java 存储过程时将会导致出现下列错误消息:
ORA-00932:inconsistent datatypes
一旦对此 Connection 对象调用了 setCreateStatementAsRefCursor(true),由对此连接的查询返回的所有 ResultSet 可以转换为 REF CURSOR。
Java 存储过程列表 1
public static ResultSet getEmployees() { .............
.............
// Obtain default connection Connection conn = new OracleDriver().defaultConnection();
// Create any subsequent statements as a REF CURSOR ((OracleConnection)conn).setCreateStatementAsRefCursor(true);
// Create the statement
Statement stmt = conn.createStatement();
// Query all columns from the EMP table
ResultSet rset = stmt.executeQuery("select * from emp");
// Return the ResultSet (as a REF CURSOR) return rset; ........... ...........
|
|
在上面的 Java 存储过程中,通过对默认服务器连接调用 setCreateStatementAsRefCursor(true),默认服务器连接设置为返回可以转换为 REF CURSOR 的 ResultSet。然后查询 EMP 表中的所有行并返回 ResultSet。
Java 存储过程列表 2
public static void getDepartments( ResultSet[] rout ) {
............
............
// Obtain the default connection Connection conn = new OracleDriver().defaultConnection();
// Create any subsequent statements as a REF CURSOR ((OracleConnection)conn).setCreateStatementAsRefCursor(true);
// Create the statement Statement stmt = conn.createStatement();
// do a simple query ResultSet rset = stmt.executeQuery("select * from dept");
// return the ResultSet (as a REF CURSOR) rout[0] = rset; ........... ...........
|
|
上面的 Java 存储过程 getDepartments( ResultSet[] rout ) 查询 DEPT 表的所有行并在 OUT 参数中返回 ResultSet。
如要观看应用程序的运行,请将 Java 类加载到您数据库的 SCOTT 模式中。
>loadjava -thin -user scott/tiger@<hostname>:<port>:<SID>
-resolve -verbose RefCursor.java
其中:
| <hostname> |
安装数据库的主机名称 |
| <port> |
数据库的 TNS 监听器端口 |
| <SID> |
数据库名称 |
例如:
>loadjava -thin -user scott/tiger@insn104a.idc.oracle.com:1521:otn9idb -resolve -verbose RefCursor.java
然后创建 Java 存储过程的调用规范。连接到 SCOTT/TIGER 用户并在 SQL 提示符处执行以下代码
create or replace package refcurpkg is
type refcur_t is ref cursor;
end refcurpkg;
/
create or replace function getemps return refcurpkg.refcur_t is
language java name 'RefCursor.getEmployees() return java.sql.ResultSet';
/
create or replace procedure getdepts(cur OUT refcurpkg.refcur_t) is
language java name 'RefCursor.getDepartments(java.sql.ResultSet[])';
/
|
|
在上面的列表中,在包 refcurpkg 中创建了一个新的类型作为 REF CURSOR 类型。然后创建 Java 存储过程的调用规范。返回 REF CURSOR 的调用规范 getemployees 发布 Java 存储过程 getEmployees()。由 Java 存储过程 getEmployees() 返回的 ResultSet 映射到 REF CURSOR。
调用规范 getdepts 发布 Java 存储过程 getDepartments,并将 OUT 参数 REF CURSOR 映射到 ResultSet
现在可以通过在 SQL 提示符处执行以下代码来测试 Java 存储过程
SQL>variable x refcursor SQL>execute :x := getemps; SQL>print x
此操作将打印 SCOTT 模式中 EMP 表的内容。
SQL>execute getdepts(:x); SQL>print x
此操作将打印 SCOTT 模式中 DEPT 表的内容。
资源
总结
本文说明了如何创建将 JDBC ResultSet 作为 REF CURSOR 返回的 Java 存储过程,以及如何为Java 存储过程编写调用规范。
|