oracle 存储过程返回结果集合

oracle的存储过程和其他的不同,返回结果集合要用游标来传递,同时存储过程要定义在package程序包中。

一、传递一个参数,返回一个结果集

1.先创建程序包和包体,两者关系类似类和类中的方法

create or replace package test_package is  
       type resCursor is ref cursor; 
       procedure test_procedure(prodId varchar2,res out resCursor);
end test_package;

定义名称为 test_package 的程序包,resCursor 是定义一种游标类型,名称随便定义;

定义包中的存储过程 test_procedure ,prodId是传入的参数,res 是返回的结果游标,类型是上边定义的resCursor。

create or replace package body test_package is
       procedure test_procedure(prodId varchar2,res out resCursor) is --注意这里的参数必须和上边的一致
       begin
          open res for
             select * from abs_product_info where productId= prodId; --这里的参数prodId,不能定义为prodcutId,不同相同
          return;
       end;
end test_package;

定义程序包体,select 的表格是自己的,就不贴出了,自己定义就行了。

至此,数据库端的创建完成。

2. java 代码调用

public static void main(String[] args) {
	Connection con = getConnection();
	CallableStatement cst = null;
	try {
		/**
		 * 第一步: 调用存储过程,这个和JDBC类型,不同的是结果不是直接返回,需要第3步先注册
		 */
		cst = con.prepareCall("{ call test_package.test_procedure(?,?)}"); //1. 预编译存储过程
		cst.setString(1, "2018101000000001"); //2. 设置参数
		cst.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR); //3. 注册返回结果
		cst.execute(); //4. 执行调用过程
		/**
		 * 第二步: 提取结果集合
		 */
		ResultSet rs = (ResultSet)cst.getObject(2); //提取结果,注意:第2个位置的是返回的结果
		while(rs.next()){
			System.out.println("输出结果 "+rs.getString(1));
			System.out.println("输出结果 "+rs.getString(2));
		}
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}	

调用很简单,为看起来简洁,这里结果只输出了两个,测试成功!

输出结果:

输出结果 2018101000000001
输出结果 测试房地产【1010】

二、传入多个参数,输出多个结果集

1. 创建程序包和包体

和单参数、单结果集类似,程序包和包体如下:

create or replace package test_package is
       type resCursor is ref cursor; 
       procedure test_procedure (prodId  varchar2,sId  varchar2,res1 out resCursor,res2 out resCursor);
end test_package;

两个参数:productId 、sId;两个结果游标结果集:res1,res2

create or replace package body test_package is
       procedure test_procedure (prodId varchar2,sId varchar2,res1 out resCursor,res2 out resCursor) is
       begin
          open res1 for
             select * from abs_product_info where productId= prodId;
          open res2 for
             select * from user_info where userId = sId;
          return;
       end;
end test_package;

 相应的增加一个对 res 2的 open ,注意 return 和标点符号。

2. java调用

public static void main(String[] args) {
	Connection con = getConnection();
	CallableStatement cst = null;
	try {
		/**
		 * 第一步: 调用存储过程,这个和JDBC类型,不同的是结果不是直接返回,需要第3步先注册
		 */
		cst = con.prepareCall("{ call test_package.test_procedure(?,?,?,?)}"); //1. 预编译存储过程
		cst.setString(1, "2018101000000001"); //2. 设置第一个参数
		cst.setString(2, "admin"); //2. 设置第二个参数
		cst.registerOutParameter(3, oracle.jdbc.OracleTypes.CURSOR); //3. 注册第一个返回结果
		cst.registerOutParameter(4, oracle.jdbc.OracleTypes.CURSOR); //3. 注册第二个返回结果
		cst.execute(); //4. 执行调用过程
		/**
		 * 第二步: 提取结果集合
		 */
		ResultSet rs1 = (ResultSet)cst.getObject(3); //提取结果,注意:第3个位置的是返回的结果
		ResultSet rs2 = (ResultSet)cst.getObject(4); //提取结果,注意:第4个位置的是返回的结果
		System.out.println("第一个结果集输出数据: ");
		while(rs1.next()){
			System.out.println("输出结果 "+rs1.getString(1));
			System.out.println("输出结果 "+rs1.getString(2));
		}
		
		System.out.println("第二个结果集输出数据: ");
		while(rs2.next()){
			System.out.println("输出结果 "+rs2.getString(1));
			System.out.println("输出结果 "+rs2.getString(2));
		}
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

测试结果:

第一个结果集输出数据:
输出结果 2018101000000001
输出结果 测试房地产【1010】
第二个结果集输出数据:
输出结果 admin
输出结果 admin001

 完成!

猜你喜欢

转载自blog.csdn.net/houdezaiwu1/article/details/83540717
今日推荐