我们使用存储过程都是返回值都是单一的,有时我们需要从过程中返回一个集合。即多条数据。这有几种解决方案。比较简单的做法是写临时表,但是这种做法不灵活。而且维护麻烦。我们可以使用嵌套表来实现.没有一个集合类型能够与java的jdbc类型匹配。这就是对象与关系数据库的阻抗吧。数据库的对象并不能够完全转换为编程语言的对象,还必须使用关系数据库的处理方式。

create or replace package procpkg is 

 type refcursor is ref cursor; 

 procedure procrefcursor(p varchar2, p_ref_postypeList out refcursor); 

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; 

end procpkg;


在包头中定义了一个游标变量,并把它作为存储过程的参数类型。
在存储过程中定义了一个嵌套表变量,对数据写进嵌套表中,然后把嵌套表进行类型转换为table,游标变量从这个嵌套表中进行查询。外部程序调用这个游标。
所以这个过程需要定义两个类型。

create or replace type PosType as Object ( 

 posType varchar2(20), 

 description varchar2(50) 

);


注意:对于游标变量,不能使用for循环来处理。因为for循环会隐式的执行open动作。而通过open for来打开的游标%isopen是为true的。也就是默认打开的。Open一个已经open的游标是错误的。所以不能使用for循环来处理游标变量。