ORACLE数据库 游标管理基础

 游标是构建在PL/SQL中的,主要用来查询数据,获得记录集的指针.一些对数据表的复杂操作我们都可以通过游标来进行。

以下代码是在PLSQL Developer 6.0环境中运行的。为了方便,我们使用 scott/tiget登陆PL/SQL,然后拷贝好样例表:
       生成emp_copy表: create table emp_copy as select * from emp;
       生成dept_copy表:  create table dept_copy as select * from dept;

下面我们可以来进行学习了:
游标分为两种:1 静态游标    2 动态游标

  1. 静态游标: 可区分为两种:隐式游标显示游标
          a. 隐式游标是不需要手工来声明、定义和关闭的。
               隐式游标有四个属性:%found 如果有影响到数据表的一行和多行,返回TRUE
                        %notfound 和上面相反,如果没有影响到行,返回TRUE
                         %rowcount 返回影响的行数
                        %isopen 如果游标是打开状态,返回false
    set  serveroutput  on ;
    begin
            
    update  emp_copy  set  ename = ' toms '   where  empno = 7900;
        if sql%found then
               dbms_output.put_line('表已更新了' || sql%rowcount || '行');  //输出 表已更新了1行
        else
               dbms_output.put_line('编号没有找到');
        end if;
    end ;
    /

    b. 显示游标
          
    显示游标需要四个步骤:声明游标->打开游标->获取数据->关闭游标
    /*使用显示游标查询数据*/
    set  serveroutput  on ;
    declare
           sals emp_copy.sal
    % type;
           
    cursor  mycur  is   select  sal  from  emp_copy  where  sal > 2000 /*申明游标*/
    begin
         
    open  mycur;
         loop
             
    fetch  mycur  into  sals;  /*提取游标值赋予sals变量*/
             
    exit   when  mycur % NOTFOUND; / /*如果最后一条fetch语句没有提取到行数据,则%notfound的值为true*/
             dbms_output.put_line(mycur
    % rowcount   ||   ' 员工工资:  '   ||  sals);
         
    end  loop;
         
    close  mycur; /*关闭游标*/
    commit ;
    end ;
    /

    /*显示游标更新行*/
    set  serveroutput  on ;
    declare
           sals emp_copy.sal
    % type;
           
    cursor  mycur  is   select  sal  from  emp_copy  where  sal > 2000   for   update   of  sal;
    begin
         
    open  mycur;
         loop
             
    fetch  mycur  into  sals;
             
    exit   when  mycur % notfound;
             
    update  emp_copy  set  sal = sals * 1.1   where   current   of  mycur; /*修改游标指向的行*/
         
    end  loop;
         
    close  mycur;
    commit ;
    end ;
    /
/*带参数的游标*/
set  serveroutput  on ;
declare
       dno dept_copy.deptno
% type;
       eno emp_copy.empno
% type;
       e_name emp_copy.ename
% type;
       
cursor  mysur(dtparam  number is   select  empno,ename  from  emp_copy  where  deptno = dtparam; /*定义带参数的游标,注意:游标包含两个字段*/
begin
     dno :
=   & 部门编号;
     
open  mysur(dno);  /*打开带参数的游标*/
     loop
         
fetch  mysur  into  eno,e_name; /*提取游标值到变量*/
         
exit   when  mysur % notfound;
         dbms_output.put_line(eno 
||   '   '   ||  e_name);
     
end  loop;
     
close  mysur;
commit ;
end ;
/
            c 循环游标:可以使用循环游标简化显示游标的代码。循环游标隐式打开游标,自动从活动集获取行,然后在处理完后自动关闭游标
/*循环游标:可以简化显示游标的处理代码。循环游标自动从活动集获取行,然后在处理完毕后自动关闭游标*/
set  serveroutput  on ;
declare
       
cursor  mycur  is   select  empno,ename,sal  from  emp_copy;
begin
     
for  emp_rec  in  mycur  /*emp_rec是记录索引*/
     loop
         dbms_output.put_line(
' 员工编号: '   ||  emp_rec.empno  ||   ' 员工姓名: '   ||  emp_rec.ename  ||   ' 员工工资: '   ||  emp_rec.sal);
     
end  loop;
     
/*循环游标在处理完毕后自动关闭*/
end ;
/

2.   REF游标:动态游标实例

/*REF游标: 引用游标,在程序运行时动态决定执行何种查询时,使用REF游标*/
set  serveroutput  on ;
declare
       type mycur 
is  ref  cursor ; /*自定义类型mycur,是一个弱类型动态游标类型,因为没有返回参数*/
      test_cur mycur;    
/*声明游标变量test_cur*/
       t_id 
number ;
       t_name 
varchar2 ( 100 );
       selection 
varchar2 ( 1 ) : =   upper (substr( ' &chr ' , 1 , 1 )); /*取出输入的字符串的第一个字母,并将其变为大写字母。赋给声明的selection变量*/
begin
     
if  selection = ' E '   then
        
open  test_cur  for   select  empno,ename  from  emp_copy;  /*关联游标和结果集*/
        dbms_output.put_line(
' 员工信息: ' );
     elsif selection
= ' D '   then
        
open  test_cur  for   select  deptno,dname  from  dept;
        dbms_output.put_line(
' 部门信息 ' );
     
else
        dbms_output.put_line(
' 请输入正确的信息(E)或(D) ' );
        
return ;
     
end   if ;
     
     
fetch  test_cur  into  t_id,t_name;  /*提取游标值给变量*/
     
while  test_cur % found loop  /*如果有数据行,则循环*/
           dbms_output.put_line(
' # '   ||  t_id  || ' : '   || t_name);
           
fetch  test_cur  into  t_id,t_name; /*提取下一条数据行*/
     
end  loop;
     
close  test_cur;
commit ;
end ;
/

 

/*REF游标:用REF游标演示动态SQL的使用*/
set  serveroutput  on ;
declare
       r_emp emp_copy
% rowtype;  /*定义一个emp_copy表的行类型变量*/
       type mycur 
is  ref  cursor /*声明一个REF游标类型*/
       test_cur mycur;  
/*定义一个mycur游标类型的变量test_cur*/
       r_sal 
number  : = 2500 ;
begin
     
/*关联游标到一个结果集,:1是占位符,表示可以引入或导出的第一个参数*/
     
open  test_cur  for   ' select * from emp_copy where sal>:1 order by sal desc '
     using r_sal;   
/*传入参数*/
     dbms_output.put_line(
' 工资大于 '   ||  r_sal  ||   ' 的员工有: ' );
     loop
         
fetch  test_cur  into  r_emp;  /*将游标中的结果集第一行赋给行对象r_emp*/
         
exit   when  test_cur % notfound;
         dbms_output.put_line(
' 编号: '   ||  r_emp.empno  ||   ' 姓名: '   ||  r_emp.ename  ||   ' 工资: '   ||  r_emp.sal);
     
end  loop;
     
close  test_cur;  /*记得关闭游标*/
commit ;
end ;
/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值