游标变量与游标相似,有其共性,也有其不同点。就其共性来说两者都是指向多行查询的结果集中的当前行。都要经历声明,打开,检索与
关闭的过程。所不同的是游标与游标变量类似于常量与变量。游标是静态的,而游标变量是动态的,因为游标变量并不与某个特定的查询相绑定。
所以,游标变量可以打开任何类型兼容的查询。其次可以将游标变量作为参数传递给本地和存储子程序。本文主要描述游标变量的使用。
一、什么是游标变量
显示游标用于命名一个工作区域,其中保存多行查询的信息,而且该游标始终指向工作区域的内容。而游标变量类似于C
或Pascal 语言中
的指针,它指向一块内存地址,而不是地址中的内容本身。所以,声明一个游标变量可以创建一个指针,而不是具体的内容。
在PL/SQL
中,为创建游标变量,首先需要申明一个REF
CURSOR类型,然后声明该类型的一个变量。
为了执行多行查询,Oracle
会开启一个未命名的工作区来存放处理信息。我们可以用显式游标为工作区命名然后访问相关的信息;或者声
明指向工作区的一个游标变量。无论在什么地方使用游标,它总是指向同一个查询工作区,而游标变量则可以指向不同的工作区。
所以,游标和游标变量不能交互使用;也就是说,我们不能在该使用游标的地方使用游标变量,不能在该使用游标变量的地方使用游标。
二、游标变量使用的情形
PL/SQL
存储子程序和各种客户端之间可以使用游标变量来传递查询结果,这是游标变量最主要的作用。PL/SQL
和其他客户端程序都不拥有
结果集,它们只是共享一个指向存放结果集工作区的指针而已。例如,一个OCI
客户端,一个Oracle Forms 应用程序和Oracle
服务器可以引用
同一个工作区。只要有游标变量指向查询工作区,我们就可以引用它。因此,我们可以把游标变量的值自由地从一个作用域传递到另一个。
例如,我们把主游标变量传递到嵌套在Pro*C
程序中的PL/SQL
块,游标变量指向的工作区就可以被访问。
如果客户端含有PL/SQL
引擎,那么从客户端调用服务器端就不会有什么约束。假如我们在客户端声明游标变量,在服务器端打开并取得数
据,然后把取得的结果返回给客户端。这些操作都是在服务器端完成,从而也减少了网络流量。
三、使用游标变量的几个关键步骤
1、定义和声明游标变量
TYPE ref_type_name IS REF
CURSOR [RETURN return_type];
--必须先定义REF CURSOR类型
cursor_variable
ref_type_name;
--接下来再定义游标变量
ref_type_name:
指定自定义的类型名
RETURN:
指定REF CURSOR返回结果的数据类型
cursor_variable: 定义游标变量的名字
注:若指定RETURN子句,其数据类型必须是记录类型,此外,不能在包规范中定义游标变量。
其次若指定RETURN子句则为强游标类型,否则,为弱游标类型。
能够把一个强类型与类型兼容的查询相关联,而若类型可以与任何查询相关联。故强类型游标变量出错概率低,而弱类型更灵活。
2、打开游标变量
当打开游标变量时,则此时游标变量便与特定的SELECT语句关联,执行该查询,标识结果集。使用OPEN
FOR可以为不同的查询打开相同的游
标变量。再次打开它之前,无需关闭游标变量,但之前的查询会全部丢失。
OPEN cursor_variable FOR
select_statement;
3、从结果集检索数据行
每次从结果集检索一次。需要注意的是强类型返回的数据类型必须与FETCH
语句中INTO所使用的变量类型兼容。
其次查询列值的数量必须等于变量的数量,如果数量不匹配,则强类型在编译时出错,而弱类型则在运行时出错。
FETCH cursor_variable INTO
variable1,...variable2
;
--提取单行数据,需要配合循环语句来使用
FETCH
cursor_variable BULK COLLECT INTO collect1,collect2,...[LIMIT
rows];
--提取多行数据,collect为集合变量
4、关闭游标变量
CLOSE cursor_vairable;
四、定义REF
CURSOR与声明游标变量示例
--PL/SQL块内声明游 变量
DECLARE
TYPE emp_cur_type IS REF CURSOR RETURN emp%ROWTYPE; -->定义具有返回类型的游 类型,此为强类型
TYPE dept_cur_type IS REF CURSOR; -->定义 返回类型的游 类型,此为弱类型
emp_cv emp_cur_type;