zoukankan      html  css  js  c++  java
  • Oracle游标详解

    1、游标的概念

    游标(CURSOR):游标是把从数据表中提取出来的数据,以临时表的形式存放在内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以移动该指针,从而对游标中的数据进行各种操作。

    2、游标的作用

    游标是用来处理使用SELECT语句从数据库中检索到的多行记录的工具。借助于游标的功能,数据库应用程序可以对一组记录逐条进行处理,每次处理一行。

    3、游标的类型

    • 显式游标(Explicit Cursor):显式游标需要定义声明,在使用前要打开和获取,使用完毕后要关闭。多用于返回多行的SELECT语句
    • 隐式游标(Implicit Cursor):在执行一个SQL语句时,服务器将自动创建一个隐式游标,该游标是内存中的工作区,存储了执行SQL语句的结果,可通过游标的属性获得SQL的执行结果及状态信息。多用于只返回一行的SQL语句

    4、隐式游标

    (ORACLE在创建隐式游标时,默认的游标名为SQL)

      1)游标的主要属性(显示游标、隐式游标)

    • %FOUND 布尔型属性,当SQL语句至少影响一行时为TRUE,否则为FALSE
    • %NOTFOUND 布尔型属性,当SQL语句没有影响的行时为TRUE,否则为FALSE
    • %ISOPEN 布尔型属性,当游标已打开时返回TRUE,否则为FALSE(对用户而言,隐式游标永远是false)
    • %ROWCOUNT 数 字型属性,返回受到SQL影响的行数

    注意:
    属性名与游标名之间没有空格。
    游标的属性只能在PL/SQL块中使用,而不能在SQL语句中使用
    例1 将PRODUCTS表中类型为1的所有产品的单价打9折,并显示该更新所影响的行数.

    BEGIN
       UPDATE products
       SET  unitprice=unitprice*0.9
       WHERE categoryid=1;
       IF SQL%FOUND THEN
          dbms_output.put_line(‘更新了’||SQL%ROWCOUNT||’条记录’);
      ELSE
          dbms_output.put_line(‘没有更新记录’);
      END IF;
    END;

    5、显式游标

     1)定义游标     

         在使用显示游标之前,必须先在声明部分定义游标,其定义语法如下:
            CURSOR cursor_name[(parameter,…)]
             IS select_statement;
      说明: 参数parameter形式如下:para_name [IN] data_type [:=|DEFAULT value]

    (2)打开游标       

      当打开游标时,ORACLE会执行游标所对应的SELECT语句,并将结果存放到结果集,其定义语法如下:
      OPEN cursor_name[(parameter,…)];

    (3)提取数据语法如下:  

       FETCH  cursor_name INTO variable[,…];
    说明:

    • 对游标第一次执行FETCH语句时,它将工作区中的第一条记录赋给赋给变量,并使工作区内的指针指向下一条记录。
    • 工作区中的游标指针只能向下移动,不能回退。
    • 在使用FETCH语句之前,必须先打开游标,才能保证工作区内有数据。
    • INTO子句中的变量,顺序、类型必须与工作区中每行记录的字段数、顺序以及数据类型一一对应

    (4)关闭游标       

      关闭游标可释放其结果集,语法如下:
          CLOSE  cursor_name;
       说明:关闭游标,就是使游标所对应的内存工作区变为无效,并释放与游标相关的系统资源

    显式游标——无参游标

    例2:用显式游标显示输出products表中供应商编号为6 的产品的信息。

    DECLARE
       CURSOR  prod_cursor  IS
         select *from products where
         supplierid=6;
      prod_record products%rowtype;
    BEGIN
      OPEN prod_cursor;
      LOOP
       FETCH prod_cursor INTO prod_record;
    EXIT WHEN
        prod_cursor%NOTFOUND;
    dbms_output.put_line(‘产品编号’||prod_record.productid);
    dbms_output.put_line(‘产品名称’||prod_record.productname);
    dbms_output.put_line(‘供应商编号’||prod_record.supplierid);
    END LOOP;
    CLOSE prod_cursor;
    END;

    显式游标——参数游标

    例3:用显式参数游标显示输出products表中供应商编号为XX 的产品的信息。

    DECLARE
       CURSOR  prod_cursor (suppID in number DEFAULT 1)  IS
         select * from products where
         supplierid=suppId;
      prod_record products%rowtype;
    BEGIN
      OPEN prod_cursor(2);
      LOOP
       FETCH prod_cursor INTO prod_record;
    EXIT WHEN
        prod_cursor%notfound;
    dbms_output.put_line(‘产品编号’||prod_record.productid);
    dbms_output.put_line(‘产品名称’||prod_record.productname);
    dbms_output.put_line(‘供应商编号’||prod_record.supplierid);
    END LOOP;
    CLOSE prod_cursor;
    END;

    注意:在为参数游标定义参数的数据类型时,不能使用长度约束

    显式游标——游标FOR循环

    语法格式:
    FOR 循环变量 IN 游标类型名
        LOOP
             循环语句
        END LOOP;
    注意:

    • 循环变量不需要定义,系统隐含地定义其数据类型为%ROWTYPE的变量
    • 使用游标FOR循环时,不能使用OPEN、FETCH、CLOSE语句。

    例4:用显式参数游标显示输出products表中供应商编号为XX 的产品的信息。

    DECLARE
       CURSOR  prod_cursor (suppID in number DEFAULT 1)  IS
         select *from products where    supplierid=suppId;
    BEGIN
    FOR v_pr IN prod_cursor(3) LOOP
    dbms_output.put_line(‘产品编号’||v_pr.productid);
    dbms_output.put_line(‘产品名称’||v_pr.productname);
    dbms_output.put_line(‘供应商编号’||v_pr.supplierid);
    END LOOP;
    END;

    5.显示游标与隐式游标比较

     6.游标变量

    游标包括显示游标和隐式游标,在定义时与特定的查询绑定,即在声明中定义查询,其结构是不变的,因此又称静态变量。

    游标变量是一个指向多行查询结果集的指针,不与特定的查询绑定,可以在打开游标变量时定义查询,可以返回不同结构的结果集。

    PL/SQL 中,使用游标变量包括定定义游标引用类型(REF CURSOR),声明游标变量,打开游标变量、检索游标变量、关闭游标变量等几个基本步骤。     

    游标变量基本步骤:

    (1) 定义游标CURSOR类型的指针
     TYPE type_name IS REF CURSOR [RETURN return_type];
    type_name 是新引用类型的名字
    而return_type表示该游标变量返回的记录类型。
    (2) 声明REF CURSOR类型的变量
        游标变量   type_name;

    (3) 打开游标变量的语法格式如下所示:
       OPEN  游标变量名  FOR SELECT 语句;

    (4) 检索游标变量

     检索游标变量的方法与检索静态游标相似,使用 FETCH.... INTO 语句循环检索游标变量的
    结果集中的记录。语法为:

    LOOP
    FETCH cursor _ variable INTO variablel,variable2........;
    EXIT WHEN Cursor_ variables%NOTFOUND;
    ........
    END LOOP;

    检索游标变量时只能使用简单循环或 WHILE 循环,不能采用 FOR 循环.

    (5)关闭游标变量

    检索并处理完游标变量所对应的结果集后,可以关闭游标变量,释放存储空间。语法为;

    close 游标变量名;

    游标变量的不同定义方式举例

    DECLARE
      1-- 用 %ROWTYPE类型定义游标变量的返回值.
           TYPE t_productsRef IS REF CURSOR
            RETURN products%ROWTYPE;
      2-- 定义一个新的记录类型
           TYPE t_prodRecord IS RECORD (
             prodid  products.productid%TYPE,
             prodname   products.productname%TYPE);
            --定义游标变量的返回值为记录类型变量
           TYPE t_prodRef IS REF CURSOR
             RETURN  t_prodRecord;

    例5:使用游标变量查询出产品表中类别为1的产品的信息,并输出产品名称、类别编号、单价。

    DECLARE
          TYPE prod_record IS RECORD
          ( pname products.productname%type,
            cid products.categoryid%type,
            uprice products.unitprice%type);
          TYPE prod_cursor IS REF CURSOR RETURN prod_reord;
          v_prodcur prod_cursor ;
          v_prodrec  prod_record;
    BEGIN
       OPEN v_prodcur FOR select productname,categoryid,unitprice from products where categoryid=1;
      LOOP
    FETCH v_prodcur INTO v_prodrec ;
     EXIT WHEN v_prodcur%notfound;
     dbms_output.put_line (‘产名’||v_prodrec.pname);
    dbms_output.put_line(‘产品类别’||v_prodrec.cid);
    dbms_output.put_line (‘单价’||v_prodrec.uprice);
      End  LOOP;
    Close v_prodcur;
    End; 

    使用同一游标变量打开多个查询
    例6:使用游标变量查询出产品表中类别为1的产品的信息,然后查询输出产品单价小于20的产品信息。

    DECLARE
    TYPE prod_cursor IS REF CURSOR;
          v_cur prod_cursor;
          v_rec products%rowtype;
    BEGIN
       OPEN v_cur FOR select *  from products where categoryid=1;
      LOOP
         FETCH v_cur INTO v_rec;
         EXIT WHEN v_cur%notfound;
         dbms_output.put_line('产品名' || v_rec.productname);
         dbms_output.put_line('产品类别' || v_rec.categoryid);
         dbms_output.put_line('单价' || v_rec.unitprice);
      End  LOOP;
    OPEN v_cur FOR select *  from products where unitprice<20;
      LOOP
         FETCH v_cur INTO v_rec;
     EXIT WHEN v_cur%notfound;
        dbms_output.put_line('产品名' || v_rec.productname);
        dbms_output.put_line('产品类别' || v_rec.categoryid);
         dbms_output.put_line('单价' || v_rec.unitprice);
      End  LOOP;
    Close v_cur;
    End;
  • 相关阅读:
    撒谎
    可怜的猪
    GIS学习笔记(五)
    国产木马冰河2.2
    矛盾
    GIS学习笔记(六)
    男人如衣服
    VS2005快捷键大全
    慧悟
    DOS命令
  • 原文地址:https://www.cnblogs.com/CX66/p/14056798.html
Copyright © 2011-2022 走看看