Java调用Oracle存储过程含游标的两种方法详解

需积分: 43 18 下载量 66 浏览量 更新于2024-09-13 1 收藏 5KB TXT 举报
"这篇文章主要介绍了如何在Java中调用Oracle数据库中的存储过程,特别是涉及到游标的处理。作者分享了自己在学习过程中总结的经验,并提供了两种不同的实现方法。" 在Oracle数据库中,存储过程是一种预编译的SQL和PL/SQL代码集合,可以执行复杂的业务逻辑。Java应用程序通常通过JDBC(Java Database Connectivity)来调用这些存储过程,以与数据库进行交互。本文将探讨两种在Java中调用包含游标的Oracle存储过程的方法。 首先,我们需要创建一个存储过程。例如,创建一个名为`first_package`的包,其中包含一个名为`proc_cur`的存储过程,该过程接收一个输入参数`dno`(部门编号)和一个输出参数`cur`(游标)。存储过程的定义如下: ```sql create or replace package first_package is -- 公共类型声明 type mycur is ref cursor; procedure proc_cur(dnoin number, cur out mycur); end first_package; ``` 接着,我们创建包体,实现存储过程的具体逻辑,打开游标并查询`emp`表中与`dno`匹配的所有员工记录: ```sql create or replace package body first_package is procedure proc_cur(dnoin number, cur out mycur) as begin open cur for select * from emp where emp.deptno = dno; end proc_cur; end first_package; ``` 现在,我们转向Java部分,调用这个存储过程。Java中调用存储过程通常使用JDBC API。以下是两种调用方式: 方法一:使用CallableStatement ```java import java.sql.*; public class JdbcCallProcedure { public static void main(String[] args) { try (Connection conn = DriverManager.getConnection(DBUtils.url, DBUtils.user, DBUtils.password)) { // 准备调用的存储过程 String callProc = "{call first_package.proc_cur(?, ?)}"; CallableStatement cs = conn.prepareCall(callProc); // 设置输入参数 cs.setInt(1, 10); // 假设部门编号为10 // 注册输出参数 cs.registerOutParameter(2, TypesCURSOR); // 执行存储过程 cs.execute(); // 处理游标结果 ResultSet rs = (ResultSet) cs.getObject(2); while (rs.next()) { System.out.println("Employee ID: " + rs.getInt("empno") + ", Name: " + rs.getString("ename")); } } catch (SQLException e) { e.printStackTrace(); } } } ``` 在这个例子中,我们使用`CallableStatement`创建一个调用语句,设置输入参数,注册输出参数(游标),然后执行存储过程。最后,我们从输出参数中获取游标并遍历结果集。 方法二:使用Oracle JDBC驱动的OracleCallableStatement Oracle JDBC驱动提供了一个特定于Oracle的`OracleCallableStatement`类,它可以更好地处理包含游标的存储过程。这个类允许我们直接将结果集作为输出参数。 ```java import oracle.jdbc.*; public class JdbcCallProcedureOracle { public static void main(String[] args) { try (Connection conn = DriverManager.getConnection(DBUtils.url, DBUtils.user, DBUtils.password)) { // 准备调用的存储过程 String callProc = "{call first_package.proc_cur(?, ?)}"; OracleCallableStatement cs = (OracleCallableStatement) conn.prepareCall(callProc); // 设置输入参数 cs.setInt(1, 10); // 注册输出参数,使用Oracle专有的OracleResultSet型 cs.registerOutParameter(2, OracleTypes.CURSOR); // 执行存储过程 cs.execute(); // 获取OracleResultSet OracleResultSet rs = (OracleResultSet) cs.getCursor(2); while (rs.next()) { System.out.println("Employee ID: " + rs.getInt("empno") + ", Name: " + rs.getString("ename")); } } catch (SQLException e) { e.printStackTrace(); } } } ``` 在这个方法中,我们首先将输出参数注册为`OracleTypes.CURSOR`,然后通过`getCursor`方法获取`OracleResultSet`。这种方式更适合处理Oracle特有的游标。 这两种方法都能有效地在Java中调用Oracle存储过程,特别是涉及游标的情况。选择哪种方法取决于项目需求和个人偏好,但通常,如果使用Oracle数据库,使用`OracleCallableStatement`可能会带来更好的兼容性和性能。