Explicit Cursors in PL/SQL

Explicit Cursors in PL/SQL

In PL/SQL cursors are a fundamental concept used to handle SQL queries that return multiple rows. There are two main types of cursors in PL/SQL, implicit and explicit cursors. While i

mplicit cursors are automatically managed by Oracle for simple SQL statements, explicit cursors give developers full control over the process of querying multiple rows and fetching data one at a time. This control is essential when dealing with complex queries or operations that require row-by-row processing. This article explores Working with Cursors in PL/SQL, Explicit Cursor Syntax in PL/SQL, usage, examples, and best practices. By the end, you’ll have a thorough understanding of how to work with cursors in PL/SQL.

What are Explicit Cursors in PL/SQL?

An explicit cursor is a user-defined cursor for queries that return multiple rows. While in the case of an implicit cursor, PL/SQL handles the query and the result set internally, in the case of an explicit cursor, you have to process query results one by one. That level of control would be particularly useful for fetching and processing data one row at a time, or for dealing with a large amount of data.

Explicit cursors in PL/SQL allow you to:

  • Define the cursor explicitly.
  • Open the cursor to execute the query.
  • Fetch rows from the result set.
  • Process the rows as needed.
  • Close the cursor once processing is complete.

Why Use Explicit Cursors in PL/SQL?

  • Greater Control: Unlike implicit cursors, explicit cursors give you more control over the lifecycle of the cursor, allowing you to fetch rows incrementally and process them.
  • Efficient Data Handling: Explicit cursors are well-suited for handling queries that return large datasets or when you need row-by-row processing.
  • Structured Code: They make it easier to structure PL/SQL programs, allowing you to separate the query logic from the data-processing logic.

Differences Between Implicit and Explicit Cursors

The table below highlights the key differences between implicit and explicit cursors:

FeatureImplicit CursorExplicit Cursor
Cursor DeclarationHandled automatically by PL/SQLManually declared by the developer
ManagementAutomatically managedRequires manual management (open, fetch, close)
ControlLimited control over executionFull control over execution and data fetching
ComplexitySimpler to use for basic operationsMore complex, but provides flexibility for multi-row processing
UsageBest for simple DML operationsIdeal for handling multi-row queries

Syntax of Explicit Cursors in PL/SQL

To use explicit cursors in PL/SQL, you need to follow a specific syntax to declare, open, fetch, and close the cursor.

Explicit Cursor Syntax in PL/SQL

  • Declaring the Cursor: This step defines the cursor and associates it with a specific SQL query.
CURSOR cursor_name IS
  SELECT column1, column2, ... FROM table_name WHERE condition;
  • Opening the Cursor: The OPEN statement executes the SQL query associated with the cursor and prepares the result set for fetching.
OPEN cursor_name;
  • Fetching Rows: The FETCH statement retrieves the next row from the cursor’s result set into specified variables.
FETCH cursor_name INTO variable1, variable2, ...;
  • Closing the Cursor: The CLOSE statement releases the resources associated with the cursor.
CLOSE cursor_name;

Example of Using an Explicit Cursor in PL/SQL

Let’s consider a practical example where we need to fetch and display employee details from a database table employees.

DECLARE
  -- Declare variables to hold fetched data
  v_employee_id employees.employee_id%TYPE;
  v_employee_name employees.employee_name%TYPE;
  
  -- Declare an explicit cursor
  CURSOR emp_cursor IS
    SELECT employee_id, employee_name
    FROM employees
    WHERE department_id = 10;

BEGIN
  -- Open the cursor
  OPEN emp_cursor;
  
  -- Fetch rows one by one
  LOOP
    FETCH emp_cursor INTO v_employee_id, v_employee_name;
    
    -- Exit loop when no more rows are available
    EXIT WHEN emp_cursor%NOTFOUND;
    
    -- Process the fetched data (for example, display the employee details)
    DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_employee_id || ', Name: ' || v_employee_name);
  END LOOP;
  
  -- Close the cursor
  CLOSE emp_cursor;
END;

In this case,

  • There is a declaration of the cursor that selects the details of the employee from an instance of the department.
  • The cursor is opened and rows are fetched within a loop.
  • The loop exits when all rows have been processed, and the cursor is then closed.

Cursor Attributes in PL/SQL

PL/SQL provides several cursor attributes that help you monitor the status of the cursor and the result set.

Cursor AttributeDescription
%FOUNDReturns TRUE if the last fetch found a row, otherwise FALSE.
%NOTFOUNDReturns TRUE if the last fetch did not find a row, otherwise FALSE.
%ROWCOUNTReturns the number of rows fetched so far.
%ISOPENReturns TRUE if the cursor is open, otherwise FALSE.

