PL 提供了更易用的 FOR 循环语句,自动执行游标的 OPEN、FETCH、CLOSE 语句和循环语句的功能。

    当进入循环时,游标 FOR 循环语句自动打开游标,并提取第一行游标数据,当程序处理完当前所提取的数据而进入下一次循环时,游标 FOR 循环语句自动提取下一行数据供程序处理,当提取完结果集合中的所有数据行后结束循环,并自动关闭游标。

    格式如下:

    1. FOR index_variable IN cursor_name[value[, value]…] LOOP
    2. -- 游标数据处理代码
    3. END LOOP;

    index_variable 为游标 FOR 循环语句隐含声明的索引变量,无需在 DECLARE 中声明,该变量为 record 类型,其结构与游标查询语句返回的结构集合的结构相同。在程序中可以通过引用该索引记录变量元素来读取所提取的游标数据,index_variable 中各元素的名称与游标查询语句选择列表中所制定的列名相同。如果在游标查询语句的选择列表中存在计算列,则必须为这些计算列指定别名后才能通过游标 FOR 循环语句中的索引变量来访问这些列数据。

    示例如下:

    1. obclient> DECLARE
    2. -> CURSOR c_emp IS SELECT first_name, salary
    3. -> FROM employees where rownum<5;
    4. -> BEGIN
    5. -> --隐含打开游标
    6. -> FOR r_emp IN c_emp LOOP
    7. -> --隐含执行FETCH语句
    8. -> DBMS_OUTPUT.PUT_LINE(r_emp.first_name||'''s salary is '||r_emp.salary );
    9. -> --隐含检测c_emp%NOTFOUND
    10. -> END LOOP;
    11. -> END;
    12. -> /
    13. Query OK, 0 rows affected (0.04 sec)
    14. Neena's salary is 17000
    15. Lex's salary is 17000
    16. Alexander's salary is 9000
    17. Bruce's salary is 6000

    使用 FOR 遍历游标时,同样可以传递游标参数:

    1. obclient> DECLARE
    2. -> CURSOR c_emp (in_job_id varchar default 'AC_MGR' ) IS
    3. -> SELECT first_name, salary
    4. -> FROM employees where job_id = in_job_id;
    5. -> v_jobid employees.job_id%TYPE;
    6. -> BEGIN
    7. -> v_jobid := 'IT_PROG';
    8. -> FOR r_emp IN c_emp(v_jobid) LOOP
    9. -> DBMS_OUTPUT.PUT_LINE('DEPT '||v_jobid||': '||r_emp.first_name||'''s salary is '||r_emp.salary );
    10. -> END LOOP;
    11. -> END;
    12. -> /
    13. Query OK, 0 rows affected (0.04 sec)
    14. DEPT IT_PROG: Alexander's salary is 9000
    15. DEPT IT_PROG: Bruce's salary is 6000
    16. DEPT IT_PROG: David's salary is 4800
    17. DEPT IT_PROG: Valli's salary is 4800
    18. DEPT IT_PROG: Diana's salary is 4200

    PL 还允许在 FOR 循环中使用子查询来直接定义游标:

    1. obclient> BEGIN
    2. -> FOR r_emp IN (SELECT first_name, salary FROM employees) LOOP
    3. -> DBMS_OUTPUT.PUT_LINE(r_emp.first_name||'''s salary is '||r_emp.salary );
    4. -> END LOOP;
    5. -> END;
    6. -> /
    7. Query OK, 0 rows affected (0.13 sec)
    8. Neena's salary is 17000
    9. Lex's salary is 17000
    10. Alexander's salary is 9000
    11. Bruce's salary is 6000
    12. ...