在jdbc下利用Oracle的存储过程取得比较复杂的数据集合

方法是利用游标表达式。(只有9i后才能使用此方法)

数据我是利用oracle中自带的scott用户,他下面有emp和dept两张表。

我先利用java描述获取的数据结构

class SalaryInfo{

         Stringdeptname;//部门姓名

         Stringdeptno;//部门号

         doublesalavg;//部门平均工资

         doublesalsum;//部门工资总和

         List<Employee>employees;//该部门下面的员工集合

}


下面是存储过程的代码:

--创建一个包,用于存储过程的参数
create or replace package get_emp_info_pkg is
 type refcursor is ref cursor;--含有一个游标
end;
--将三处test code的注释去掉,并将open all_emp_info for......这个语句注释掉,再将本存储过的
--参数去掉,运行该存储过程可以直接看到结果。
create or replace procedure get_emp_info(all_emp_info out get_emp_info_pkg.refcursor) is
 /*--test code
 type refcursor is ref cursor;
 cursor all_emp_info is 
  (
   select dept.dname,dept.deptno,
      nvl(temp.salavg,0) salavg,
      nvl(temp.salsum,0)salsum,
      cursor(select * from emp where deptno = dept.deptno) from dept 
   left outer join 
   (select deptno,sum(sal) salsum,round(avg(sal),2) salavg from emp group by emp.deptno) temp
    on dept.deptno = temp.deptno
  );
  */
  --部门下的员工游标
  emplist get_emp_info_pkg.refcursor;
  
  --单个员工
  employee emp%rowtype;
  
  --部门信息
  dname varchar2(32);
  deptno number(3);
  salavg number(9,2);
  salsum number(9,2);
begin
 /* --test code
	open all_emp_info;
 */
 --打开游标
 open all_emp_info for 
   --下面的语句是获取部门名称、部门号等信息
   select dept.dname,dept.deptno,
      nvl(temp.salavg,0) salavg,
      nvl(temp.salsum,0)salsum,
	  --游标表达式,获取每个部门下的员工
      cursor(select * from emp where deptno = dept.deptno) from dept 
   left outer join 
   --下面这个语句是获得每个部门的平均工资和工资总和
   (select deptno,sum(sal) salsum,round(avg(sal),2) salavg from emp group by emp.deptno) temp
    on dept.deptno = temp.deptno
  ;
  /*--test code
 loop
  --第一层循环,获取基本信息,emplist是指向员工集合的游标
  fetch all_emp_info into dname,deptno,salavg,salsum,emplist;
  --判断退出的条件
  exit when all_emp_info%notfound;
  --打印
   dbms_output.put_line('部门:'||dname||'平均工资:'||salavg||'工资总和:'||salsum);
   --第二层循环
   loop 
   --获取员工信息
     fetch emplist into employee;
     exit when emplist%notfound;
	 --打印员工信息
       dbms_output.put_line(
       employee.ename||chr(9)||
       employee.deptno||chr(9)||
       employee.mgr||chr(9)||
       employee.job||chr(9)||
       employee.hiredate); 
   end loop;
 end loop;
 */
end;

java代码


package com.test.oracle;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;


public class Test {
	public static void main(String[] args) {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL","scott","root");
			
			CallableStatement cs = ct.prepareCall("{call get_emp_info(?)}");
			//注册参数
			cs.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
			cs.execute();
			
			//最外层返回的是部门信息集合
			ResultSet rs = (ResultSet)cs.getObject(1);
			while(rs.next()){
				System.out.println("部门名称\t\t部门号\t\t平均薪水\t\t总和薪水:");
	
				System.out.println(rs.getString(1)+"\t\t"+rs.getString(2)+"\t\t"+rs.getString(3)+"\t\t"+rs.getString(4)+"\t");//里面返回的是该部门下面的员工集合。
				ResultSet rs2 = (ResultSet)rs.getObject(5);
				System.out.println("员工姓名\t\t员工职位\t\t入职时间\t\t员工薪水");
				
				while (rs2.next()) {
					System.out.print(rs2.getString(2)+"\t\t");
					System.out.print(rs2.getString(3)+"\t\t");
					System.out.print(rs2.getString(5)+"\t\t");
					System.out.println(rs2.getString(6)+"\t\t");
				}
			}
			
			cs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值