zoukankan      html  css  js  c++  java
  • PL/SQL学习(三)游标

    两种类型:
        隐式:
            执行INSERT、UPDATE、DELETE 或者只返回一条结果的SELECT语句时默认创建。
        显式:
             执行返回多条结果的SELECT语句时才能创建显式游标,创建时游标可以存储多行记录,但是同一个时间点上只能对一条记录进行处理。

    隐式游标
    隐式游标属性:
    属性
       返回类型

    例子

    %FOUND

    至少一条记录受影响(或者返回)时返回TRUE

    SQL%FOUND

    没有记录受影响(或者返回)时返回FALSE

    %NOTFOUND

    没有记录受影响(或者返回)时返回TRUE

    SQL%NOTFOUND

    至少一条记录受影响(或者返回)时返回FALSE

    %ROWCOUNT 

    返回受影响的记录条数

    SQL%ROWCOUNT


    例子:

    DECLARE  var_rows number(5);
    BEGIN
      UPDATE employee 
      SET salary = salary + 1000;
      IF SQL%NOTFOUND THEN
        dbms_output.put_line('None of the salaries where updated');
      ELSIF SQL%FOUND THEN
        var_rows := SQL%ROWCOUNT;
        dbms_output.put_line('Salaries for ' || var_rows || 'employees are updated');
      END IF; 
    END; 

    显式游标
    创建格式:
    CURSOR cursor_name IS select_statement;
    使用:
    • 在声明部分声明显式游标.
    • 在执行部分打开游标.
    • 将从游标里获取到的数据放到PL/SQL变量或者记录里.
    • 关闭游标.

    1) 声明游标:

       DECLARE
       CURSOR cursor_name IS 
       返回多条记录的SELECT语句; 

    2) 打开游标:

        OPEN cursor_name;
    3) 取数据放到PL/SQL变量或者记录里:

    FETCH cursor_name INTO record_name;

        FETCH cursor_name INTO variable_list;  
    4) 关闭游标:
        CLOSE cursor_name;
    5)注意:  
        当取数据(数据库里一行记录)存到记录里面时,记录和游标的数据结构必须一致。
        当取数据(数据库里一行记录)存到多个变量里时,变量的顺序和游标列的顺序一致。
        游标打开后,第一行被指定为当前行,每当数据被取到变量或者记录里,游标指向下一行。

         试图打开一个在前面操作中没有关闭的游标,程序会报错。

             当游标移到最后一行记录的后面,再取数据时,程序会报错。

    例子:
    1> DECLARE 
    2>    emp_rec emp_tbl%rowtype;
    3>    CURSOR emp_cur IS 
    4>    SELECT *
    5>    FROM emp_tbl
    6>    WHERE salary > 10; 
    7> BEGIN 
    8>    OPEN emp_cur; 
    9>    FETCH emp_cur INTO emp_rec; 
    10>      dbms_output.put_line (emp_rec.first_name || '  ' || emp_rec.last_name); 
    11>   CLOSE emp_cur; 
    12> END; 

    显式游标属性:

    属性

    返回值

    例子

    %FOUND

    至少获取一条数据时返回TRUE

    Cursor_name%FOUND

    没有获取到数据时返回FALSE

    %NOTFOUND

    没有获取到数据时返回TRUE Cursor_name%NOTFOUND
    至少获取一条数据时返回FALSE

    %ROWCOUNT

    获取到的数据条数

    Cursor_name%ROWCOUNT

    没有取到数据时,报错

    %ISOPEN

    游标打开时返回TRUE

    Cursor_name%ISNAME

    游标关闭时返回FALSE

    使用简单循环:

    1> DECLARE 
    2>   CURSOR emp_cur IS 
    3>   SELECT first_name, last_name, salary FROM emp_tbl; 
    4>   emp_rec emp_cur%rowtype; 
    5> BEGIN 
    6>   IF NOT emp_cur%ISOPEN THEN 
    7>      OPEN emp_cur; 
    8>   END IF; 
    9>   LOOP 
    10>     FETCH emp_cur INTO emp_rec; 
    11>     EXIT WHEN emp_cur%NOTFOUND; 
    12>     dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name 
    13>     || ' ' ||emp_cur.salary); 
    14>  END LOOP;
    15>  END; 
    16>  / 

    使用While循环:

    9>   FETCH sales_cur INTO sales_rec;  
    10>  WHILE sales_cur%FOUND THEN  
    11>  LOOP 
    12>    dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name 
    13>    || ' ' ||emp_cur.salary); 
    15>    FETCH sales_cur INTO sales_rec; 
    16>  END LOOP; 

    使用FOR循环:

    1> DECLARE 
    2>  CURSOR emp_cur IS 
    3>  SELECT first_name, last_name, salary FROM emp_tbl; 
    4>  emp_rec emp_cur%rowtype; 
    5> BEGIN 
    6>  FOR emp_rec in sales_cur 
    7>  LOOP  
    8>  dbms_output.put_line(emp_cur.first_name || ' ' ||emp_cur.last_name 
    9>    || ' ' ||emp_cur.salary);  
    10> END LOOP; 
    11>END;
    12> /

     


    带参数游标

    格式:CURSOR cursor_name(parameter_name1 type1,parameter_name2 datetype type2..) IS select_statement;
    例子:
    1)定义
    CURSOR c_emp(no IN emp.empno%TYPE) --或者(no NUMBER)
    IS
    SELECT * FROM emp
    WHERE
    empno = no;

    2)使用
    OPEN c_emp('no1')
    FOR r_emp IN c_emp('no1') LOOP...

     


    使用FOR UPDATE 和 WHERE CURRENT的游标

    以下内容摘自《Oracle PL/SQL by Example》

    使用FOR UPDATE 和 WHERE CURRENT的游标:
    FOR UPDATE 能锁定希望更新的行,commit或者rollback 后才会释放锁
    没有commit或者rollback时可以在游标中使用WHERE CURRENT OF 检索最新的数据
     使用:
        在游标定义结尾处加上
        FOR UPDATE [OF item_name]
            
    例子:
     1)
            DECLARE
              CURSOR c_course IS
                SELECT course_no,cost
                FROM course FOR UPDATE [OF cost];
            BEGIN
               FOR r_course IN c_course
               LOOP
                 IF r_course.cost < 2500
                 THEN
                   UPDATE course
                   SET cost = r_course.cost + 10
                   WHERE course_no = r_course.course_no;
                 END IF;
                END LOOP;
              END;
              
    2) 使用WHERE CURRENT OF子句,可以不用在UPDATE语句中添加对应的WHERE条件
            DECLARE
              CURSOR c_course IS
                SELECT course_no,cost
                FROM course
                WHERE cost < 2500
                FOR UPDATE [OF cost];
            BEGIN
               FOR r_course IN c_course
               LOOP
                 UPDATE course
                   SET cost = r_course.cost + 10
                 WHERE CURRENT OF c_course;
                END LOOP;
              END;
    
    
    
    
    
    
    
    
  • 相关阅读:
    qt5--创建控件的两种方式
    qt5-编码转换
    C++qt助手assistant
    C++opencv绘制几何图形
    C++opencv创建图像
    【全球软件大会】华为前端工程师分享:华为云官网的智能化实践
    图解 Redis丨这就是 RDB 快照,能记录实际数据的
    云小课 | 玩转HiLens Studio之快速订购HiLens Studio版本
    带你认识4种设计模式:代理模式、装饰模式、外观模式和享元模式
    线性表、顺序表和链表,你还分不清?
  • 原文地址:https://www.cnblogs.com/goingforward/p/5846226.html
Copyright © 2011-2022 走看看