通过游标FOR LOOP循环语句处理查询结果集

通过使用游标FOR LOOP循环,可以在运行SELECT语句后直接对其结果集中的行进行循环。此语句既可以使用隐式游标,又可以使用显示游标。

语法:

cursor_for_loop_statement ::=

说明:

record:是游标FOR LOOP循环语句隐式的通过%ROWTYPE声明和cursor或者select_statement返回值类型相同的记录变量作为该循环的索引的名称。record是游标FOR LOOP语句的局部变量。在循环语句内部的语句可以引用record和它的成员。只能通过列别名引用需要通过计算而获取的列。在循环之外的语句不能对record进行引用。在游标FOR LOOP语句运行完之后,record处于未定义状态。

cursor:在进入游标FOR LOOP语句时还未被打开的显式游标的名称。

actual_cursor_parameter:和形式参数cursor相对应的实际参数。

select_statement:SQL的SELECT语句,不是PLOSCAR的SELECT INTO语句。PLOSCAR会为该语句声明、打开、关闭一个隐式游标,并从该游标中提取数据。由于该语句不是一独立的部分,隐式游标是内在的,因此不能通过名称SQL对该游标进行引用。

statement:语句块,可以是赋值语句、基本的循环语句、条件语句、打开语句、PLOSCAR块、退出语句等。

label: cursor_for_loop_statement的标签。CONTINUE、EXIT、GOTO语句都可以引用该标签。标签可增加语句的可读性,特别是在嵌套的循环中。但是必须保证在END LOOP语句中的标签与对应的开始处的LOOP语句中标签相匹配,因为编译器并不会检测匹配问题。

如果仅仅只是在FOR LOOP语句中使用SELECT语句,建议将SELECT语句嵌入到FOR LOOP语句内部。此类型的FOR LOOP语句使用被称为隐式游标的FOR LOOP语句中的隐式游标。由于隐式游标被内嵌到语句中,因此不能通过使用名称SQL来引用之。

如果需要在同一PLOSCAR单元中多次使用相同的SELECT语句,通过为该查询定义显式游标并将该游标放到FOR LOOP语句中,可以实现在同一PLOSCAR单元的任意位置对该显式游标的使用。此种游标FOR LOOP语句被称为显式游标FOR LOOP语句。

游标FOR LOOP循环语句隐式的通过%ROWTYPE声明和游标返回值类型相同的记录变量作为该循环的索引。该记录是循环的局部记录,只在循环执行期间存在。在循环内部的语句可以引用该记录以及该记录的成员。他们只能通过别名来对被计算的列进行引用。

在声明循环的索引记录变量后,FOR LOOP语句会打开相应的游标。对于循环的每一次的迭代,FOR LOOP语句将从结果集中提取一行并将该行存储到记录中。当各行提取完毕后,游标FOR LOOP语句会关闭游标。当循环内部的语句将控制权交接给循环外部语句或者 PLOSCAR抛出异常时,游标同样会关闭。当游标FOR LOOP语句内部抛出异常时,在异常处理器运行之前,游标会关闭,也就是说,显式游标的属性值在异常处理器中并不适用。

游标FOR LOOP语句隐式的将其循环索引声明成类型为游标返回值类型的记录变量,并打开该游标。对于每一次的迭代,游标FOR LOOP语句会从结果集中提取一行数据到记录中。当没有数据以供提取时,游标FOR LOOP语句会关闭游标。当循环内部的语句将控制权交接给循环外部语句或者抛出异常时,游标同样会关闭。

示例:通过游标FOR LOOP循环语句处理查询结果集

--  清理环境
DROP TABLE tab CASCADE;
DROP PROCEDURE proc;

create table tab
(
    a int,
    b varchar(20),
    c date
);
insert into tab values(1,'wang','2010-03-23');
insert into tab values(2,'wang','2010-03-23');
insert into tab values(3,'wang','2010-03-23');

create or replace procedure proc as
declare
    cursor c1 is select * from tab order by a;
    a int;
    item tab%rowtype;
begin
    for item in c1 loop
    a := item.a;
    DBMS_OUTPUT.PUT_LINE(a);
    end loop;
end;

/
exec proc;
1
2
3

--删除过程
DROP PROCEDURE proc;
DROP TABLE tab CASCADE;