游标 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. java使用jdbc对sqlite 添加、删除、修改的操作

    package com.jb.jubmis.Dao.DaoImpl; import java.io.File;import java.io.FileInputStream;import java.io ...

  2. 转载:linux vi命令详解

    转自:http://www.cnblogs.com/mahang/archive/2011/09/01/2161672.html 刚开始学着用linux,对vi命令不是很熟,在网上转接了一篇. vi编 ...

  3. Junit 测试断言说明

    Assert.assertEquals("发生错误时报告消息","预期值","生产值"); Assert.assertEquals(&quo ...

  4. TAxThread - Inter thread message based communication - Delphi

    http://www.cybletter.com/index.php?id=3 http://www.cybletter.com/index.php?id=30 Source Code http:// ...

  5. PPAS上运行pg_dump经过

    目前我有两台机器, 分别已经安装了PPAS9.1,安装后建立了OS系统用户enterprisedb和数据库用户enterprisedb. 机器1:master  192.168.10.88 机器2: ...

  6. Docker:使用Ambassador进行跨主机间容器通信

    转载请注明出处:点我 由于Docker自身的网络的原因,想要在多主机间的容器之间进行通信是比较麻烦的事情.可以利用Ambassador容器来实现这一功能. 基本原理: 利用Ambassador来实现主 ...

  7. CircleWaveProgressBar

    https://github.com/eltld/CircleWaveProgressBar

  8. 分布式存储系统sheepdog

    Sheepdog,是由NTT的3名日本研究员开发的开源项目,主要用来为虚拟机提供块设备. 其架构例如以下: 以下,我们将从架构.模块等几个方面来介绍下: 一.架构图 如上图: 採用无中心节点的全对称架 ...

  9. centos 服务器配置(三) 之定时任务

    有些liunx系统已经自带定时任务crontab,但是有的新装系统还未安装定时任务,这个时候就需要我们手动对其进行安装. 安装crontab: yum install crontabs 说明: /sb ...

  10. 项目源码--Android即时通讯IM客户端

    下载源码   技术要点: 1.完整精美客户端UI设计 2.自定义控件的灵活使用 3.UI控件的详细使用 4.即时通讯IM协议的实现 5.完整即时通讯IM客户端实现 6.源码详细的中文注释 …….   ...