oracle中后台的存储过程就有fucntion(函数)和procedure(过程)之分。
其中function是通过第一种方式获取返回值:
?=call client_no (?,?)。
因为function的是通过return语句返回结果的。
而procedure是没有return语句的。因此只有通过out类型的参数来返回结果,但通过这种方式可以返回多个结果(多定义几个out参数就可以),这是function不能实现的。
因此procedure的调用就是通过call client_no (?,?)。。。。。。。
一般的通用流程
1.获取CallableStatement语句:(关于callablestatement的用法参考另一篇blog)
CallableStatement cs = conn.prepareCall("{call spName(?,?,?)}");
2.传入输入参数和注册输出参数
cs.setXXX(index,value);//输入参数
cs.registerOutParameter(index,type);//输出参数
3.执行存储过程:
cs.execute();
/**
*begin 不是原创
*/
一个存储过程执行后返回的是boolean型:
boolean flag = callableStatement.execute();
如果flag为true,那么说明返回了一个结果集(ResultSet)类型,你可以用getResultSet()得到当前行所在
的结果,而如果返回为flase,说明什么呢?
如果你不进行处理,什么也不能说明,只能说明当前指针不是ResultSet,有可能是更新计数(updateCount)
也可能什么也没有反因.
那么如果当前指针为flase时如何处理?我们应该先getUpdateCount();如果返回-1,既不是结果集,又
不是更新计数了.说明没的返回了.而如果getUpdateCount()返回0或大于0,则说明当前指针是更新计数(
0的时候有可能是DDL指令).无论是返回结果集或是更新计数,那么则可能还继续有其它返回.只有在当前
指指针getResultSet()==null && getUpdateCount() == -1才说明没有再多的返回.
存储过程的返回和ResultSet类似,每次处理的返回结果相当于是ResultSet的Row,只不过存储过程的Row
最先在第一行而不是象ResultSet要先next才到第一行,存储过程向下移动一行用getMoreResults(),相
当于ResultSet的next().同样它返回boolean和上面的flag一样,只是说明当前行是不是ResultSet,如果是
flase,你还是要判断是不是updateCount,在每一行,都要先同时判断是否为ResultSet还是UpdateCount,如
果是其中一种则要继续getMoreResults(),当不是ResultSet也不是updateCount时,说明没有返回结果了,
这时再获取输出参数.
/**
* end
*/
下面的例子我没有用到上面的方法(^_^),不太会用!
/*************************************
*用到游标取结果集,在oracle中单一的procedure
*无法返回结果集.
*************************************/
/*************************************
*存储过程部分 begin
*************************************/
//packages
create or replace package gprmi is
-- Author : meconsea
-- Created : 2005-3-29 15:40:02
-- Purpose : 根据信息id和信息type获得处理信息的详细情况
-- Public type declarations
type outlist is ref cursor;
-- Public function and procedure declarations
procedure getproremarkinfo(
infoIdArg in workflow.processinfo.infoid%type, --//信息id
infoTypeArg in workflow.processinfo.infotype%type, --//信息类型
result_cursor out outlist
);
end gprmi;
//package badies
create or replace package body gprmi is
-- Function and procedure implementations
procedure getproremarkinfo(
infoIdArg in workflow.processinfo.infoid%type, --//信息id
infoTypeArg in workflow.processinfo.infotype%type, --//信息类型
result_cursor out outlist
)is
begin
open result_cursor
for
select a.currentprocessor , c.name as personname, b.currenttache,d.tachename,a.receivedate,a.processdate,a.processremark,a.attitude
from processinfoattach a, processinfo b, operator c,Tache d
where a.processinfoid = b.objectid and a.processstatus = 1
and b.infotype = infoTypeArg and b.infoid = infoIdArg
and a.currentProcessor = c.objectid and b.currentTache = d.objectid
order by a.processdate;
end;
end gprmi;
/*************************************
*存储过程部分 end
*************************************/
/*************************************
*程序部分 begin
*************************************/
/**
* 根据信息类型和信息ID查询该信息的处理情况<调用存储过程(getProcessRemarkInfo)>
* @param infoId --//信息id
* @param infoType --//信息类型
* @return
*/
public ArrayList getProcessRemarkInfo(long infoId, long infoType){
ArrayList al = new ArrayList();
ProcessRemarkInfo pri = null;
oracle.jdbc.OracleCallableStatement ocs = null;
String sqlStr = "{call gprmi.getproremarkinfo(?,?,?)}";
ResultSet rs = null;
try{
ocs = (oracle.jdbc.OracleCallableStatement)conn.prepareCall(sqlStr);
ocs.setLong(1,infoId);
ocs.setLong(2,infoType);
ocs.registerOutParameter(3,oracle.jdbc.OracleTypes.CURSOR);
ocs.execute();
rs = ocs.getCursor(3);
while(rs.next()){
pri = new ProcessRemarkInfo();
long currentProcessor = rs.getLong(1);
pri.setCurrentProcessor(currentProcessor);
pri.setPersonName(rs.getString(2));
pri.setCurrentTache(rs.getLong(3));
pri.setTacheName(rs.getString(4));
pri.setReceiveDate(rs.getDate(5));
pri.setProcessDate(rs.getDate(6));
pri.setProcessRemark(rs.getString(7));
pri.setAttitude(rs.getLong(8));
al.add(pri);
}
rs.close();
ocs.close();
}catch(Exception e){
System.out.println("Exception e"+e.getMessage());
}
return al;
}
/*************************************
*程序部分 end
*************************************/