首页 > 技术文章 > Oracle 基础 游标

futao123 2015-04-24 17:47 原文

一:游标的基本原理

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

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

二:游标的分类

  1.静态游标:在编译时知道其SELECT语句的游标。

    (1).显示游标

    (2).隐式游标

  2.动态游标:用户为游标使用的查询直到运行的时候才能确定,必须声明游标变量。

    (1):强类型REF游标

    (2):弱类型REF游标。

 

三:显示游标的用法

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

  (一):使用步骤

    1)声明游标:

      CURSOR cursor_name(游标名) IS select 语句;

    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;
复制代码

 

    显示游标的属性

    %isopen:游标是否打开

    %found:游标是否指向有效行

    %notfounp:游标是否没有指向有效行

    %rowcount:游标抽取的行数

   语法:游标名  属性名

    

      方法二:使用游标简化游标的读取

      For 自定义类型 in 游标名 loop;

        --操作各行的数据

      end loop;

 

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;

 

 

 

 

 

 

 

四、隐式游标:

  所有的隐式游标都被假设为只返回一条记录。   

  使用隐式游标时,用户无需进行声明、打开及关闭。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;
复制代码

五:动态游标

推荐阅读