根据我们之前了解到的情况,SQL是面向集合的,我们的查询结果一般包含多条数据,而在PL/SQL 中的变量一般只能存放一条数据,因此变量是无法满足我们的需求的。这时候我们就需要引入游标来为我们解决问题了。
我们知道在 PL/SQL 中可以使用数据控制语言(DML)对数据进行操作,而在使用这些的时候 Orcale 会在内存中为其分配一个缓存区。而游标就是指向该缓存区的指针。它可以对查询结果集的每一行数据分别进行单独的处理。
游标分为显式游标和隐式游标。显式游标是由用户声明操作的一种游标,而隐式游标是 Orcale 为所有的操作语言自动声明和操作的游标。
显式游标
对于显式游标的操作分为:声明,打开,提取,关闭。
1. 声明游标
在游标的声明中定义了游标的名字而且这个游标和一个 SELECT 关联起来。除此之外显式游标必须在 DEXLARE 中。它的语法如下:
CURSOR <游标名> IS SELECT <语句>
注意:这里的SELECT 语句是可以带有 UNION 或者 MINUS 的语句。
2. 打开游标
语法如下:
OPEN <游标名>;
打开游标就会执行定义的 SELECT语句,执行完毕后,查询出来的结果会放入内存,游标的指针会指向查询结果的头部,
3. 提取游标
打开游标后的工作就是从查询出来的集合进行取值了,取值的语句是 FETCH 语法有两种格式:
FETCH <游标名> INTO <变量列表>; FETCH <游标名> INTO PL/SQL 记录;
FETCH 每执行一次游标会向后移动一次直到结束位置。
4. 关闭游标
CLOSE <游标名>;
5. 例子
--创建临时表 create table t_emp ( tempne number(4) primary key, tename varchar2(20) ); create table t_emp2 ( tempne number(4) primary key, tename varchar2(20) ); DECLARE emp_no number(4); --定义变量 emp_nanme varchar2(20); CURSOR emp_cur IS --定义游标 SELECT empno, ename FROM emp; BEGIN OPEN emp_cur; --打开游标 --将第一行的数据放入变量中,之后游标后移 FETCH emp_cur INTO emp_no, emp_nanme; LOOP EXIT WHEN NOT emp_cur%FOUND; --如果游标已经到末尾结束 IF emp_no = '7839' THEN INSERT INTO t_emp values(emp_no,emp_nanme); else INSERT INTO t_emp2 values(emp_no,emp_nanme); END IF; FETCH emp_cur INTO emp_no, emp_nanme; END LOOP; CLOSE emp_cur; --关闭游标 END; /
隐式游标
上面我们学到了显示游标的使用,接下来我们说下隐式游标。当我们在PL/SQL 中直接使用 SELECT 语句进行操作,则就是隐式的使用了游标,这就是隐式游标。这种游标无需定义,也不需要打开和删除。如下所示
BEGIN SELECT empno, ename INTO emp_no, emp_nanme FROM emp WHERE empno = 7839; END
对于隐式游标来说必须要有一个 INTO 子句,因此对于隐式游标来说 SELECT 子句的返回值必须只有一行数据。