Example of Cursor Attributes in PL/SQL

DECLARE
  v_employee_id employees.employee_id%TYPE;
  v_employee_name employees.employee_name%TYPE;
  
  CURSOR emp_cursor IS
    SELECT employee_id, employee_name
    FROM employees
    WHERE department_id = 10;

BEGIN
  OPEN emp_cursor;
  
  LOOP
    FETCH emp_cursor INTO v_employee_id, v_employee_name;
    EXIT WHEN emp_cursor%NOTFOUND;  -- Use cursor attribute %NOTFOUND to exit loop
    
    -- Use cursor attributes to monitor cursor status
    DBMS_OUTPUT.PUT_LINE('Row fetched: ' || emp_cursor%ROWCOUNT);
  END LOOP;
  
  CLOSE emp_cursor;
END;

Advanced Cursor Features of PL/SQL

Explicit cursors of PL/SQL do much more than fetching rows. Let’s look into some advanced features.

Parameterised Cursors

A parameterized cursor can use parameters to accept input values to pass to a cursor, enabling it to be more flexible to build dynamic queries based on the actual value provided.

Parameterised Cursors Syntax

CURSOR cursor_name (parameter1 TYPE, parameter2 TYPE) IS
  SELECT column1, column2 FROM table_name WHERE condition;

Example of a Parameterized Cursor

DECLARE
  v_employee_id employees.employee_id%TYPE;
  v_employee_name employees.employee_name%TYPE;
  
  -- Declare a parameterized cursor
  CURSOR emp_cursor (p_department_id employees.department_id%TYPE) IS
    SELECT employee_id, employee_name
    FROM employees
    WHERE department_id = p_department_id;

BEGIN
  -- Open the cursor with a parameter value
  OPEN emp_cursor(10);  -- Fetch employees from department 10
  
  LOOP
    FETCH emp_cursor INTO v_employee_id, v_employee_name;
    EXIT WHEN emp_cursor%NOTFOUND;
    
    DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_employee_id || ', Name: ' || v_employee_name);
  END LOOP;
  
  CLOSE emp_cursor;
END;

In this example, the cursor emp_cursor takes a department ID as a parameter, allowing it to fetch employee details dynamically based on the department.

Cursor FOR Loops

A cursor FOR loop simplifies the process of fetching rows from a cursor. The cursor is opened, fetched, and closed automatically within the loop.

Example of Cursor FOR Loop

DECLARE
  CURSOR emp_cursor IS
    SELECT employee_id, employee_name
    FROM employees
    WHERE department_id = 10;

BEGIN
  -- Using a FOR loop to iterate over the cursor
  FOR emp_rec IN emp_cursor LOOP
    DBMS_OUTPUT.PUT_LINE('Employee ID: ' || emp_rec.employee_id || ', Name: ' || emp_rec.employee_name);
  END LOOP;
END;

Here, the FOR loop automatically handles opening, fetching, and closing the cursor. It reduces the need for manual cursor management, making the code more concise and readable.

Handling Exceptions with Cursors

DECLARE
  CURSOR emp_cursor IS
    SELECT employee_id, employee_name FROM employees WHERE department_id = 10;
  v_employee_id employees.employee_id%TYPE;
  v_employee_name employees.employee_name%TYPE;
BEGIN
  OPEN emp_cursor;
  
  LOOP
    FETCH emp_cursor INTO v_employee_id, v_employee_name;
    EXIT WHEN emp_cursor%NOTFOUND;
    
    DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_employee_id || ', Name: ' || v_employee_name);
  END LOOP;
  
  CLOSE emp_cursor;

EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('An error occurred: ' || SQLERRM);
    IF emp_cursor%ISOPEN THEN
      CLOSE emp_cursor;
    END IF;
END;

Advantages of Explicit Cursors in PL/SQL

Explicit cursors in PL/SQL give one more control and flexibility to work with the database. The developers define and control the cursor while working on hand, which is a more personalized approach toward retrieving and manipulating data. Keeping all that in mind, some of the main advantages are as follows:

1. More Control Over Data Retrieval

Explicit cursors allow the programmer to define a specified SQL statement and control explicitly the fetching of the data. This provides them with the kind of functionality which can process complex queries and multiple rows much better than that of implicit cursors.

2. Capability of Handling Multi-Row Queries

Unlike implicit cursors, explicit cursors can retrieve data from more than one row. This is very helpful when one needs to process large result sets larger than one row in queries; it’s a great way to process bulk data efficiently.

3. Better Flexibility in Fetching Data

