(转)oracle 存储过程 带游标作为OUT参数输出

时间:2022-10-13 19:03:44

(转)oracle 存储过程 带游标作为OUT参数输出

存储过程返回OUT参数的游标 例子。

包中带过程 要自己定义一个type [cur_name] is ref cursor游标,返回的时候就直接 procedure AAA(变量名 out [cur_name])如此申明OUT变量

存储过程 用系统默认的 sys_refcursor 游标类型 定义变量就OK了

--=====================================================

Sql代码 :

--PL/SQL Code (包中带过程) 过程带游标的OUT参数,返回游标(ref cursor)
            
            create or replace package my_pack as
             type my_ref_cursor is ref cursor;
             procedure getMyCursor(val out my_ref_cursor);
            end my_pack;
            
            create or replace package body my_pack as
             procedure getMyCursor(val out my_ref_cursor)
             is
             begin
              open val for select * from student;
             end;
            end my_pack;
   --=====================================================

Sql代码 :
            --PL/SQL Code(存储过程) 带游标的OUT参数,返回游标(ref cursor)
            
            create or replace procedure retCursor(ret_cursor out sys_refcursor)is
            ret_cursor_value  sys_refcursor;
            begin
            open ret_cursor_value for select * from student;
             ret_cursor:=ret_cursor_value;
            end retCursor;

--=====================================================

下面是个每个学生求平均值的存储过程。遇到的问题是带参数游标中的变量名字不要和表中的一样,否则会出问题

create or replace procedure prc_student_avg_score
as

cursor c_sno is select s.sno , s.name from STUDENT s; --查询学生表的ID
cursor sc_avg(s_no varchar2) is select avg(sc.degree) from SCORE sc where sc.sno=s_no; --通过学生ID查询平均成绩

s_sno_j student.sno%type;   --变量ID
sc_avg_i score.degree%type; --变量平均成绩
sname   student.name%type;  
 
begin
 open c_sno;--打开查询ID的游标
 loop
   fetch c_sno into s_sno_j ,sname ;
   --DBMS_OUTPUT.PUT_LINE( '    c_sno当前扫描行:' || c_sno%rowcount );
   exit when c_sno%notfound;
     open sc_avg(s_sno_j); --打开查询平均成绩的游标,参数为学生ID
     loop
       fetch sc_avg into sc_avg_i;
       if  sc_avg_i is null or sc_avg_i=0  then
          sc_avg_i:=0 ;
       end if;
 
       exit when sc_avg%notfound;
       DBMS_OUTPUT.PUT_LINE(  sname || ':' ||sc_avg_i);
 
     end loop;
     close sc_avg;
 end loop;
 close c_sno;
end prc_student_avg_score;