游标 Cursors--Conception

每一条被Oracle服务器执行的SQL语句都有一个独立的游标与之相关联:
隐式游标 Implicit cursors: 用于所有的DML和PL/SQL的SELECT语句。
显示游标 Explicit cursors: 被程序显示声明和命名。
所定义的SQL语句必须只包含select语句,并且不能用insert、update或delete关键字。
当select语句可能返回零或多于一行时,必须用显式游标。
当Select语句预计只返回一行时,隐式游标将做得更好。


SQL游标属性(隐式游标)

使用SQL游标属性,能够测试SQL语句的执行结果。
在PL/SQL中用“SQL”引用最近的隐式游标。在程序中不能用OPEN、FETCH和CLOSE语句控制隐式游标。显示游标在后续课程中讲解。

从表rooms中删除指定的room_id行,并打印删除的行数。
 
VARIABLE rows_deleted VARCHAR2(100)
DECLARE
  v_empno  NUMBER := 7788;
BEGIN
  DELETE   FROM emp
  WHERE    empno = v_room_id;
  :rows_deleted := SQL%ROWCOUNT||' rows deleted.';
END;

PRINT rows_deleted


显示游标的功能
能够一行一行的处理多行查询结果。
 能够记录和跟踪当前正在处理的行。
 在PL/SQL块中允许程序手工控制游标。

(1)创建游标语法:

CURSOR cursor_name IS
     select_statement;

在游标声明中不能包含INTO子句。
如果处理的行要求特定的顺序,在查询语句中可以使用 ORDER BY子句。
examples;

DECLARE
  CURSOR c1 IS
    SELECT empno, ename
        FROM   emp;
  CURSOR c2 IS
    SELECT *
    FROM   dept
    WHERE  deptno = 10;
BEGIN
  ...
(2)打开游标

OPEN        cursor_name;

打开游标
执行查询。
活动集(查询结果的行的集合)被确定。
活动集的指针指向第一行。
如果查询没有返回行,不会抛出异常。
提取一行后,应该使用游标属性测试结果。
(3)从游标中提取数据

FETCH cursor_name INTO    [variable1, variable2, ...]
                                    | record_name];

提取当前行的值存储到PL/SQL变量中。
变量的类型必须与查询的选择列表的类型相兼容。
变量的数量必须与查询的选择列表的数量相同。
测试游标是否包含行。如果没有提取出值,则说明在处理的活动集中没有剩下需要处理的行并且不会有错误记录。

例子
DECLARE(声明数据变量)
  v_ename  emp.ename%TYPE;
  v_sal    emp.sal%TYPE;
  v_empRecord  emp%ROWTYPE;
  CURSOR cur_AllEmp IS(创建游标)
    SELECT *  FROM emp;  
BEGIN
  OPEN cur_AllEmp;打开游标
  FETCH cur_AllEmp INTO v_empRecord;(从游标中提取数据)
  FETCH cur_AllEmp INTO v_ename, v_sal;(error)
END;

例子 从scott.emp表中查询所有记录,利用游标获取前两行记录并输出ename、job、sal中的值
DECLARE
CURSOR c1 IS SELECT * FROM emp; 创建游标)
emp_rec emp%ROWTYPE;  --定义一个和表结构完全一致的记录变量
BEGIN
   OPEN c1;
   FETCH c1 INTO emp_rec;
   dbms_output.put_line('姓名是:'||emp_rec.ename|| '工作是:'||emp_rec.job|| '工资是:'||emp_rec.sal);
   FETCH c1 INTO emp_rec;
   dbms_output.put_line('姓名是:'||emp_rec.ename||'工作是:'||emp_rec.job|| '工资是:'||emp_rec.sal);
   CLOSE c1;
END;

关闭游标 CLOSE        cursor_name;

当所有的活动集都被检索以后,游标就应该关闭。
如果需要,可以在重新打开游标。
一旦关闭了游标,再从该游标提取数据就将是非法的。这样做会产生一个Oracle错误。


游标提取控制

使用LOOP循环实现显示游标多行数据处理。
反复使用Fetch来提取每一行数据。
使用%NOTFOUND属性来判断提取(Fetch)行是否不成功。
使用%FOUND显示游标属性来判断每一次提取(Fetch)操作是否成功。
%ISOPEN属性

只有当游标打开是才能进行提取(Fetch)行的操作。
在进行提取(Fetch)行操作之前,使用%ISOPEN属性测试游标是否打开。
Example
IF NOT c1%ISOPEN THEN
    OPEN c1;
