游标属性
每个游标都有一组与之关联的属性,允许程序测试游标的状态。这些属性是 %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异常 |
版权声明
本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
评论