Each cursor has four attributes: %ISOPEN, %FOUND, %NOTFOUND, and %ROWCOUNT. These attributes are used to test the cursor status. This topic describes these attributes and their examples.
%ISOPEN
The %ISOPEN attribute is used to test whether a cursor is open.
cursor_name%ISOPEN
cursor_name is the name of the cursor. If the cursor is open, TRUE of the BOOLEAN data type is returned. Otherwise, FALSE is returned.
%ISOPEN is used in the following example:
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
The %FOUND attribute is used to test whether a row is retrieved from the result set of the specified
cursor after a FETCH operation is performed on the cursor.
cursor_name%FOUND
cursor_name is the name of the cursor. If a row is retrieved from the result set of the cursor
after a FETCH operation is performed, TRUE of the BOOLEAN data type is returned.
After the last row of the result set is fetched in a FETCH operation, %FOUND returns FALSE due to the next FETCH operation. FALSE is also returned after the first FETCH operation if the result set has no rows.
If %FOUND is referenced on a cursor before the cursor is opened or after the cursor is closed,
an INVALID_CURSOR exception occurs.
If the cursor is open and %FOUND is referenced before the first FETCH operation, %FOUND returns null.
%FOUND is used in the following example:
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;
When the previous stored procedure is invoked, the following output appears:
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
The %NOTFOUND attribute is the logical opposite of %FOUND.
cursor_name%NOTFOUND
cursor_name is the name of the cursor. If a row is retrieved from the result set of the cursor
after a FETCH operation, FALSE of the BOOLEAN data type is returned.
After the last row of the result set is fetched in a FETCH operation, %NOTFOUND returns TRUE due to the next FETCH operation. TRUE is also returned after the first FETCH operation if the result set has no rows.
If %NOTFOUND is referenced on a cursor before the cursor is opened or after the cursor is closed,
an INVALID_CURSOR exception occurs.
If the cursor is open and %NOTFOUND is referenced before the first FETCH operation, %NOTFOUND returns null.
%NOTFOUND is used in the following example:
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;
This stored procedure generates the same output as the preceding example when the stored procedure is invoked.
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
The %ROWCOUNT attribute returns an integer that indicates the number of rows that have been fetched
from the specified cursor in a FETCH operation by now.
cursor_name%ROWCOUNT
cursor_name is the name of the cursor. For this cursor, %ROWCOUNT returns the number of rows that have been retrieved by now. After the last row is
retrieved, %ROWCOUNT is still specified as the total number of rows that are returned before the cursor
is closed. In this case, if %ROWCOUNT is referenced, an INVALID_CURSOR exception occurs.
If %ROWCOUNT is referenced on a cursor before the cursor is opened or after the cursor is closed,
an INVALID_CURSOR exception occurs.
If the cursor has been opened and %ROWCOUNT is referenced before the first FETCH operation, %ROWCOUNT returns 0. %ROWCOUNT also returns 0 after the first FETCH operation when the result set has no rows.
%ROWCOUNT is used in the following example:
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;
This stored procedure generates the total number of rows that are retrieved at the end of the employee list, as shown in the following example:
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
Summary of cursor states and attributes
The following table summarizes the possible cursor states and the values that are returned by the cursor attributes.
| Cursor state | %ISOPEN | %FOUND | %NOTFOUND | %ROWCOUNT |
|---|---|---|---|---|
| Before OPEN | False | INVALID_CURSOR exception | INVALID_CURSOR exception | INVALID_CURSOR exception |
| After OPEN and Before the first FETCH | True | Null | Null | 0 |
| After the first successful FETCH | True | True | False | 1 |
| After the nth successful FETCH (last row) | True | True | False | n |
| After the (n+1)th FETCH (after the last row) | True | False | True | n |
| After CLOSE | False | INVALID_CURSOR exception | INVALID_CURSOR exception | INVALID_CURSOR exception |