Oracle基础 游标

原文:Oracle基础 游标

一、游标  

  游标用来处理从数据库中检索的多行记录(使用SELECT语句)。利用游标,程序可以逐个地处理和遍历一次检索返回的整个记录集。

     为了处理SQL语句,Oracle将在内存中分配一个区域,这就是上下文区。这个区包含了已经处理完的行数、指向被分析语句的指针,整个区是查询语句返回的数据行集。游标就是指向上下文区句柄或指针。

 

二、游标的分类:

  1、静态游标:静态游标是在编译时知道其SELECT语句的游标。静态游标又分为两种类型,隐式游标和显示游标。

  2、动态游标:用户为游标使用的查询直到运行的时候才能确定,可以使用REF游标和游标变量满足这个要求。为了使用引用游标,必须声明游标变量。有两种类型的REF游标:强类型REF游标和弱类型REF游标。

 

 

三、显示游标的用法:

  显示游标被用于处理返回多行数据的SELECT 语句,游标名通过CURSOR….IS 语句显示地赋给SELECT 语句。

       (一)使用步骤;

       1)声明游标:CURSOR cursor_name IS select_statement

        2)为查询打开游标:OPEN cursor_name

        3)取得结果放入PL/SQL变量中;

                 FETCH cursor_name INTO list_of_variables;

               FETCH cursor_name INTO PL/SQL_record;

        4)关闭游标。CLOSE cursor_name

  注意:在声明游标时,select_statement不能包含INTO子句。当使用显示游标时,INTO子句是FETCH语句的一部分。

  例:显示雇员的名称和薪水

--使用LOOP遍历游标
DECLARE
  v_name emp.ename%TYPE;
  v_sal emp.sal%TYPE;
  CURSOR cus_emp IS
    SELECT ename,sal FROM emp;                         --声明游标
BEGIN
   OPEN cus_emp;                                       --打开游标
   LOOP
      FETCH cus_emp INTO v_name,v_sal;                 --提取游标
      EXIT WHEN cus_emp%NOTFOUND;
      dbms_output.put_line('第'||cus_emp%ROWCOUNT||'个用户:  name:'||v_name||'     sal:'||v_sal);
   END LOOP;
   CLOSE cus_emp;                                      --关闭游标
END;

  显示游标的属性:

  %FOUND:只有在DML语句影响一行或者多行是,则返回TRUE;

  %NOTFOUND:没有影响任何行,则返回TRUE。

  %ROWCOUNT:返回DML语句影响的行数,没有影响则返回0;

  %ISOPEN:返回游标是否打开,在执行SQL之后,Oracle自动关闭SQL游标,所以隐式游标的%isopen属性始终未false;

 

  另一种方式:

--使用for来简化游标遍历
DECLARE
  CURSOR cus_emp IS
    SELECT ename,sal FROM emp;
BEGIN
   FOR record_emp IN cus_emp
   LOOP
      dbms_output.put_line('第'||cus_emp%ROWCOUNT||'个用户:  name:'||record_emp.ename||'     sal:'||record_emp.sal);
   END LOOP;
END;

  record_emp是plsql声明的的记录变量,此变量的属性为声明为%ROWTYPE类型,作用域在FOR循环之内,即在FOR循环外就不能访问了。

  循环游标的特性:
  (1)从游标中提取了所有记录之后自动终止。
  (2)提取和处理游标中的每一条记录。
  (3)如果在提取记录之后%NOTFOUND属性返回TRUE,则终止循环。如果未返回任何行,则不进入循环。

 

游标案例:  

--给员工加薪,按员工入职时间进行加薪,每年加100,1000封顶
DECLARE
  v_date emp.hiredate%TYPE;
  v_empno emp.empno%TYPE;
  v_money NUMBER;
  CURSOR cur_emp IS
    SELECT empno,hiredate FROM emp;
BEGIN
  OPEN  cur_emp;
  LOOP
     FETCH cur_emp INTO v_empno,v_date;
     EXIT WHEN cur_emp%NOTFOUND;
     v_money := 100*(1990-to_char(v_date,'yyyy'));
     IF v_money<1000 THEN
        UPDATE emp SET sal=sal+v_money WHERE empno=v_empno;
     ELSE
        UPDATE emp SET sal=sal+1000 WHERE empno=v_empno;
     END IF;
  END LOOP;
END;

 

四、隐式游标:

  所有的隐式游标都被假设为只返回一条记录。
  使用隐式游标时,用户无需进行声明、打开及关闭。PL/SQL隐含地打开、处理,然后关掉游标。多条sql语句 隐式游标SQL永远指的是最后一条sql语句的结果,主要使用在update 和 delete语句上。

  隐式游标的四个属性:

 

