如何从 Java 存储过程将 JDBC ResultSet 作为 Ref Cursor 返回

如何从 Java 存储过程将 JDBC ResultSet 作为 Ref Cursor 返回

日期:2003 年 3 月 3 日

在阅读此方法文档以后,您应该能够:

  • 创建将 JDBC 结果集作为 REF CURSOR 返回的 Java 存储过程

  • 创建 Java 存储过程的调用规范

简介

本文档演示如何从 Java 存储过程将 JDBC ResultSet 作为 REF CURSOR 返回。JDBC ResultSet 是一个表示数据库的数据表,通常通过执行查询数据库的语句产生该表。REF CURSORPL/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 对象中。

软件需求

  • Oracle9i Database 版本 9.0.1 或更高版本。您可从 Oracle 技术网下载 Oracle9i 数据库。

  • JDK1.2.x 或以上版本。可以从此处下载。

说明

首先必须创建 Java 存储过程。以下为代码段。单击此处查看完整的 java 代码。

在 Java 存储过程中,可获得默认的服务器端对数据库的连接。默认情况下,由服务器端 JDBC 驱动程序创建的语句产生不能转换为 REF CURSORResultSet 对象。要将 ResultSet 作为 REF CURSOR 返回,必须以特殊方式创建 StatementPreparedStatement,即必须在创建该语句之前对 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 存储过程编写调用规范。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值