暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

oracle存储过程中游标的使用

知识共鸣 2019-03-29
491

--案例1.使用游标查询部门编号为10的所有人姓名和薪水

create or replace procedure sp_04 is 

begin 

   declare type c is ref cursor;

     emp_sor c;

     ename emp.ename%type;

     sal emp.sal%type;

   begin

     open emp_sor for select ename,sal from emp where deptno=10;

     loop

       fetch emp_sor into ename,sal;--取值标的值给变量

       dbms_output.put_line('ename:'||ename||'sal:'||sal);

       exit when emp_sor%notfound;

     end loop;

     close emp_sor;

   end;

end sp_04;

 

 

 

--案例2.直接定义游标

create or replace procedure sp_05 is 

begin 

  declare 

     cursor emp_sor is select ename,sal from emp where deptno=10;

     ename emp.ename%type;

     sal emp.sal%type;

  begin

    open emp_sor;

    loop

      fetch emp_sor into ename,sal;

       dbms_output.put_line('ename:'||ename||'sal:'||sal);

       exit when emp_sor%notfound;

    end loop;

    close emp_sor;

  end;

end sp_05;

 

 

--案例3.使用记录变量来接受游标指定的表的数据

create or replace procedure sp_06 is 

begin

  declare 

    cursor  emp_sor is select ename,sal from emp where deptno=10;

    --使用记录变量来接受游标指定的表的数据

    type emp_type is record(

       v_ename emp.ename%type,

       v_sal emp.sal%type

    );

    --emp_type声明一个与emp_type 类似的记录变量,该记录有两列,与emp表的ename,sal同类型的列.

    emp_type1 emp_type;

  begin

    open emp_sor;

    loop

      fetch emp_sor into emp_type1;--取游标的值给变量

      dbms_output.put_line(emp_type1.v_ename||','||emp_type1.v_sal);

      exit when emp_sor%notfound;

    end loop;

    close emp_sor;

  end;

end sp_06;

      

--案例4.用for游标取值

create or replace procedure sp_07 is

begin

  declare

    cursor emp_sor is select a.ename from emp a;

    type ename_table_type is table of varchar2(20);

    ename_table ename_table_type;

  begin

    --用for游标取值

    open emp_sor;

    --通过bulk cellect 减少loop处理的开销,使用bulk collect 提高oralce查询效率

    --oracle  8i中首次引入bulk collect 特性,该特性可以让我们在PL/sql中能使用批查询,批查询在某些情况下能显著提高查询效率

    --采用bulk collect 可以将查询结果一次性地加载到collertions 中。

    --而不是通过cursor一条一条地处理

    --可以在select into ,fetch into ,returning into 语句中使用bulk collect.

    --注意在使用bulk collect 时,所有的into 变量都必须是collections

    fetch emp_sor bulk collect into ename_table;

    for i in 1..ename_table.count loop

      dbms_output.put_line(ename_table(i));

    end loop;

    close emp_sor;

  end;

end sp_07;

    

    

 

--案例5.用for取值,带隐形游标会自动打开和关闭

create or replace procedure sp_08 is

begin

  declare 

    cursor emp_sor is select a.ename from emp a;

    type emp_table is table of varchar2(20);

  begin

      for emp_record in emp_sor

         loop

           dbms_output.put_line('第'||emp_sor%rowcount||'雇员名:'||emp_record.ename);

         end loop;

  end;

end sp_08;

 

    

--案例6.判断游标是否打开

create or replace procedure sp_09 is 

begin

  declare

     cursor emp_sor is select a.ename from emp a;

     type emp_table_type is table of varchar2(20);

     emp_table emp_table_type;

  begin

    --用for取值,判断游标是否打开

    if not emp_sor%isopen then 

      open emp_sor;

    end if;

    

    fetch emp_sor bulk collect into emp_table;

    dbms_output.put_line(emp_sor%rowcount);

    

    close emp_sor;

  end;

end sp_09;

    

    

--案例7.使用游标变量取值

create or replace procedure sp_10 is

