Oracle Nested Cursor Faqs Iwth Examples

1. What is a Nested Cursor?

A nested cursor is a cursor operation performed inside another cursor operation. The outer cursor processes the parent records, while the inner cursor processes related child records.

2. Why do we use Nested Cursors?

Nested cursors are useful when one set of records is related to another. The source notes show examples such as departments with employees beneath them.

3. Basic Syntax

DECLARE
    CURSOR outer_cursor IS
        SELECT ...;

```
CURSOR inner_cursor(...) IS
    SELECT ...;
```

BEGIN
FOR outer_rec IN outer_cursor
LOOP
FOR inner_rec IN inner_cursor(...)
LOOP
-- Process inner record
END LOOP;
END LOOP;
END;
/

4. Simple Nested Cursor Example

The notes show a department-and-employee example using a department cursor and a parameterized employee cursor.

DECLARE
    CURSOR dept_cursor IS
        SELECT department_id, department_name
        FROM departments;

    CURSOR emp_cursor(p_dept_id NUMBER) IS
        SELECT employee_id, first_name, salary
        FROM employees
        WHERE department_id = p_dept_id;
BEGIN
    FOR dept IN dept_cursor
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            'Department: ' || dept.department_name
        );

        FOR emp IN emp_cursor(dept.department_id)
        LOOP
            DBMS_OUTPUT.PUT_LINE(
                '  Employee: ' ||
                emp.first_name ||
                ' - Salary: ' ||
                emp.salary
            );
        END LOOP;
    END LOOP;
END;
/

5. How does a Nested Cursor work?

The processing happens like this: outer cursor, then one inner cursor run for each outer-row value. The inner cursor starts again for each outer row.

Outer Cursor
    ↓
Department 10
    ↓
Inner Cursor
    ↓
Employees of Department 10
    ↓
Finish employees
    ↓
Department 20
    ↓
Inner Cursor
    ↓
Employees of Department 20
    ↓
Finish employees
    ↓
Next department

6. Outer Cursor and Inner Cursor

Term Meaning
Outer cursor The cursor that controls the outer loop.
Inner cursor The cursor inside the outer loop.

7. Why is a Parameterized Cursor useful?

A parameterized cursor allows the inner cursor to use a value from the current outer record.

CURSOR emp_cursor(p_dept_id NUMBER) IS
    SELECT employee_id, first_name
    FROM employees
    WHERE department_id = p_dept_id;

8. Can we use an inline query instead of a named inner cursor?

Yes. The notes say you do not always need a named inner cursor, and for a simple one-time inner query the inline query is often easier to read.

BEGIN
    FOR dept IN (
        SELECT department_id, department_name
        FROM departments
    )
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            'Department: ' || dept.department_name
        );

        FOR emp IN (
            SELECT employee_id, first_name, salary
            FROM employees
            WHERE department_id = dept.department_id
        )
        LOOP
            DBMS_OUTPUT.PUT_LINE(
                '  Employee: ' || emp.first_name
            );
        END LOOP;
    END LOOP;
END;
/

9. Can a Nested Cursor have three levels?

Yes. The file gives a Department → Employee → Project example.

BEGIN
    FOR dept IN (
        SELECT department_id, department_name
        FROM departments
    )
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            'Department: ' || dept.department_name
        );

        FOR emp IN (
            SELECT employee_id, first_name
            FROM employees
            WHERE department_id = dept.department_id
        )
        LOOP
            DBMS_OUTPUT.PUT_LINE(
                '  Employee: ' || emp.first_name
            );

            FOR project IN (
                SELECT project_id, project_name
                FROM projects
                WHERE employee_id = emp.employee_id
            )
            LOOP
                DBMS_OUTPUT.PUT_LINE(
                    '    Project: ' || project.project_name
                );
            END LOOP;
        END LOOP;
    END LOOP;
END;
/

10. Can we use nested explicit cursors with OPEN/FETCH/CLOSE?

Yes. The notes show a full explicit example with OPEN, FETCH, EXIT WHEN, and CLOSE for both cursors, but also note that a Cursor FOR LOOP is much simpler.

DECLARE
    CURSOR dept_cursor IS
        SELECT department_id, department_name
        FROM departments;

    CURSOR emp_cursor(p_dept_id NUMBER) IS
        SELECT employee_id, first_name
        FROM employees
        WHERE department_id = p_dept_id;

    v_dept_id   departments.department_id%TYPE;
    v_dept_name departments.department_name%TYPE;

    v_emp_id    employees.employee_id%TYPE;
    v_emp_name  employees.first_name%TYPE;
