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
完成!