Oracle——11游标
PL/SQL语句通过游标提供了对一个结果集进行逐行处理的能力。游标可以视为一种特殊的指针,它与某个查询结果相联系,可以指向结果集的任何位置,以便对指定位置的数据进行处理。使用游标可以在查询数据的同时对数据进行处理。游标分为显式游标和隐式游标两种。
一、显式游标
使用显示游标需要遵循声明游标——>打开游标——>读取数据——>关闭游标四个步骤。
1、声明游标
定义的方法如下:
declare cursor cursorName is select_statement
其中cursorName是游标名,select_statement是select语句,它是由该查询产生与所声明的游标像关联的结果集。
例如,以下是一个游标的定义实例:
declare cursor moduleCursor is select name,parent from t_module;
2、打开游标
声明游标后,在使用数据前,必须先打开游标。在PL/SQL中使用open语句打开游标,其格式为:
open cursorName
其中,cursorName是需要打开的游标的名字,打开游标后,可以使用系统变量%rowcount查看游标当前所在的位置。
示例,定义游标moduleCursor,然后打开游标,输出其当前所在的位置。
declare cursor moduleCursor is select name,parent from t_module; begin open moduleCursor; dbms_output.put_line(moduleCursor%rowcount); end;
3、读取数据
打开游标后,就可以使用fetch语句从中读取数据了。fetch语句的语法格式为:
fetch cursorName [into variable_name,...n]
其中,cursorName表示从中提取数据的游标名,into表示将提取的数据存放到变量variable_name中去。
示例代码:
declare moduleName char(20); moduleId number(3); cursor moduleCursor is select id, name from t_module; begin open moduleCursor; dbms_output.put_line(moduleCursor%ROWCOUNT); fetch moduleCursor into moduleId, moduleName; --在进行found操作之前必须先进行一次fetch操作,否则游标不会指向结果集的开始,found操作永远返回false。 while moduleCursor%found loop dbms_output.put_line('ModuleName: ' || moduleName || ' , ModuleId: ' || moduleId); fetch moduleCursor into moduleId, moduleName; end loop; close moduleCursor; end;
在读取游标的数据的时候,也可以使用游标的for循环进行读取,把上述示例用for循环可以重写如下:
declare moduleId number(3); moduleName char(20); cursor moduleCursor is select id, name from t_module; begin for moduleCursorRecord in moduleCursor loop --moduleCursorRecord是一个临时变量,代表当前的一条记录 moduleId := moduleCursorRecord.id; moduleName := moduleCursorRecord.name; dbms_output.put_line('ModuleId:' || moduleId || ', ModuleName:' || moduleName); end loop; end;
有上述代码可知,在对游标进行循环取数据时,使用for循环可以大大减少代码量,增强代码的可读性。此外,使用for循环的时候,不需要显式的打开和关闭游标。
4、关闭游标
游标使用完以后,要及时关闭,释放所占的内存区。关闭游标使用close语句,格式如下:
close cursorName;
5、几点需要注意的地方
(1)用%found和%notfound检验游标成功与否。该属性表示当前的游标是否指向有效的一行,根据其返回值true或者false检查是否该结束游标的使用。如果游标不是指向结果集的末尾,则返回成功,在第一次fetch的时候,游标指向结果集的最前端,如果此时结果集中含记录,则%found将返回true,下一次执行fetch操作将使游标指向下一条记录的前端,如果该记录存在则%found将返回true,否则返回false。该测试必须在游标关闭前进行。
(2)游标目标变量必须与游标select表中的列的数据类型一致。
(3)如果试图打开一个已打开或者关闭一个已关闭的游标时将会出现错误。因此,在进行打开或者关闭操作前,如果不知道游标的当前状态,可以使用%isopen进行检查,再根据其返回值执行相应的打开或者关闭操作。
(4)可以使用%rowcount获取当前游标所在的位置。
二、隐式游标
如果在PL/SQL程序段中使用select语句进行操作,PL/SQL语言会隐含地处理游标定义,这就是隐式游标。这种游标不需要像显式游标一样的声明,也不需要打开和关闭。
以下是一段在方法中使用了隐式游标的说明:
create or replace function moduleNameFunc(moduleId in number) return char as moduleName char(20); begin select name into moduleName from t_module where id = moduleId; return moduleName; end;
使用隐式游标需要注意以下几点:
(1)每一个隐式游标必须有一个into语句。
(2)into语句后接收数据的变量的数据类型要与对应的列的数据类型一致。
(3)隐式游标一次只能返回一条数据。