BEGIN
    OPEN dept_cursor;

    LOOP
        FETCH dept_cursor
        INTO v_dept_id, v_dept_name;

        EXIT WHEN dept_cursor%NOTFOUND;

        DBMS_OUTPUT.PUT_LINE(
            'Department: ' || v_dept_name
        );

        OPEN emp_cursor(v_dept_id);

        LOOP
            FETCH emp_cursor
            INTO v_emp_id, v_emp_name;

            EXIT WHEN emp_cursor%NOTFOUND;

            DBMS_OUTPUT.PUT_LINE(
                '  Employee: ' || v_emp_name
            );
        END LOOP;

        CLOSE emp_cursor;
    END LOOP;

    CLOSE dept_cursor;
END;
/

11. Nested Cursor vs JOIN

The source recommends a JOIN for simple data retrieval and a single SQL statement for set-based work whenever possible.

Nested Cursor JOIN / Set-based SQL
Useful for parent-child processing Often better for simple retrieval
Processes row by row Processes data in a set
Can be more verbose Usually shorter and clearer

12. Can the inner cursor use values from the outer cursor?

Yes. This is one of the most important features of nested cursor processing. The inner query can use the current outer cursor value, such as dept.department_id.

13. What happens if the outer cursor returns no rows?

The entire nested processing is skipped. If the outer loop has zero iterations, the inner loop never runs.

14. What happens if the inner cursor has no rows?

The outer loop continues normally, and the inner loop simply executes zero times for that outer row.

15. Can we use IF, UPDATE, DELETE, EXIT, and CONTINUE inside nested cursors?

Yes. The source includes examples of IF logic, UPDATE, DELETE, EXIT, CONTINUE, FOR UPDATE, and WHERE CURRENT OF inside nested cursor processing.

16. Customer and Orders Example

The notes also show another hierarchical example using customers and orders.

BEGIN
    FOR customer IN (
        SELECT customer_id, customer_name
        FROM customers
    )
    LOOP
        DBMS_OUTPUT.PUT_LINE(
            'Customer: ' || customer.customer_name
        );

        FOR ord IN (
            SELECT order_id, order_date, total_amount
            FROM orders
            WHERE customer_id = customer.customer_id
        )
        LOOP
            DBMS_OUTPUT.PUT_LINE(
                '  Order: ' || ord.order_id ||
                ' Amount: ' || ord.total_amount
            );
        END LOOP;
    END LOOP;
END;
/

17. Frequently Asked Questions

Question Answer
What is a nested cursor? A cursor or cursor loop executed inside another cursor loop.
What is the outer cursor? The cursor controlling the outer loop.
What is the inner cursor? The cursor executing inside the outer loop.
Why use nested cursors? To process related parent-child records.
Can the inner cursor use values from the outer cursor? Yes.
Can a parameterized cursor be used as the inner cursor? Yes.
Can we use an inline query for the inner cursor? Yes.
Can we have three or more cursor levels? Yes, although deep nesting can become difficult to maintain.
What happens if the outer cursor returns no rows? The inner cursor is never executed.
What happens if the inner cursor returns no rows? The inner loop executes zero times, and the outer loop continues.

Important Exam Points

  1. Nested cursor = cursor inside another cursor.
  2. The outer cursor processes the parent records.
  3. The inner cursor processes related child records.
  4. The inner cursor can use values from the outer cursor.
  5. Parameterized cursors are commonly used for the inner cursor.
  6. Cursor FOR LOOP automatically handles OPEN, FETCH, and CLOSE.
  7. The inner loop executes once for each applicable outer row.
  8. Outer cursor returns zero rows → inner cursor does not execute.
  9. Inner cursor returns zero rows → outer loop continues.
  10. EXIT without a label exits the innermost loop.
  11. Labels can be used to exit an outer loop.
  12. CONTINUE can skip an iteration.
  13. FOR UPDATE can be used when row locking or update processing is required.
  14. WHERE CURRENT OF can be used with an appropriate FOR UPDATE cursor.
  15. Multiple nesting levels are possible.
  16. For simple parent-child retrieval, a JOIN may be better.
  17. For set-based DML, prefer a single SQL statement when possible.

Quick Revision Diagram

OUTER CURSOR
    |
    +-- Department
         |
         +-- INNER CURSOR
              |
              +-- Employees
                   |
                   +-- Another level if needed

One-line memory trick: Nested Cursor = Outer cursor finds the parent, and the inner cursor processes the related children.

No comments:

Post a Comment