You can fetch a rowset with explicit cursors in a way that suits your application logic. For instance, you can fetch rows one at a time or in groups through methods such as FETCH accompanying a condition that controls the fashion in which the rowset is fetched.

4. Cursor Attributes to Monitor

Explicit cursors provide access to many attributes, for example: %ROWCOUNT, %FOUND, %NOTFOUND, %ISOPEN allowing developers to track the cursor state and the operation results. This is very precious in debugging and in conditional logic depending on the results.

5. Robust Exception Handling

Explicit cursors enable exact error handling on SQL statements. Specific exception handling is possible for developers to deal with different scenarios, such as NO_DATA_FOUND or TOO_MANY_ROWS. This makes the code more robust as regards the possible issues that might be raised.

6. Reusability of Cursors

Once declared, explicit cursors may be opened, fetched from, and closed multiple times within the same block or procedure. This reusability will result in performance gains only when the data is accessed iteratively in a single environment.

7. Better Performance for Complex Operations

Explicit cursors may also be optimized for execution performance when queries are particularly complex or very large result sets have to be returned, or in case a number of processing steps have to be done. When using explicit cursors, developers always have the option of fine-tuning queries and fetching strategies to get maximum efficiency.

8. Easier Code

Using explicit cursors often means having structured code. The application of explicit cursors is obviously followed through at the time of data retrieval as well as processing, therefore the readability and maintainability of the code improve.

9. Capability to handle more than one result set

For their part, explicit cursors can be used to manage the presence of several result sets in a single block of PL/SQL, thus giving easier control and management of data even when dealing with various datasets to be processed concurrently.

10. Better facility for debugging

Management of explicit cursors has better debugging facilities. Developers can insert statements of debugging that can trace the state of cursors as well as the data.

Disadvantages of Explicit Cursors in PL/SQL

Notwithstanding this, explicit cursors in PL/SQL have also some disadvantages and disadvantage. Such disadvantages can affect the complexity of the code, performance, and resource management. Here are the main disadvantages of explicit cursors in PL/SQL :

1. Increased Complexity

Explicit cursors, compared to implicit cursors, require more code and management, and hence may be more complex. Developers must actually declare a cursor, open it, fetch records, and close it, which of course results in somewhat more verbose and difficult-to-read code.

2. Manual Resource Management

Using explicit cursors, a developer needs to handle the cursor lifecycle, that is open and close the cursor. If they forget to close a cursor resource leaks may occur, meaning it may degrade application performance and even exhaust resources in a database.

3. Performance Overhead

Some very simple queries require some overhead of defining and managing explicit cursors, which is likely to degrade performance, since an implicit cursor would be more than enough in such cases. Opening, fetching, and closing may be required with unnecessary overhead in execution time and complexity.

4. Risk of Errors in Cursor Management

The explicit cursor handling process is done by hand; therefore, there is the increased chance of making mistakes while coding those cases. Developers may forget closing a cursor. They can perform exception handling incorrectly and get bizarre behavior along with resource leakage.

5. Not so Ideal for Simple Queries

For simple, single-row queries, explicit cursors are perhaps overkill. In these simple cases, implicit cursors leave for cleaner as well as efficient code while adding unwanted complexity by explicit cursors.

6. Greater Learning Curve

The most cumbersome part of explicit cursors is the fact that they are a bit more complex to understand and create compared to implicit cursors, especially for the new developers in PL/SQL, which will extend time needed for training and development, especially if they don’t know cursor management concepts.

7. Duplicate Code

If many explicit cursors are needed for similar work, this causes code duplication. The developer has to copy cursor definitions and fetch logic resulting in a higher maintenance burden and making the codebase harder to maintain.

8. Inability to Debug

Even though cursors can have a kind of debug as cursors explicit, it is cumbersome to debug when a large number of cursors is kept or complex operations involving cursors. It will be very confusing while debugging when know which one cursor is the culprit or which are some cursors in unknown state.

9. Possibility of Not Executing the Query as Efficiently

Explicit cursors may make the database optimizer exclude generation of a most optimal execution plan. Increasing complexity in cursor logic typically means far less than optimal execution time for the query. This is especially so when compared to using certain other even simpler queries with implicit cursors.

10. Not Ideal for Bulk Processing

Explicit cursors are probably not the best choice for dealing with a lot of data. There are mechanisms available in PL/SQL, for example, in the form of bulk processing statements, such as FLORAL or BULK COLLECT, which would typically be a better choice for these scenarios, possibly making explicit cursors more code-complexity intensive.


Discover more from PiEmbSysTech

Subscribe to get the latest posts sent to your email.

Leave a Reply

Scroll to Top

Discover more from PiEmbSysTech

Subscribe now to keep reading and get access to the full archive.

Continue reading