实用Oracle存储过程技巧(六)

2015-01-22 21:19:28 · 作者: · 浏览: 20
procpkg.procrefcursor('a',v_ref_postype); loop fetch v_ref_postype into v_postype,v_desc; exit when v_ref_postype%notfound; dbms_output.put_line('posType:'|| v_postype || ';description:' || v_desc); end loop; end;
注意:对于游标变量,不能使用for循环来处理。因为for循环会隐式的执行open动作。而通过open for来打开的游标%isopen是为true的。也就是默认打开的。Open一个已经open的游标是错误的。所以不能使用for循环来处理游标变量。

我们主要讨论的是如何通过jdbc调用来处理这个输出参数。
conn = this.getDataSource().getConnection();   
CallableStatement call = conn.prepareCall("{call procpkg.procrefcursor(?,?)}");   
call.setString(1, null);   
call.registerOutParameter(2, OracleTypes.CURSOR);   
call.execute();   
ResultSet rsResult = (ResultSet) call.getObject(2);   
while (rsResult.next()) {   
  String posType = rsResult.getString("posType");   
  String description = rsResult.getString("description");   
  ......   
}  

这就是jdbc的处理方法。

Ibatis处理方法:
1.参数配置
    
     
     
   
  
2.调用过程   
     
      {call procpkg.procrefcursor(?,?)}   
     
  
3.定义自己的处理器   
  public class CursorHandlerCallBack implements TypeHandler{   
    public Object getResult(CallableStatement cs, int index) throws SQLException {   
        ResultSet rs = (ResultSet)cs.getObject(index);   
        List result = new ArrayList();   
        while(rs.next()) {   
            String postype =rs.getString(1);   
            String description = rs.getString(2);   
            CodeTableItemDTO posTypeItem = new CodeTableItemDTO();   
            posTypeItem.setCode(postype);   
            posTypeItem.setDescription(description);   
            result.add(posTypeItem);   
        }   
        return result;   
    }   
  
  
  
4. dao方法   
    public List procPostype() {   
        String p = "";   
        Map para = new HashMap();   
        para.put("p",p);   
        para.put("p_ref_postypeList",null);   
         this.getSqlMapClientTemplate().queryForList("pos_dayprocset.procrefcursor",  para);   
         return (List)para.get("p_ref_postypeList");   
    }  

这个跟jdbc的方式非常的相似.
我们使用的是ibatis的2.0版本,比较麻烦。
如果是使用2.2以上版本就非常简单的。
因为可以在parameterMap中定义一个resultMap.这样就无需要自己定义处理器了。
可以从分析2.0和2.0的dtd文件知道。

上面的两种方式都是非常的复杂,如果仅仅是需要返回一个结果集,那就完全可以使用函数来实现了。
create or replace package procpkg is   
   type refcursor is ref cursor;   
   procedure procrefcursor(p varchar2, p_ref_postypeList  out refcursor);   
   function procpostype(p varchar2) return PosTypeTable;    
end procpkg;   
  
create or replace package body procpkg is   
  procedure procrefcursor(p varchar2, p_ref_postypeList out  refcursor)   
  is   
    v_posTypeList PosTypeTable;   
  begin   
    v_posTypeList :=PosTypeTable();--初始化嵌套表   
    v_posTypeList.extend;   
    v_posTypeList(1) := PosType('A001','客户资料变更');   
    v_posTypeList.extend;   
    v_posTypeList(2) := PosType('A002','团体资料变更');   
    v_posTypeList.extend;   
    v_posTypeList(3) := PosType('A003','受益人变更');   
    v_posTypeList.extend;   
    v_posTypeList(4) := PosType('A004','续期交费方式变更');   
    open p_ref_postypeList for  select * from table(cast (v_posTypeList as PosTypeTable));   
  end;   
  
  function procpostype(p varchar2) return PosTypeTable   
  as   
   v_posTypeList PosTypeTable;   
  begin   
      v_posTypeList :=PosTypeTable();--初始化嵌套表   
    v_posTypeList.extend;   
    v_posTypeList(1) := PosType('A001','客户资料变更');   
    v_posTypeList.extend;   
    v_posTypeList(2) := PosType('A002','团体资料变更');   
    v_posTypeList.extend;   
    v_posTypeList(3) := PosType('A003','受益人变更');   
    v_posTypeList.extend;   
    v_posTypeList(4) := PosType('A004','续期交费方式变更');   
    return  v_posTypeList;   
  end;   
end procpkg;  

ibatis配置