END IF;
LOOP
  FETCH c1...

使用%ROWCOUNT游标属性,返回到目前位置由游标返回的行的数目。
使用%NOTFOUND游标属性,作为LOOP循环的退出条件。
例子  使用游标实现逐行输出scott.emp表中部门编号为10的员工姓名和工资。
DECLARE
   CURSOR emp_cursor IS 创建游标
    SELECT ename,sal FROM emp WHERE deptno=10;
   emp_record emp%ROWTYPE;  
BEGIN
   OPEN emp_cursor ;打开游标
   LOOP 建立loop循环
      FETCH emp_cursor INTO emp_record.ename,emp_record.sal; 、、提取数据
      EXIT WHEN emp_cursor%NOTFOUND;  //退出循环
      dbms_output.put_line('ename: '||emp_record.ename||'  sal:'||emp_record.sal);
   END LOOP;//
   dbms_output.put_line('row count:'||emp_cursor%rowcount);
   CLOSE emp_cursor;//关闭游标
END;


游标的FOR循环

FOR record_name IN cursor_name LOOP   
  statement1;
  statement2;
  . . .
END LOOP;
游标的FOR循环能够便捷的处理显示游标。
FOR循环中的循环控制变量不需要事先定义。
在游标的FOR循环之前,系统能够自动打开游标;在FOR循环结束后,系统能够自动关闭游标,不需要人为操作。
在游标的FOR循环过程中,系统能够自动执行FETCH语句;每一次循环,系统就自动执行一次FETCH语句,将游标指向的当前行记录存入循环控制变量中
例子使用FOR循环实现逐行输出emp表中部门编号为10的员工姓名和工资。

DECLARE
   CURSOR emp_cursor IS
    SELECT ename,sal FROM scott.emp WHERE deptno=10;
BEGIN
   FOR emp_record IN emp_cursor LOOP
      dbms_output.put_line('ename: '||emp_record.ename||'  sal:'||emp_record.sal);
   END LOOP;
/* 该命令无效,因为FOR循环结束后游标自动关闭
dbms_output.put_line('row count:'||emp_cursor%rowcount); */
END;
游标提取循环

例子使 用游标查询emp表中的所有记录,并在程序块中输出工资最高的前五行记录。
DECLARE
   CURSOR cur IS SELECT * FROM scott.emp ORDER BY sal DESC;