属性 说明
 SQL%rowcount  影响的记录的行数整数(用来判断插入,更新修改是否成功,必须在comit之前,否则提交后结果为0.)
 SQL%found  影响到了记录 true()
 SQL%notfound  没有影响到记录 true
 SQL%isopen  是否打开 布尔值 永远是false

例如:

DECLARE
  row_emp emp%ROWTYPE;
BEGIN
  SELECT ename,sal INTO row_emp.ename,row_emp.sal
  FROM emp WHERE emp.empno = 7369;
  --判断是否查到数据
  if(SQL%ROWCOUNT=1) THEN
    dbms_output.put_line('找到了');
  END IF;
  --另一种方式判断
  IF(SQL%Found) THEN
    dbms_output.put_line('找到了');
  END IF;

  dbms_output.put_line('ename:'||row_emp.ename||'    sal:'||row_emp.sal);
END;

 

上述游标自动打开,并把相关值赋给对应变量,然后关闭。执行完后,PL/SQL变量rowemp.ename,rowemp.sal中已经有了值。

五:动态游标

  静态游标是在声明就已经确定查询语句,如果用户需要在运行时动态决定游标执行的查询,就需要使用动态游标(REF游标)。

  动态游标分为两类:强类型游标和弱类型游标。

  动态游标使用步骤:

  1、声明动态游标类型;

  2、打开游标,指定游标查询;

  3、提取游标。

  4、关闭游标。

  例:

  强类型游标,使用return声明的游标为强类型游标。在对游标进行绑定查询只能绑定游标返回的类型rowtype。

--强类型的动态游标,查询emp表中的数据
DECLARE
  TYPE ref_cur IS REF CURSOR    --声明游标类型
  RETURN emp%ROWTYPE;       --带返回值的为强类型动态游标
  refcur_emp ref_cur;         --游标类型对象
  v_emp emp%ROWTYPE;
BEGIN
  OPEN refcur_emp FOR        --将游标绑定到一个查询语句,因为声明的是强类型,所以只能绑定emp;
    SELECT * FROM emp;
  LOOP
    FETCH refcur_emp INTO v_emp;     --提取游标内容
    EXIT WHEN refcur_emp%NOTFOUND;
    dbms_output.put_line(refcur_emp%Rowcount||'、name:'||v_emp.ename||'    sal:'||v_emp.sal);
  END LOOP;
  CLOSE refcur_emp;
END;

  

  弱类型游标:可以用来绑定多个查询结果。

  例:

--弱类型游标
DECLARE
  TYPE refcur IS REF CURSOR;   --未定义返回类型为弱类型游标
  rc refcur;
  v_name emp.ename%TYPE;
  v_deptname dept.dname%TYPE;
BEGIN
  OPEN rc FOR SELECT ename,dname FROM emp e,dept d WHERE e.deptno = d.deptno;  --绑定查询
  LOOP
    FETCH rc INTO v_name,v_deptname;
    EXIT WHEN rc%NOTFOUND;
    dbms_output.put_line('name:'||v_name||'               deptname:'||v_deptname);
  END LOOP;
  CLOSE rc;
END;

 

  例:

--根据输入的内容绑定游标
DECLARE
  TYPE refcur IS REF CURSOR;
  rc refcur;
  v_tablename VARCHAR2(10) := '&tab';
  v_id NUMBER;
  v_name VARCHAR2(20);
BEGIN
  IF(v_tablename = 'e') THEN
    OPEN rc FOR
      SELECT e.empno,e.ename INTO v_id,v_name FROM emp e;
      dbms_output.put_line('=========员工信息=============');
  Elsif(v_tablename = 'd') THEN
    OPEN rc FOR
      SELECT d.deptno,d.dname INTO v_id,v_name FROM dept d;
      dbms_output.put_line('=========部门信息=============');
  ELSE
      dbms_output.put_line('输入错误,请输入e或者d!');
      RETURN;
  END IF;  

  LOOP
    FETCH rc INTO v_id,v_name;
    dbms_output.put_line('#'||rc%Rowcount||'   id:'||v_id||'   name:'||v_name);
    EXIT WHEN rc%NOTFOUND;
  END LOOP;
END;

 

时间: 2024-08-02 00:20:15

Oracle基础 游标的相关文章

Oracle基础 动态SQL语句