begin 

  --使用游标变量取值

  declare

    cursor emp_sor is select a.ename,a.sal from emp a;

    emp_record emp_sor%rowtype;

  begin

     open emp_sor;

     loop

       fetch emp_sor into emp_record;

       exit when emp_sor%notfound;

       --exit when emp_sor%notfound 放的位置不一样得到的结果也不一样,如果放到dbms_...后;

       --结果会多显示一行数据,即查询结果的最后一行显示了两次

       dbms_output.put_line('序号'||emp_sor%rowcount||'名称:'||emp_record.ename||'薪水:'||emp_record.sal);

     end loop;

     close emp_sor;

   end;

end sp_10;

 

 

--案例8.带参数的游标,在打开游标的时候传入参数

create or replace procedure sp_11 is 

begin 

  --带参数的游标,在打开游标的时候传入参数

  declare 

     cursor emp_sor(no number) is select a.ename from emp a where a.deptno=no;

     emp_record emp_sor%rowtype;

  begin

    open emp_sor(10);

    loop

      fetch emp_sor into emp_record;

      exit when emp_sor%notfound;

      dbms_output.put_line('序号'||emp_sor%rowcount||'名称:'||emp_record.ename);

    end loop;

    close emp_sor;

   end;

end sp_11;

 

 

--案例9.使用游标做更新操作

create or replace procedure sp_12 is 

begin

  --使用游标做更新,删除操作,必须在定义游标的时候加上for update

  --当然也可以用for update nowait;

  declare

    cursor emp_sor is select a.ename,a.sal from emp a for update;

    cname emp.ename%type;

    csal emp.sal%type;

   begin 

      open emp_sor;

      loop

        fetch emp_sor into cname,csal;

        exit when emp_sor%notfound;

        dbms_output.put_line('名称:'||cname||','||'薪水:'||csal);

        if csal < 2000 then 

          update emp set sal=sal+200 where current of emp_sor;

        end if;

      end loop;

      close emp_sor;

      --要查看更新后的数据,必须得重新打开游标去查询

      open emp_sor;

      

      loop

        fetch emp_sor into cname,csal;

        exit when emp_sor%notfound;

        dbms_output.put_line('名称:'||cname||','||'薪水:'||csal);

      end loop;

      close emp_sor;

     end;

end sp_12;

 

 

 

--案例10.使用游标做删除操作

create or replace procedure sp_13 is 

begin

  --使用游标做更新,删除操作,必须在定义游标的时候加上for update

  declare 

    cursor emp_sor is select a.empno from emp a for update;

    pempno emp.empno%type;

  begin

    open emp_sor;

    loop

      fetch emp_sor into pempno;

      exit when emp_sor%notfound;

      dbms_output.put_line('旧的empno:'||pempno);

      if pempno = 2009 then 

         delete emp where current of emp_sor;

       end if;

    end loop;

    close emp_sor;

    --要查看删除后的数据,必须得重新打开游标去查询

    open emp_sor;

    loop

       fetch emp_sor into pempno;

       exit when emp_sor%notfound;

       dbms_output.put_line('新的empno:'||pempno);

    end loop;

    close emp_sor;

  end;

end sp_13;

 

    

--案例11.直接使用游标而不用去定义

create or replace procedure sp_14 is 

begin 

   for emp_record in(select empno,sal,deptno from emp )   

   loop

     dbms_output.put_line('员工编号:'||emp_record.empno||',薪水:'||emp_record.sal||',部门编号'||emp_record.deptno);

   end loop;

end sp_14;

 

 

--案例12.带sql的统计查询

create or replace procedure sp_15 is 

begin 

   declare 

      type test_cursor_type is ref cursor;

      test_cursor test_cursor_type;

      v_ename emp.ename%type;

      v_count number;

      str_sql varchar2(100);

   begin 

     open test_cursor for select ename from emp;

     loop

       fetch test_cursor into v_ename;

       if v_ename is not null then 

         str_sql:='select count(*) from emp';

         execute immediate str_sql into v_count;

       end if;

       exit when test_cursor%notfound;

       dbms_output.put_line(v_ename||','||v_count);

     end loop;

     close test_cursor;

   end;

end sp_15;    

个人整理出来的oracle存储过程中游标的使用,供大家参考和学习。

文章转载自知识共鸣,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论