BEGIN
   FOR rec IN cur  LOOP
      IF cur%ROWCOUNT<=5 THEN [cur%ROWCOUNT 从1 开始]
                dbms_output.put_line('ename:'||rec.ename||’sal:'||rec.sal);
      ELSE
        EXIT;
      END IF;
   END LOOP;
END;


使用子查询的游标FOR循环(不需要定义游标)

BEGIN
  FOR emp_record IN ( SELECT empno, ename
                          FROM   emp) LOOP  (就是用DML语句 代替了游标而已,其他到没有啥子)
         -- implicit open and implicit fetch occur
    IF emp_record.empno = 7839 THEN
      ...
  END LOOP; -- implicit close occurs
END;


带参数的游标

CURSOR cursor_name(parameter_name datatype) IS select_statment;
使用open命令打开带参数的游标时,需要给游标传递实参值。
   实例 定义参数游标,查询指定部门的员工姓名
DECLARE
--定义游标参数no,参数类型为number类型
CURSOR emp_cursor( no NUMBER) IS
        SELECT ename FROM emp WHERE deptno=no;
emp_rec emp_cursor%ROWTYPE;
BEGIN
  --打开参数游标时,指明一个替代变量作为游标参数的值
  OPEN emp_cursor(&no);   
  LOOP
    FETCH emp_cursor INTO emp_rec;
    EXIT WHEN emp_cursor%NOTFOUND;     
    dbms_output.put_line('ename:'||emp_rec.ename);
  END LOOP;
  CLOSE emp_cursor;
END;

oracle PL/SQL(procedure language/SQL)程序设计之游标cursors的更多相关文章

  1. oracle PL/SQL(procedure language/SQL)程序设计

    PL/SQL(procedure language/SQL)语言是Oracle对SQL语言的过程化扩充,是一个完整的编程语言.PL/SQL实现了过程化语句(如分支.循环等)与SQL语句的无缝连接,将过 ...

  2. Oracle笔记--PL/SQL(Procedure Language & Structured Query Language)

    1.PL/SQL是一种高级数据库程序设计语言,专门用于在各种环境下对Oracle数据库进行访问.该语言集成于数据库服务器中,所以PL/SQL代码可以对数据进行快速高效的处理. 2.PL/SQL是对SQ ...

  3. oracle PL/SQL(procedure language/SQL)程序设计之异常(exception)

    什么是异常?在PL/SQL中的一个标识.在程序运行期间被触发的错误.异常是怎样被触发的?产生一个Oracle错误.用户显示触发.怎样处理异常?用异常处理句柄捕获异常.传播异常到调用环境. 捕获异常 E ...

  4. oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包

    匿名PL/SQL块回顾 DECLARE (可选)    定义在PL/SQL块中要使用的对象BEGIN (必须)    执行语句EXCEPTION (可选)    错误处理语句END; (必须)匿名块( ...

  5. oracle PL/SQL(procedure language/SQL)程序设计之函数+过程+包(转)

    匿名PL/SQL块回顾 DECLARE (可选)     定义在PL/SQL块中要使用的对象 BEGIN (必须)     执行语句 EXCEPTION (可选)     错误处理语句 END; (必 ...

  6. oracle PL/SQL(procedure language/SQL)程序设计之触发器(trigger)

    创建触发器 触发器类似于过程和函数,都拥有声明.执行和异常处理过程的带名PL/SQL块.与包类似,触发器必须存储在数据库中.前面已经讲过,过程是显式地通过过程调用执行的,同时过程调用可以传递参数.与之 ...

  7. oracle PL/SQL(procedure language/SQL)程序设计(在PL/SQL中使用SQL)

    在PL/SQL程序中,允许使用的SQL语句只有DML和事务控制语句,使用DDL语句是非法的.使用SELECT语句从数据库中选取数据时,只能返回一行数据.使用COMMIT,  ROLLBACK, 和SA ...

  8. oracle PL/SQL(procedure language/SQL)程序设计--控制结构(if else )

    IF逻辑结构:IF-THEN-END IFIF-THEN-ELSE-END IFIF-THEN-ELSIF-END IF 语法 IF condition THEN  statements;[ELSIF ...

  9. oracle PL/SQL(procedure language/SQL)程序设计(续集)之PL/SQL函数

    PL/SQL函数 examples:“ 构造一个邮件地址 v_mailing_address := v_name||CHR(10)||                                 ...

随机推荐

  1. 浅析 JavaScript 中的闭包(Closures)

    a { text-decoration: none; color: #4094c7 } h4,h5 { margin: 0; font-weight: 700; color: inherit; lin ...

  2. Objective-C 学习记录4

    字符串的一些方法使用: 1.创建字典的NSString可变字符串,和NSMutableString不可变字符串.都是objective的对象. char *str是字母数组. 2.字符串格式化:str ...

  3. DIV 布局 左中右

    <style type="text/css">body{ margin:0; padding:0;}.Header{ height:100px; background: ...

  4. Unity3d:使用uWebKit插件嵌入网页,网页中的flv视频无法播放

    问题描述:unity3d程序,使用uWebKit插件嵌入网页,用来播放FLV视频,有的电脑可以正常播放,有的电脑在网页中播放不了ps:网页中的播放器用的是player.swf解决方案:是由于网页中的播 ...

  5. 有关ListBox

    如何拿到Source:从SQL,从XML file SQL:一个是ObjectDataProvider //用linq方法拿到SQL data,wrap到一个IEnumerable<Custom ...

  6. SQLServer获取随机数据

    1.比较常见和好用的一种 SELECT TOP 10 *, NEWID() AS randomFROM tableORDER BY random --newid函数会随机生成一个guid,很长的一个字 ...

  7. PING的原理以及ICMP协议

    主要内容: 1.ping的原理以及工作过程 2.ICMP协议 3.ICMP的应用:ping,traceroute 1.ping的原理以及工作过程  ping的原理  ping 程序是用来探测主机到主机 ...

  8. JS函数的定义与调用方法

    JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式 1.方法调用模式:先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来 ...

  9. Sqlite表的结构修改

    Sqlite删除列方法 http://blog.csdn.net/aben_2005/article/details/6563538 SQLite3 table 结构修改 http://blog.cs ...

  10. DataInputStream和DataOutputStream使用方法细节探讨

    DataInputStream和DataOutputStream都是Java中输入输出流的装饰类,用起来非常方便.今天就来讨论一下使用该类时候遇到的编码问题.  package com.vince ...