每个游标都有%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 |
---|
游标状态 | %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异常 |