以下程序是建在SCOTT用户下。
--包头
--SunYS
CREATE OR REPLACE PACKAGE sun_pk1 IS
  TYPE t_ref IS REF CURSOR ;            --参考游标类型
  type t_table is table of emp%rowtype; --参考表类型
  
  procedure p_test(cur out t_ref);      --返回参考游标的过程
  function  f_test return t_ref;        --返回参考游标的函数
  
  procedure tp_test(ttt out t_table);   --返回参考表类型的过程
  function  tf_test return t_table;     --返回参考表类型的函数
END;
/
--包体
--SunYS
CREATE OR REPLACE PACKAGE body sun_pk1 IS
      ---------------------------------------------------------------
      procedure p_test(cur out t_ref) as      --返回参考游标的过程
      begin
          open cur for select * from emp;
      end;  
      --------------------------------------------------------------
      function f_test return t_ref             --返回参考游标的函数
      as
        rc t_ref;
      begin
        open rc for select * from emp;
        return rc;
      end;
      ----------------------------------------------------------------        
      procedure tp_test(ttt out t_table)          --返回参考表类型的过程
      as
      begin
          select * bulk collect into ttt from emp;  
      end;
      ----------------------------------------------------------------      
      function  tf_test return t_table         --返回参考表类型的函数
      as
         tab t_table;
      begin
      
           select * bulk collect into tab from emp;  
           return tab;      
      end;
      --------------------------------------------------------------- 
  
END;
/
--测试过程,仅为演示使用
-SunYS
create or replace procedure test
is
    v_ref sun_pk1.t_ref;    ----游标变量
    v_t_emp emp%rowtype;    ----行类型变量
    v_table sun_pk1.t_table;----表类型
begin
    dbms_output.put_line('===========返回参考游标的过程===============');   
    sun_pk1.p_test(v_ref);
    loop    
    fetch v_ref into v_t_emp;
    exit when v_ref%notfound;
    dbms_output.put_line(rpad(v_t_emp.ename,15,' ')||lpad(v_t_emp.sal,15,' '));
    end loop;
  
    
    dbms_output.put_line('===========返回参考游标的函数===============');
    v_ref:=sun_pk1.f_test;    
    loop    
    fetch v_ref into v_t_emp;
    exit when v_ref%notfound;
    dbms_output.put_line(rpad(v_t_emp.ename,15,' ')||lpad(v_t_emp.sal,15,' '));
    end loop;
    
    dbms_output.put_line('===========返回参考表类型的过程===============');
    sun_pk1.tp_test(v_table);
    for ii in v_table.first..v_table.last loop
    dbms_output.put_line(rpad(v_table(ii).ename,15,' ')||lpad(v_table(ii).sal,15,' '));
    end loop;    dbms_output.put_line('===========返回参考表类型的函数===============');
    v_table:=sun_pk1.tf_test;
    for ii in v_table.first..v_table.last loop
    dbms_output.put_line(rpad(v_table(ii).ename,15,' ')||lpad(v_table(ii).sal,15,' '));
    end loop;       
    
end;
/c:\>sqlplus scott/tiger@ora9SQL*Plus: Release 9.2.0.1.0 - Production on 星期四 10月 23 15:20:34 2003Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
连接到:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - ProductionSQL> set serverout on size 8000
SQL> exec test
===========返回参考游标的过程===============
SMITH                      800
ALLEN                     1600
WARD                      1250
JONES                     2975
MARTIN                    1250
BLAKE                     2850
CLARK                     2450
SCOTT                     3000
KING                      5000
TURNER                    1500
ADAMS                     1100
JAMES                      950
FORD                      3000
MILLER                    1300
===========返回参考游标的函数===============
SMITH                      800
ALLEN                     1600
WARD                      1250
JONES                     2975
MARTIN                    1250
BLAKE                     2850
CLARK                     2450
SCOTT                     3000
KING                      5000
TURNER                    1500
ADAMS                     1100
JAMES                      950
FORD                      3000
MILLER                    1300
===========返回参考表类型的过程===============
SMITH                      800
ALLEN                     1600
WARD                      1250
JONES                     2975
MARTIN                    1250
BLAKE                     2850
CLARK                     2450
SCOTT                     3000
KING                      5000
TURNER                    1500
ADAMS                     1100
JAMES                      950
FORD                      3000
MILLER                    1300
===========返回参考表类型的函数===============
SMITH                      800
ALLEN                     1600
WARD                      1250
JONES                     2975
MARTIN                    1250
BLAKE                     2850
CLARK                     2450
SCOTT                     3000
KING                      5000
TURNER                    1500
ADAMS                     1100
JAMES                      950
FORD                      3000
MILLER                    1300PL/SQL 过程已成功完成。

