Explicit Cursors in PL/SQL โ Syntax, Attributes, and Loop Examples
Explicit cursors in PL/SQL provide precise control over query execution and result set handling, especially when dealing with multi-row SELECT statements. Unlike implicit cursors that are managed automatically by PL/SQL, explicit cursors must be explicitly declared, opened, fetched from, and closed.
What Are Explicit Cursors in PL/SQL?
Explicit cursors in PL/SQL are named memory areas that store the result set of a SELECT statement that returns multiple rows. Unlike implicit cursors (which are automatically created), explicit cursors must be declared and controlled by the developer.
Use them when:
You need row-by-row control of a query
You’re locking rows with
FOR UPDATE
You want to pass parameters into the query
Syntax to Declare Explicit Cursors in PL/SQL
CURSOR cursor_name [(parameter_list)]
[RETURN return_type]
IS
SELECT_statement
[FOR UPDATE [OF column_list] [NOWAIT]];
Example โ Simple Declaration:
CURSOR author_cur1 IS
SELECT rowid FROM authors WHERE id > 50;
Example โ With Parameter:
CURSOR author_cur1 (i_id IN NUMBER) IS
SELECT rowid FROM authors WHERE id > i_id;
Opening the Cursor
OPEN author_cur1;
-- Or with parameters:
OPEN author_cur1(50);
Opening:
Parses the query
Evaluates parameters
Creates a result set in the context area
Fetching Records
FETCH cursor_name INTO variable_list | record_variable;
Examples:
FETCH author_cur1 INTO v_rowid;
FETCH author_cur INTO v_first_name, v_last_name;
-- With record variable
FETCH author_cur INTO v_author;
v_author.id
Closing the Cursor
CLOSE cursor_name;
Failure to close a cursor causes memory leaks and potential ORA-01001: invalid cursor errors.Cursor Attributes
Attribute | Description |
---|---|
%FOUND | TRUE if last FETCH returned a row |
%NOTFOUND | Opposite of %FOUND |
%ROWCOUNT | Number of rows fetched so far |
%ISOPEN | TRUE if the cursor is open |
%BULK_ROWCOUNT | Used in BULK COLLECT โ rows affected |
%BULK_EXCEPTIONS | Used in BULK COLLECT โ errors info |
Using Loops with Explicit Cursors in PL/SQL
1. Simple Loop
LOOP
FETCH auth_cur INTO v_author;
EXIT WHEN auth_cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_author.last_name);
END LOOP;
2. While Loop
FETCH auth_cur INTO v_author;
WHILE auth_cur%FOUND LOOP
DBMS_OUTPUT.PUT_LINE(v_author.last_name);
FETCH auth_cur INTO v_author;
END LOOP;
3. Cursor FOR Loop (Most Efficient)
FOR v_author IN auth_cur LOOP
DBMS_OUTPUT.PUT_LINE(v_author.last_name);
END LOOP;
Full Example โ Using Cursor Attributes
SET SERVEROUTPUT ON
DECLARE
v_first_name AUTHORS.FIRST_NAME%TYPE;
v_last_name AUTHORS.LAST_NAME%TYPE;
v_row_count PLS_INTEGER := 0;
v_book_count PLS_INTEGER := 0;
CURSOR auth_cur IS
SELECT a.first_name, a.last_name, COUNT(b.title)
FROM authors a, books b
WHERE a.id IN (b.author1, b.author2, b.author3)
GROUP BY a.first_name, a.last_name
HAVING COUNT(b.title) > 0
ORDER BY a.last_name;
BEGIN
OPEN auth_cur;
LOOP
FETCH auth_cur INTO v_first_name, v_last_name, v_book_count;
EXIT WHEN auth_cur%NOTFOUND;
v_row_count := auth_cur%ROWCOUNT;
DBMS_OUTPUT.PUT_LINE(v_row_count || ' rows processed so far');
DBMS_OUTPUT.PUT_LINE(v_last_name || ', ' || v_first_name || ' wrote ' || v_book_count || ' book(s).');
END LOOP;
CLOSE auth_cur;
IF NOT auth_cur%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE('Cursor closed');
END IF;
END;
/
Conclusion
Explicit cursors are powerful tools in PL/SQL that give you fine-grained control over result sets. Use them when working with multi-row queries, performing row-by-row processing, or needing update locks. Always remember to close cursors and consider cursor FOR loops for cleaner syntax.
AmantPoint Exclusive Learning Series
ยฉ 2025 AmantPoint. All rights reserved. Educational content for developers and learners.