Oracle PL/SQL语句基础学习笔记(下)

游标

游标: 游标(cursor)可以被看作指向结果集(a set of rows)中一行的指针(pointer)。在oracle数据库中可以使用显示或隐式两种游标。

1、隐式游标

在执行一个sql语句时,oracle服务器将自动创建一个隐式游标,这个游标是内存中处理该语句的工作区域,其中存储了执行SQL语句的结果.通过游标的属性可获得sql语句执行的结果以及游标状态信息。

游标的主要属性如下:

%found      布尔属性 如果sql语句至少影响一行则为true 否则为false  
%notfound   布尔属性与%found相反。  
%isopen     布尔属性游标是否打开 打开为true 否则为false  
%rowcount   数字属性返回受sql语句影响的行数  

怎么来使用这些属性呢?
则可以通过“sql属性名”来查看结果

//%rowcount 用来检查受影响的行  
SQL> declare  
     emp_row emp%rowtype;  
     begin  
     select * into emp_row from emp where empno=7369;  
     dbms_output.put_line(sql%rowcount);  
     end;  
     /  

1 //返回的结果为1  
//%found用来检查是否影响到了行  
SQL> begin  
     update emp set sal=2000 where empno=7369;  
     if sql%found then  
     dbms_output.put_line('更新记录成功影响了'||sql%rowcount||'行');  
     else  
     dbms_output.put_line('未更新记录');  
     end if;  
     end;  
     / 

更新记录成功 影响了1

//%notfound
//%isopen
以上两个的使用方式参考 %found进行理解。

另外一种隐式游标cursor for loop可用于处理sql语句的结果集

SQL> begin 
     for rec in (select * from emp) 
     loop      dbms_output.put_line(rec.empno||'/'||rec.ename||'/'||rec.job||'/'||rec.mgr||'/'||rec.hiredate||'/'||rec.sal||'/'||rec.comm||'/'||rec.deptno);  
     end loop;  
     end;  
     /  

2、显示游标

显示游标是在PL/SQL程序中使用包含select语句来声明的游标。如果需要处理从数据库中检索的一组记录,则可以使用显示游标。

(1).显示游标处理数据四步骤

  • 声明游标

    声明游标就是通过定义游标的名称,游标的特性来声明游标,以及打开游标 后就可调用查询语句

语法:

Cursor cursor_name[parameter[,parameter]….]  [return return_type] is select_statement;

Parameter作为游标的输入参数,它可以让用户在打开游标时,向游标传递值;

语法:

Parameter_name [in] datatype[{:=|default} expression]\

举例:

 declare  
 cursor emp_cursor (pno in number(4) default 7369)  
 is select * from emp  where empno=pno; 
  • 打开游标

指执行声明游标时指定的查询语句。打开的方式只需使用open打开。

语法:

Open cursor_name(参数);  

如果没有指定参数就采用默认值执行select语句

  • 检索数据

检索数据就是从检索到的结果集中获取数据保存到变量中,以便变量进行处理。

使用fetch语句找出结果集中的单行,并从中提取单个值传递给主变量。

语法:

Fetch cursor_name into [variable_list[record_variable]]

变量用于存储检索的数据

  • 关闭游标

close 游标名称

综上所述综合案例如下:

SQL> declare  
     cursor emp_cursor (pno in number default 7369)   //声明游标  
     is select * from emp where empno=pno;    
     emp_row emp%rowtype; //声明变量  
     begin  
         open emp_cursor(7934); //打开游标  
         fetch emp_cursor into emp_row; //检索数据 结果为一行  
         dbms_output.put_line(emp_row.ename); //输出检索结果
         close emp_cursor; //关闭游标  
     end;  
     /  

(2).游标for循环

依次读取结果集中的行,当for循环开始时,游标会自动打开(不需要使用open方法开启),每循环读取一次,系统自动读取当前数据(不需要使用fetch),当退出for循环时,游标也会自动关闭(不需要使用close方法)

SQL> declare  
  cursor emp_cursor (pno in number default 7369) //声明游标  
  is select * from emp where empno=pno;  

  begin  
     for emp_row in emp_cursor(7934) loop //for循环开始时 自动打开游标 并且自动获取数据 自动关闭  
      dbms_output.put_line(emp_row.ename);  
     end loop;  
  end;  
  /  

(3).游标变量

游标变量也可以处理多行查询结果集。

(3.1).弱ref cursor类型

游标变量定义两个步骤:

  • 定义cursor类型的指针

语法:

Type ref_cursor_name is ref cursor[return return_type]  

举例:

Type var_cursor_name is ref cursor;  
  • 定义ref cursor类型的变量
v_rc var_cursor_name;  

综合写法如下:

Type var_cursor_name is ref cursor;  
v_rc var_cursor_name; 

上面的综合声明的游标变量 称为弱的ref cursor类型,因为它没有指明游标返回的结果,因此它可以指向任何一个具有多列的select查询结果.

(3.2).强ref cursor类型

声明:

Type varcursorName is ref cursor return emp%rowtype; //指明了返回的结果  
Vcn varcursorName; //声明一个强的ref cursor类型的变量  

使用游标变量与游标使用方式一样,也需要声明,打开,检索,关闭游标变量。

综合案例如下:

 SQL> declare  
      type emp_cname is ref cursor return emp%rowtype; //声明游标变量第一步 
      ecname emp_cname; //声明游标变量第二步
      emp_row emp%rowtype; //声明用于保存检索数据的变量 
      begin  
       dbms_output.put_line('开始');  
       open ecname for select * from emp where empno=7934; //打开游标变量  
       loop  
        fetch ecname into emp_row; //查询结果赋值给保存的变量  
        exit when ecname%notfound; //退出条件  
        dbms_output.put_line(emp_row.ename); //输出结果  
       end loop; //退出循环  
       close ecname; //关闭游标变量  
       dbms_output.put_line('结束');  
     end;  
     /  

开始
MILLER
结束

//复杂的案例  
SQL> declare
     type emp_cname is ref cursor return emp%rowtype;
     ecname emp_cname;
     emp_row emp%rowtype;
     begin  
       dbms_output.put_line('开始');  
       open ecname for select * from emp;  
       loop  
        fetch ecname into emp_row;  
        exit when ecname%notfound;  
        dbms_output.put_line(emp_row.ename);  
       end loop;  
       close ecname;  
     dbms_output.put_line('结束');  
    end;  
    /  

开始
SMITH
ALLEN
WARD
JONES
MARTIN
BLAKE
CLARK
SCOTT
KING
TURNER
ADAMS
JAMES
FORD
MILLER
结束

使用游标更新数据库

定位游标之后进行删除|修改指定的数据行 更新的时候需要使用for update选项。

Cursor cursor_name is select_statement;  
For update[of column[,column],[nowait]]

of用来指定要锁定的列,如果忽略of那么表中选择的数据行都将锁定。如果被锁定行已经被锁定了,那么必须等待释放才能锁定对于这种情况我们可以使用nowait语句。

当使用for update语句声明游标后,可以再delete|update语句中使用where current of子句,修改|删除游标结果集中当前行对应的表中的数据。

语法:

where { current of cursor_name|search_condition}

举例说明:

//修改操作  
SQL> declare
     cursor ecname is select * from emp where empno=7934  
     for update of sal nowait;
     esal number(7,2);
     begin  
       dbms_output.put_line('开始');
       for r in ecname loop  
        esal:=r.sal*10;  
        update emp set sal=esal where current of ecname;  
       end loop;
       dbms_output.put_line('结束');  
     end;  
     /  

开始
结束


参考文献:redarmy_chen,http://redarmychen.iteye.com/blog/1023158

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值