jdbc 通过存储过程得到结果集
oracle 中存储结果集一般使用的是游标,所以,一般 select 一个结果集后会保存在游标中,而jdbc调用该存储过程时,只需要提取该游标即可。
需要注意的是通过 Cursor 定义的游标变量,无法做为存储过程的返回值,这里需要用到 自定义的游标变量,使用 "Type 游标类型名 is REF CURSOR"。
所以,
1、一般的做法是需要创建在oracle中创建包,包头是该自定义的游标变量以及存储过程的声明;在包体中实现该存储过程:
1 create or replace package pk_pro1 as 2 type user_refcursor is ref cursor; 3 procedure sp_pro8(users_cursor out user_refcursor); 4 end pk_pro1; 5 6 create or replace package body pk_pro1 as 7 procedure sp_pro8(users_cursor out user_refcursor) is 8 begin 9 open users_cursor for select * from t_user; 10 end sp_pro8; 11 end pk_pro1;
下面是jdbc调用该包中的存储过程的代码(conn是connection对象、cs是CallableStatement对象):
1 @Test 2 public void testPackage(){ 3 String sql = "{call pk_pro1.sp_pro8(?)}"; 4 try { 5 cs = conn.prepareCall(sql); 6 cs.registerOutParameter(1, OracleTypes.CURSOR); 7 cs.execute(); 8 rs = (ResultSet) cs.getObject(1); 9 while(rs.next()){ 10 System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getInt(3)); 11 } 12 } catch (SQLException e) { 13 e.printStackTrace(); 14 } 15 }
2、还有一种方式,直接使用系统中已经定义的游标变量 sys_refcursor ,这样就可以免去我们自己创建游标类型的部分了
create or replace procedure sp_pro7(users_cursor out sys_refcursor) is begin open users_cursor for select * from t_user; end;
jdbc调用存储过程:
1 @Test 2 public void testSelect() { 3 String sql = "select * from t_user"; 4 try { 5 ps = conn.prepareStatement(sql); 6 rs = ps.executeQuery(); 7 while(rs.next()){ 8 System.out.println(rs.getInt(1)+" "+rs.getString(2)+" "+rs.getInt(3)); 9 } 10 } catch (SQLException e) { 11 e.printStackTrace(); 12 } 13 }