PL/SQL REF Cursors: A Comprehensive Guide
In PL/SQL, a standard cursor is static; it is tied to a specific SELECT statement at compile time. A REF CURSOR (Reference Cursor) is a dynamic cursor variable. It is essentially a pointer to a result set that can be opened for different queries at runtime (Oracle, 2009). This makes REF Cursors incredibly powerful for returning result sets from stored procedures to external applications, such as Java, .NET, or Oracle APEX (Oracle, 2026).
Part 1: Using REF Cursors (The Core Concept)
The most common use case for a REF Cursor is as an OUT parameter in a stored procedure. The procedure opens the cursor and passes it back to the calling application (Oracle, 2026).
Crucial Rule: When a procedure returns a SYS_REFCURSOR, it should NOT close the cursor. It is up to the calling code (the application or the PL/SQL block that called the procedure) to fetch the data and close the cursor (Oracle, 2026).
The Procedure Example
The following procedure opens a query using a SYS_REFCURSOR output parameter to return a subset of records from the EMP table.
CREATE OR REPLACE
PROCEDURE get_emp_rs (
p_deptno IN emp.deptno%TYPE,
p_recordset OUT SYS_REFCURSOR
) AS
BEGIN
OPEN p_recordset FOR
SELECT ename,
empno,
deptno
FROM emp
WHERE deptno = p_deptno
ORDER BY ename;
END get_emp_rs;
/
Part 2: How to Call the Procedure (The Missing Piece)
Because the procedure above does not close the cursor, you must write a PL/SQL block to call it, fetch the data, and close it. Here is how you would call get_emp_rs from another PL/SQL block (Oracle, 2009).
SET SERVEROUTPUT ON
DECLARE
-- 1. Declare a variable of type SYS_REFCURSOR
v_cursor SYS_REFCURSOR;
-- 2. Declare variables to hold the fetched columns
v_ename emp.ename%TYPE;
v_empno emp.empno%TYPE;
v_deptno emp.deptno%TYPE;
BEGIN
-- 3. Call the procedure and pass the cursor variable
get_emp_rs(p_deptno => 10, p_recordset => v_cursor);
-- 4. Fetch the data in a loop
LOOP
FETCH v_cursor INTO v_ename, v_empno, v_deptno;
EXIT WHEN v_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Name: ' || v_ename || ' | ID: ' || v_empno);
END LOOP;
-- 5. Close the cursor (The calling code is responsible for this)
CLOSE v_cursor;
END;
/
Part 3: Strongly Typed vs. Weakly Typed REF Cursors
When defining a REF Cursor, you have two choices: Strongly Typed and Weakly Typed (Oracle, 2009).
1. Strongly Typed REF Cursor
A strongly typed REF Cursor has a fixed return type. Oracle knows exactly what columns the cursor will return at compile time. This provides compile-time safety, as the compiler will reject queries that do not match the declared return type (Oracle, 2009).
DECLARE
-- The cursor MUST return columns that match the EMP table
TYPE emp_cursor IS REF CURSOR RETURN emp%ROWTYPE;
v_cur emp_cursor;
BEGIN
OPEN v_cur FOR SELECT * FROM emp WHERE deptno = 10;
END;
/
2. Weakly Typed REF Cursor
A weakly typed REF Cursor has no fixed return type. You can open it for any query you want. SYS_REFCURSOR is a built-in weakly typed REF Cursor (Oracle, 2009).
DECLARE
-- This can be opened for ANY select statement
v_cur SYS_REFCURSOR;
BEGIN
OPEN v_cur FOR SELECT ename, salary FROM emp;
-- ... later ...
OPEN v_cur FOR SELECT department_id, department_name FROM departments;
END;
/
Part 4: Why Use REF Cursors? (Real-World Benefits)
- Returning Result Sets to Applications: In Oracle APEX, Java, or .NET, you cannot easily return a standard PL/SQL cursor. You must use a
SYS_REFCURSORto pass the data back to the application's UI (Oracle, 2026). - Dynamic SQL: Because you can open a REF Cursor for different queries at runtime, they are perfect for building dynamic search screens where the user selects different filters (Oracle, 2009).
- Modularity: You can create generic procedures that return a REF Cursor, and then open that same cursor for different queries based on business logic (Oracle, 2009).
Conclusion: REF Cursors are the bridge between PL/SQL and the outside world. Mastering SYS_REFCURSOR is essential for any Oracle developer building web applications or APIs. Just remember the golden rule: if the procedure opens it, the caller must close it (Oracle, 2026).
References
Oracle. (2009). PL/SQL language elements: Cursor variables. Oracle Help Center. https://docs.oracle.com/cd/A91034_01/DOC/appdev.901/a89856/13_elems13.htm
Oracle. (2026). Database PL/SQL language reference: Cursor variables (19c). Oracle Help Center. https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/cursor-variables.html
No comments:
Post a Comment