解决方案 »

  1.   

    我也来写点吧if you open a ref cursor for select * from emp there 
    is ONE open cursor -- the ref cursor.  the select * from emp, that is just textopen p_ref for select * from emp;
    这个将分成两部分 cursor:p_ref  和 sql语句 :select * from emp 他们分别执行:
    the cursor is getting opened
    the statement that will be parsed is represented by the SQL you have "select * from emp"
    the SQL gets parsed, the cursor points to the parsed representation.re
    sun9989 (一品黄山)  
    老哥真热心啊 csdn要多点这样的讨论就好了
    我像是不是下面的好点
    ---------------------------------------------------------------
          procedure p_test(cur out t_ref) as      --返回参考游标的过程
          begin
              open cur for select * from emp;
          end;  
    因为返回的只是一个 cursor的指针 而且代码比 --返回参考游标的函数 少:
     --返回参考表类型的过程 bulk collect 
    这返回的是一个type的整体 要用内存把一个 type 整个的装下是不是可能太耗内存了
    不知道 fetch c BULK COLLECT INTO data LIMIT 100; 会有什么样的效果以上只是个人观点 还请多多指点
      

  2.   

    再给一个老例子:
    1、建立测试表
    CREATE TABLE student
     (
      id                         NUMBER,
      name                       VARCHAR2(30),
      sex                        VARCHAR2(10),
      address                    VARCHAR2(100),
      postcode                   VARCHAR2(10),
      birthday                   DATE,
      photo                      LONG RAW
     );
    /
     
    2、建立带ref cursor定义的包和包体及函数:
    CREATE OR REPLACE
    package pkg_test as
    /* 定义ref cursor类型
       不加return类型,为弱类型,允许动态sql查询,
       否则为强类型,无法使用动态sql查询;
    */
      type myrctype is ref cursor; 
     
    --函数申明
      function get(intID number) return myrctype;
    end pkg_test;
    /
     
    CREATE OR REPLACE
    package body pkg_test as
    --函数体
       function get(intID number) return myrctype is
         rc myrctype;  --定义ref cursor变量
         sqlstr varchar2(500);
       begin
         if intID=0 then
            --静态测试,直接用select语句直接返回结果
            open rc for select id,name,sex,address,postcode,birthday from student;
         else
            --动态sql赋值,用:w_id来申明该变量从外部获得
            sqlstr := 'select id,name,sex,address,postcode,birthday from student where id=:w_id';
            --动态测试,用sqlstr字符串返回结果,用using关键词传递参数
            open rc for sqlstr using intid;
         end if;
     
         return rc;
       end get;
     
    end pkg_test;
    /
     
    3、用pl/sql块进行测试:
    declare
      w_rc       pkg_test.myrctype; --定义ref cursor型变量
     
      --定义临时变量,用于显示结果
      w_id       student.id%type;
      w_name     student.name%type;
      w_sex      student.sex%type;
      w_address  student.address%type;
      w_postcode student.postcode%type;
      w_birthday student.birthday%type;
     
    begin
      --调用函数,获得记录集
      w_rc := pkg_test.get(1);
     
      --fetch结果并显示
     loop
     fetch w_rc into w_id,w_name,w_sex,w_address,w_postcode,w_birthday;
     exit when w_rc%notfound;
     dbms_output.put_line(w_name);
     end loop;
    end;
     
    4、测试结果:
    通过。
      

  3.   

    再顶,
    就是想要更多的CASE