每个游标都有%ISOPEN、%FOUND、%NOTFOUND 和 %ROWCOUNT四个属性,用于测试游标的状态。本文为您介绍这些属性及示例。
%ISOPEN
%ISOPEN属性用于测试游标是否已打开。
cursor_name%ISOPEN
cursor_name是游标的名称,如果游标打开,将返回BOOLEAN数据类型TRUE,否则将返回FALSE。
下面是使用%ISOPEN的示例。
CREATE OR REPLACE PROCEDURE cursor_example
IS
...
CURSOR emp_cur_1 IS SELECT * FROM emp;
...
BEGIN
...
IF emp_cur_1%ISOPEN THEN
NULL;
ELSE
OPEN emp_cur_1;
END IF;
FETCH emp_cur_1 INTO ...
...
END;
%FOUND
%FOUND属性用于测试在对游标执行FETCH操作之后是否从指定游标的结果集中检索到行。
cursor_name%FOUND
cursor_name是游标的名称,如果在FETCH之后从游标的结果集中检索到行,则将返回BOOLEAN数据类型TRUE。
在结果集的最后一行被FETCH之后,下一个FETCH将导致%FOUND返回 FALSE。如果结果集中没有行,则第一个FETCH之后也会返回FALSE。
在游标打开之前或关闭游标之后对游标引用%FOUND会导致引发INVALID_CURSOR异常。
如果游标已打开,但在第一个FETCH之前引用%FOUND,它将返回null。
以下示例使用%FOUND。
CREATE OR REPLACE PROCEDURE cursor_example
IS
v_emp_rec emp%ROWTYPE;
CURSOR emp_cur_1 IS SELECT * FROM emp;
BEGIN
OPEN emp_cur_1;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
FETCH emp_cur_1 INTO v_emp_rec;
WHILE emp_cur_1%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_emp_rec.empno || ' ' || v_emp_rec.ename);
FETCH emp_cur_1 INTO v_emp_rec;
END LOOP;
CLOSE emp_cur_1;
END;
调用前面的存储过程时,输出显示如下:
EXEC cursor_example;
EMPNO ENAME
----- ------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
%NOTFOUND
%NOTFOUND属性是%FOUND的逻辑对立面。
cursor_name%NOTFOUND
cursor_name是游标的名称,如果在FETCH之后从游标的结果集中检索到行,则将返回BOOLEAN 数据类型FALSE。
在结果集的最后一行被FETCH之后,下一个FETCH将导致%NOTFOUND返回TRUE。如果结果集中没有行,则第一个FETCH之后也会返回TRUE。
在游标打开之前或关闭游标之后对游标引用%NOTFOUND会导致引发INVALID_CURSOR异常。
如果游标已打开,但在第一个FETCH之前引用%NOTFOUND,它将返回null。
以下示例使用%NOTFOUND。
CREATE OR REPLACE PROCEDURE cursor_example
IS
v_emp_rec emp%ROWTYPE;
CURSOR emp_cur_1 IS SELECT * FROM emp;
BEGIN
OPEN emp_cur_1;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
LOOP
FETCH emp_cur_1 INTO v_emp_rec;
EXIT WHEN emp_cur_1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_emp_rec.empno || ' ' || v_emp_rec.ename);
END LOOP;
CLOSE emp_cur_1;
END;
与前面的示例类似,此存储过程在调用时会生成相同的输出。
EXEC cursor_example;
EMPNO ENAME
----- ------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
%ROWCOUNT
%ROWCOUNT属性返回一个整数,显示到目前为止通过FETCH从指定游标获取的行数。
cursor_name%ROWCOUNT
cursor_name是游标的名称,%ROWCOUNT对其返回到目前为止检索的行数。在检索到最后一行之后,%ROWCOUNT仍然设置为在游标关闭之前返回的总行数,此时如果引用%ROWCOUNT,它将引发 INVALID_CURSOR 异常。
在游标打开之前或关闭游标之后对游标引用%ROWCOUNT会导致引发INVALID_CURSOR异常。
如果游标已打开,但在第一个FETCH之前引用%ROWCOUNT,它将返回0。如果结果集中没有行,%ROWCOUNT也会在第一个FETCH后返回0。
以下示例使用%ROWCOUNT。
CREATE OR REPLACE PROCEDURE cursor_example
IS
v_emp_rec emp%ROWTYPE;
CURSOR emp_cur_1 IS SELECT * FROM emp;
BEGIN
OPEN emp_cur_1;
DBMS_OUTPUT.PUT_LINE('EMPNO ENAME');
DBMS_OUTPUT.PUT_LINE('----- -------');
LOOP
FETCH emp_cur_1 INTO v_emp_rec;
EXIT WHEN emp_cur_1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_emp_rec.empno || ' ' || v_emp_rec.ename);
END LOOP;
DBMS_OUTPUT.PUT_LINE('**********************');
DBMS_OUTPUT.PUT_LINE(emp_cur_1%ROWCOUNT || ' rows were retrieved');
CLOSE emp_cur_1;
END;
此存储过程输出在员工列表末尾检索的总行数,如下所示:
EXEC cursor_example;
EMPNO ENAME
----- -------
7369 SMITH
7499 ALLEN
7521 WARD
7566 JONES
7654 MARTIN
7698 BLAKE
7782 CLARK
7788 SCOTT
7839 KING
7844 TURNER
7876 ADAMS
7900 JAMES
7902 FORD
7934 MILLER
**********************
14 rows were retrieved
游标状态和属性摘要
下表总结了可能的游标状态和游标属性返回的值。
| 游标状态 | %ISOPEN | %FOUND | %NOTFOUND | %ROWCOUNT |
|---|---|---|---|---|
| 在OPEN之前 | False | INVALID_CURSOR异常 | INVALID_CURSOR异常 | INVALID_CURSOR异常 |
| 在OPEN之后,第一个FETCH之前 | True | Null | Null | 0 |
| 第一个成功的FETCH之后 | True | True | False | 1 |
| 第n个成功的FETCH之后(最后一行) | True | True | False | n |
| 第n+1个FETCH之后(最后一行之后) | True | False | True | n |
| 在CLOSE之后 | False | INVALID_CURSOR异常 | INVALID_CURSOR异常 | INVALID_CURSOR异常 |