Chinaunix首页 | 论坛 | 博客
  • 博客访问: 51989
  • 博文数量: 23
  • 博客积分: 1415
  • 博客等级: 上尉
  • 技术积分: 281
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-04 16:00
文章分类

全部博文(23)

文章存档

2014年(19)

2008年(1)

2007年(3)

我的朋友

分类: Oracle

2014-05-23 16:32:57

                                                    

一、应用背景:
     在PL/SQL中,有时希望将SELECT语句的结果取出,然后逐条处理。但是PL/SQL中的复合变量只能存储一条记录结果。
  因此就迫切需要有一种机制可以解决该应用需求,于是乎,就出现了游标。

二、游标(cursor):


       游标是一个SELECT语句执行结果集,其里面可以存储多条表记录,是一块内存区域。当游标被定义时,内存中并未分配存储空间,只是给了一个存储地址;游标定义中的SELECT也不会被执行。只有当游标被打开时,才会真正的执行SELECT,然后将执行结果放入指定的内存区域;在游标使用完成后,游标使用的内存并不会释放,只有当游标被关闭时,其所占用的内存才会被释放。

      简而言之,打开(open)游标时,分配内存,执行SELECT语句,存储执行结果到内存;关闭(close)游标时,释放其所占用的内存。提取(fetch)游标数据时,当前一行的全部值被取出存入指定的变量中,fetch使得游标指针指向游标的下一条记录。
          
三、创建游标:

  语法:

       cursor cursor_name is select ...;            //无参数游标

       cursor cursor_name(para1 data_type,...) is select ...;    //带参数的游标
       
       例如:cursor A is select * from emp;
              
               cursor A(v_dpetno number) is select * from emp where deptno=v_deptno;
              
  说明:
       cursor,is             ----是关键字
       cursor_name       ----表示游标名字
       select ...             ----表示SELECT语句


四、游标使用:
  
   打开游标:

      命令:open cursor_name;    --例如:open A;    
  
               //分配内存空间,执行游标中定义的SELECT语句,存储结果到内存中  

   关闭游标:

      命令:close cursor_name;   --例如:close A;  
 
            //关闭游标,释放内存。因此在游标使用完成时,一定要关闭游标。

   提取游标数据:
    
      命令: fetch cursor_name into var_name;    --例如:fetch A into v_A;  
 
            //提取游标当前值到变量v_A中,v_A是复合变量。

   游标变量:

          cursor_name%found : 当找到数据时,结果为真(true);反之为假(false);

          cursor_name%notfound : 当无数据找到时,结果为真(true);反之为假(false);
      

五、实例应用


   1、游标数据简单提取: 

    --set serverout on;      打开服务器输出。

    declare
       cursor c_emp is select * from emp;
       v_emp c_emp%rowtype;
    begin
       open c_emp;
       fetch c_emp into v_emp;                            --只取出第一行。
       dbms_output.put_line(v_emp.name);
       close c_emp;
    end;


    --执行结果:


     js_china


     PL/SQL procedure successfully completed.


  2、遍历游标(推荐/经典): 
  
     提示:for循环中游标不需要open、close、featch,for语句会自动完成。

    --set serverout on;      打开服务器输出。

    declare
      cursor c is select * from emp; 
    begin
      for c_emp in c                                 --for循环中游标不需要open、close、featch,for语句会自动完成。
      loop 
       dbms_output.put_line(c_emp.name);
      end loop;
    end;
    
   
  3、遍历游标(while..loop): 


    --set serverout on;      打开服务器输出。 
    declare
      cursor c is select * from emp;
      v_emp c%rowtype;
    begin
      open c;                                 --必须打开游标
      fetch c into v_emp;
      while (c%found) loop
        dbms_output.put_line(v_emp.name);
        fetch c into v_emp;
      end loop;
      close c;
    end;


  4、遍历游标(loop ..exit when): 
 
    --set serverout on;          打开服务器输出。 
    declare
      cursor c is select * from emp;
      v_emp c%rowtype;
    begin
      open c;
      loop
        fetch c into v_emp;
        exit when (c%notfound);
        dbms_output.put_line(v_emp.name);
      end loop;
      close c;
    end;
  
   5、游标更新数据:
     
    --set serverout on;      打开服务器输出。 
    declare
      cursor c is select * from emp for update;      --必须加for update
    begin
      for c_emp in c 
      loop
        if (c_emp.sal < 2000) then 
          update emp set sal=sal + 5000 where current of c;
        elsif (c_emp.sal between 2000 and 10000 ) then
          update emp set sal=sal + 3000  where current of c;
        elsif (c_emp.sal between 10000 and 20000 ) then
          update emp set sal=sal + 1000  where current of c;
        else
          update emp set sal=sal + 100  where current of c; 
        end if ;
      end loop;
      commit;
    end;


   6、带参数的游标:
     
    --set serverout on;      打开服务器输出。 
    declare
      cursor c(v_deptno number) is select * from emp where emp.deptno = v_deptno;
    begin
      for c_emp in c(20)
      loop
         dbms_output.put_line(c_emp.name || ' ''s sal is '||c_emp.sal);
      end loop;
    end;


    执行结果:


    js_china 's sal is 16060
    js2 's sal is 14260
    hgx 's sal is 13260

    PL/SQL procedure successfully completed.

阅读(1050) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~