PL/SQL Cursor Variable with REF CURSOR
Last Updated :
17 Oct, 2024
In PL/SQL, Cursor variables, also known as REF CURSORs, provide a dynamic and flexible means to handle query results. A cursor variable is a reference to a cursor, which can be opened, fetched, and closed dynamically at runtime.
Here, we'll look into the usage of cursor variables with REF CURSOR in PL/SQL and showcase their versatility in managing dynamic queries and result sets.
Why Use REF CURSOR in PL/SQL?
Cursor variables with REF CURSOR are important in PL/SQL programming for below reasons:
- Dynamic SQL: They allow the creation and execution of dynamic SQL queries. This is useful when the structure of the query or the tables involved is not known at compile time.
- Reusability: Cursor variables can be reused across different parts of the program reducing code duplication and improving maintainability.
- Parameter Passing: They can be used to pass query results between different program units such as stored procedures or functions and enable more modular and flexible code.
- Data Manipulation: They enable complex data manipulation operations that may involve multiple queries or data sources.
What is Cursor Variable with REF CURSOR?
Cursor variables in PL/SQL provide a means to work with dynamic SQL queries and results. Unlike explicit cursors, cursor variables allow the definition of a cursor without specifying the SQL query at compile-time. This flexibility is particularly useful when dealing with varying queries or when the query needs to be determined dynamically during runtime. REF CURSORs, associated with cursor variables enable the retrieval of query results. The below method helps to understand the Cursor Variable with REF CURSOR very effectively.
Let's understand both methods with the help of examples.
1. Using PL/SQL Cursor Variable with REF CURSOR to Fetch Data Dynamically
Let's create a PL/SQL block that utilizes a cursor variable with REF CURSOR to dynamically fetch and display data from the "employees" table. The PL/SQL block should open a cursor for a dynamic query that selects all columns from the "employees" table, fetch the data into variables for "employee_id" and "employee_name", and then display each employee's ID and name using the DBMS_OUTPUT.PUT_LINE function. Finally the cursor should be closed to release resources.
Query:
PL/SQL
-- Sample Data
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(50)
);
INSERT INTO employees VALUES (1, 'John Doe');
INSERT INTO employees VALUES (2, 'Jane Smith');
-- PL/SQL Block with Cursor Variable
DECLARE
TYPE ref_cursor_type IS REF CURSOR;
cursor_variable ref_cursor_type;
emp_id employees.employee_id%TYPE;
emp_name employees.employee_name%TYPE;
BEGIN
-- Dynamic Query using Cursor Variable
OPEN cursor_variable FOR 'SELECT * FROM employees';
-- Fetch and Display Data
LOOP
FETCH cursor_variable INTO emp_id, emp_name;
EXIT WHEN cursor_variable%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_id || ', Employee Name: ' || emp_name);
END LOOP;
-- Close Cursor
CLOSE cursor_variable;
END;
/
Output:
Employee ID | Employee Name |
---|
1 | John Doe |
2 | Jane Smith |
Explanation:
- The cursor variable cursor_variable is dynamically opened for the query 'SELECT * FROM employees'.
- The loop fetches and displays the data from the result set.
2. Using Passing Cursor Variable as Parameter to a Procedure
Let's create a PL/SQL procedure named "display_employee_data" that accepts a cursor variable as an IN OUT parameter. The procedure should fetch and display employee data (employee_id and employee_name) from the cursor variable.
Additionally, we need to create a PL/SQL block that opens a cursor for a dynamic query selecting all columns from the "employees" table. The block should call the "display_employee_data" procedure with the cursor variable as a parameter and then close the cursor to release resources.
Query:
PL/SQL
-- Procedure Accepting Cursor Variable as Parameter
CREATE OR REPLACE PROCEDURE display_employee_data (
p_cursor_variable IN OUT SYS_REFCURSOR
)
IS
emp_id employees.employee_id%TYPE;
emp_name employees.employee_name%TYPE;
BEGIN
-- Fetch and Display Data
LOOP
FETCH p_cursor_variable INTO emp_id, emp_name;
EXIT WHEN p_cursor_variable%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_id || ', Employee Name: ' || emp_name);
END LOOP;
END;
/
-- Sample Data
INSERT INTO employees VALUES (3, 'Bob Johnson');
INSERT INTO employees VALUES (4, 'Alice Williams');
-- PL/SQL Block Calling Procedure with Cursor Variable
DECLARE
TYPE ref_cursor_type IS REF CURSOR;
cursor_variable ref_cursor_type;
BEGIN
-- Dynamic Query using Cursor Variable
OPEN cursor_variable FOR 'SELECT * FROM employees';
-- Call Procedure with Cursor Variable as Parameter
display_employee_data(p_cursor_variable => cursor_variable);
-- Close Cursor
CLOSE cursor_variable;
END;
/
Output:
Employee ID | Employee Name |
---|
1 | John Doe |
2 | Jane Smith |
3 | Bob Johnson |
4 | Alice Williams |
Explanation:
- The procedure display_employee_data accepts a cursor variable as a parameter and fetches data from the provided result set.
- The PL/SQL block calls this procedure with the cursor variable, displaying the combined data from both sets.
Difference between Cursor and REF Cursor
Here is a concise table highlighting the key differences between Cursor and REF Cursor in PL/SQL:
Feature | Cursor | REF Cursor |
---|
Type | Static | Dynamic |
---|
SQL Binding | Query is predefined at compile-time | Query is dynamically assigned at runtime |
---|
Usage | Specific to the defined query | Can be reused with multiple queries |
---|
Passing as Parameter | Cannot be passed between subprograms | Can be passed as a parameter (IN, OUT, IN OUT) |
---|
Flexibility | Less flexible (fixed query structure) | More flexible (dynamic query structure) |
---|
Memory Usage | More resource-intensive for large queries | More efficient for large or dynamic queries |
---|
Important Points About PL/SQL Cursor Variable with REF CURSOR
- Strong REF CURSOR is bound to a specific return type.
- Weak REF CURSOR is not bound to any specific return type, allowing for more flexibility but with less type safety.
- Always remember to explicitly close the REF CURSOR after use to free up resources and avoid memory leaks.
- Unlike static cursors, REF CURSORs can be assigned different queries at runtime.
Similar Reads
SQL Server SELECT INTO @Variable
In the world of SQL Server, the SELECT INTO statement is a powerful syntax for retrieving data from one or more tables and inserting it into a new table. However, what if you want to store the result set of a SELECT query into a variable rather than a table? This is where the SELECT INTO @Variable s
6 min read
PL/SQL Cursor Update
PL/SQL stands for Procedural Language/Structured Query Language. It has block structure programming features. In Oracle PL/SQL, cursors play a vital role in managing and processing query results. Among the various types of cursors, updatable cursors stand out for their ability to fetch data and modi
5 min read
How to Declare a Variable in PL/SQL?
Declaring variables in PL/SQL is a fundamental step towards building powerful and efficient database applications. Variables act as placeholders for data which enable us to manipulate and store information within our PL/SQL programs. Here, we will explore various methods of declaring variables in PL
5 min read
PostgreSQL - Variables
PostgreSQL, one of the most powerful and advanced open-source relational database management systems, provides robust support for procedural programming through its PL/pgSQL language. A fundamental aspect of PL/pgSQL is the use of variables that play a crucial role in storing temporary data and faci
4 min read
How to Declare a Variable in SQL Server?
In SQL Server, variables play a critical role in the dynamic execution of SQL scripts and procedures. Variables allow you to store and manipulate data temporarily within the scope of a batch or procedure. By using the DECLARE statement, you can create variables with specific data types, which can th
6 min read
PL/SQL WITH Clause
The PL/SQL WITH clause is a powerful feature that enhances the readability and performance of your SQL queries. It allows you to define temporary result sets, which can be referenced multiple times within a single query. This feature is particularly useful for simplifying complex queries and improvi
5 min read
PL/SQL Cursor FOR LOOP
Oracle PL/SQL is a powerful extension of SQL, specifically designed to provide procedural capabilities for Oracle databases. It allows developers to write complex programs that combine SQL queries with procedural constructs like loops, conditionals, and exception handling. Among these features, PL/S
4 min read
How to Retrieve Data From Multiple Tables Using PL/SQL Cursors
In database programming, the ability to retrieve data from multiple tables is essential for building robust and efficient applications. PL/SQL Cursors is a powerful feature that enables developers to navigate through result sets and make them the best option for querying data from multiple tables. I
4 min read
PostgreSQL - Record type variable
In PostgreSQL, record-type variables provide a dynamic and flexible way to handle result sets that don't have a predefined structure. Unlike row-type variables, PostgreSQL record-type variables can change their structure after being assigned a new row, making them highly versatile for dynamic SQL op
5 min read
What is Cursor in SQL ?
When working with SQL, most operations are performed on entire sets of data. But what if we need to process each row individually maybe to perform some custom logic or apply conditions row-by-row? Cursors come into play in such scenarios, providing a way to process each row individually. This articl
9 min read