游标概述
为了处理SQL语句,存储过程进程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。
须知: 当游标作为存储过程的返回值时,如果使用JDBC调用该存储过程,返回的游标将不可用。
游标的使用分为显式游标和隐式游标。对于不同的SQL语句,游标的使用情况不同,详细信息请参见表1。
SQL语句 | 游标 |
---|---|
非查询语句 | 隐式的 |
结果是单行的查询语句 | 隐式的或显式的 |
结果是多行的查询语句 | 显式的 |
显式游标
显式游标主要用于对查询语句的处理,尤其是在查询结果为多条记录的情况下。
处理步骤
显式游标处理需六个PL/SQL步骤:
-
定义静态游标:就是定义一个游标名,以及与其相对应的SELECT语句。
定义静态游标的语法图,请参见图1。
参数说明:
-
cursor_name: 定义的游标名。
-
parameter: 游标参数,只能为输入参数,其格式为:
parameter_name datatype
复制 -
select_statement: 查询语句。
说明: 根据执行计划的不同,系统会自动判断该游标是否可以用于以倒序的方式检索数据行。
定义动态游标:指ref游标,可以通过一组静态的SQL语句动态的打开游标。首先定义ref游标类型,然后定义该游标类型的游标变量,在打开游标时通过OPEN FOR动态绑定SELECT语句。
-
-
打开静态游标:就是执行游标所对应的SELECT语句,将其查询结果放入工作区,并且指针指向工作区的首部,标识游标结果集合。如果游标查询语句中带有FOR UPDATE选项,OPEN语句还将锁定数据库表中游标结果集合对应的数据行。
打开静态游标的语法图,请参见图4。
打开动态游标:可以通过OPEN FOR语句打开动态游标,动态绑定SQL语句。
打开动态游标的语法图,请参见图5。
PL/SQL程序不能用OPEN语句重复打开一个游标。
-
提取游标数据: 检索结果集合中的数据行,放入指定的输出变量中。
提取游标数据的语法图,请参见图6。
-
对该记录进行处理。
-
继续处理,直到活动集合中没有记录。
-
关闭游标: 当提取和处理完游标结果集合数据后,应及时关闭游标,以释放该游标所占用的系统资源,并使该游标的工作区变成无效,不能再使用FETCH语句获取其中数据。关闭后的游标可以使用OPEN语句重新打开。
关闭游标的语法图,请参见图7。
属性
游标的属性用于控制程序流程或者了解程序的状态。当运行DML语句时,PL/SQL打开一个内建游标并处理结果,游标是维护查询结果的内存中的一个区域,游标在运行DML语句时打开,完成后关闭。显式游标的属性为:
- %FOUND布尔型属性: 当最近一次读记录时成功返回,则值为TRUE。
- %NOTFOUND布尔型属性: 与%FOUND相反。
- %ISOPEN布尔型属性: 当游标已打开时返回TRUE。
- %ROWCOUNT数值型属性: 返回已从游标中读取的记录数。
隐式游标
对于非查询语句,如修改、删除操作,则由系统自动地为这些操作设置游标并创建其工作区,这些由系统隐含创建的游标称为隐式游标,隐式游标的名称为SQL,这是由系统定义的。
简介
对于隐式游标的操作,如定义、打开、取值及关闭操作,都由系统自动地完成,无需用户进行处理。用户只能通过隐式游标的相关属性,来完成相应的操作。在隐式游标的工作区中,所存放的数据是最新处理的一条SQL语句所包含的数据,与用户自定义的显式游标无关。
格式调用为: SQL%
说明: INSERT,UPDATE,DELETE,SELECT语句中不必明确定义游标。
属性
隐式游标属性为:
- SQL%FOUND布尔型属性: 当最近一次读记录时成功返回,则值为TRUE。
- SQL%NOTFOUND布尔型属性: 与%FOUND相反。
- SQL%ROWCOUNT数值型属性: 返回已从游标中读取得记录数。
- SQL%ISOPEN布尔型属性: 取值总是FALSE。SQL语句执行完毕立即关闭隐式游标。
示例
--删除员工表hr.staffs表中某部门的所有员工,如果该部门中已没有员工,则在部门表hr.sections中删除该部门。 CREATE OR REPLACE PROCEDURE proc_cursor3() AS DECLARE V_DEPTNO NUMBER(4) := 100; BEGIN DELETE FROM hr.staffs WHERE section_ID = V_DEPTNO; --根据游标状态做进一步处理 IF SQL%NOTFOUND THEN DELETE FROM hr.sections WHERE section_ID = V_DEPTNO; END IF; END; / CALL proc_cursor3(); --删除存储过程和临时表 DROP PROCEDURE proc_cursor3;
复制
游标循环
游标在WHILE语句、LOOP语句中的使用称为游标循环,一般这种循环都需要使用OPEN、FETCH和CLOSE语句。下面要介绍的一种循环不需要这些操作,可以简化游标循环的操作,这种循环方式适用于静态游标的循环,不用执行静态游标的四个步骤。
语法
FOR AS循环的语法请参见图8。
注意事项
- 不能在该循环语句中对查询的表进行更新操作。
- 变量loop_name会自动定义且只在此循环中有效,类型和select_statement的查询结果类型一致。loop_name的取值就是select_statement的查询结果。
- 游标的属性中%FOUND、%NOTFOUND、%ROWCOUNT在MogDB数据库中都是访问同一个内部变量,事务和匿名块不支持多个游标同时访问。