原文:Oracle基础 动态SQL语句 一.静态SQL和动态SQL的概念. 1.静态SQL 静态SQL是我们常用的使用SQL语句的方式,就是编写PL/SQL时,SQL语句已经编写好了.因为静态SQL是在编写程序时就确定了,我们只能使用SQL中的DML和事务控制语句,但是DDL语句,以及会话控制语句却不能再PL/SQL中直接使用,如动态创建表或者某个不确定的操作时,这就需要动态SQL来实现. 2.动态SQL 动态SQL是指在PL/SQL编译时SQL语句是不确定的,如根据用户输入的参数的不同来执行不

Oracle 基础和管理

oracle http://www.cnoug.orghttp://www.itpub.netwww.oradb.nethttp://www.oracle.com.cn/ SQLMicrosoft SQL Server中文主页 http://www.microsoft.com/china/sql/default.mspx   数据库网络学院 http://www.pconline.com.cn/pcedu/empolder/db/index.html 教您从无到有学会SQL语句.MYSQL.SQ

oracle中游标(Cursor)的详解

概述 也许大家对数据库中游标都不陌生,但对于其概念可能有时又会有些模糊,游标到底是什么? 为了使大家对游标有个清晰的认识,本文将介绍Oracle中游标(curosr)相关的知识. 游标的概念 一般来讲,游标包含着两种不同的概念: 程序中的游标(Program Cursor)和Oracle中的游标(Oracle Curosr). 程序中的游标(Program Cursor): 在最终用户程序(Client Application)中,游标(curosr)通常指和SQL语句关联的一个数据结构,用于关

oracle的游标和过程区别

问题描述 oracle的游标和过程区别 我想要查询emp表中的所有的数据 用游标的方式会写 但是能不能用过程实现这个查询呢?还有过程是和函数一样 只能返回一个参数吗?不能返回行数据吗? 解决方案 存储过程当然可以返回行数据.http://www.cnblogs.com/attraction/archive/2008/01/23/13489.html

oracle带游标的存储过程列子

问题描述 oracle带游标的存储过程列子 oracle带游标的存储过程列子简单点, 能用就行.主要是实现将一个表中的一个字段当条件使用 解决方案 begin for c in (select * from dual) loop update dual set a=c.a where a=c.a; end loop; end ; 解决方案二: Oracle存储过程,带游标oracle带游标的存储过程oracle 存储过程 游标 解决方案三: for c in (select * from tab

oracle基础问题,求大神用白话文帮小弟解释下,扩展表空间

问题描述 oracle基础问题,求大神用白话文帮小弟解释下,扩展表空间 今天同事创建表的时候,系统提示ORA-01658错误,知道是表空间不足,就想起增加表空间 可是增加表空间我经常用到的就是alter database和alter tablespace,一个是增加表空间大小,一个是增加数据库文件 这两种方式有什么区别么? 解决方案 alter database 是修改数据库吧,alter tablespace 是修改表空间

Oracle基础 数据库备份和恢复

原文:Oracle基础 数据库备份和恢复 一.为什么需要数据备份 造成数据丢失的主要原因: 1.介质故障. 2.用户的错误操作. 3.服务器的彻底崩溃. 4.计算机病毒. 5.不可预料的因素.   Oracle中故障类型分为以下4种. 1.语句故障: 执行SQL语句过程发生的逻辑故障可导致语句故障.如果用户编写的SQL语句无效,就会发生语句故障.Oracle可自我修复语句故障,撤销语句产生的而印象,并将控制权交给应用程序. 2.用户进程故障 当用户程序出错而无法访问Oracle数据库时,就会发生

Oracle存储过程游标用法分析_oracle

本文实例讲述了Oracle存储过程游标用法.分享给大家供大家参考,具体如下: 使用游标的5个步骤 1.声明一些变量用于保存select语句返回的指 2.声明游标,并指定select 语句 3.打开游标 4.从游标中获取记录 5.关闭游标 从游标中获取每一条记录可使用fetch语句.fetch语句将列的指读取到指定的变量中: 语法: fetch cursor_name into variable[, variable ...]; 例子: create or replace procedure se

Oracle显示游标的使用及游标for循环_oracle

下面给大家介绍在什么情况下用隐式游标,什么情况下用显示游标: 1.查询返回单行记录时→隐式游标: 2.查询返回多行记录并逐行进行处理时→显式游标 --显示游标属性 declare CURSOR cur_emp IS SELECT * FROM emp; row_emp cur_emp%ROWTYPE; BEGIN OPEN cur_emp; FETCH cur_emp INTO row_emp; WHILE cur_emp%FOUND LOOP dbms_output.put_line(row_