BULK COLLECT with FORALL

Pranav Bakare - Oct 10 - - Dev Community

BULK COLLECT with FORALL

The combination of BULK COLLECT and FORALL in Oracle PL/SQL allows for efficient data manipulation by minimizing context switches between SQL and PL/SQL engines. You typically use BULK COLLECT to fetch large datasets into collections and FORALL to perform bulk DML operations (like INSERT, UPDATE, or DELETE) using those collections.


Key Points:

BULK COLLECT allows fetching multiple rows into a collection with a single context switch.

FORALL is used to apply DML operations in bulk to improve performance by minimizing context switches.


In this example, we will use BULK COLLECT to retrieve data from the database and FORALL to update the data in bulk. The use case will be to:

  1. Retrieve employees with a salary less than a certain threshold.

  2. Update their salaries in bulk by adding a raise.

Example: BULK COLLECT with FORALL

Step 1: Create a Sample employees Table


CREATE TABLE employees (
    employee_id NUMBER PRIMARY KEY,
    first_name VARCHAR2(50),
    last_name VARCHAR2(50),
    salary NUMBER
);

INSERT INTO employees VALUES (1, 'John', 'Doe', 50000);
INSERT INTO employees VALUES (2, 'Jane', 'Smith', 60000);
INSERT INTO employees VALUES (3, 'Mike', 'Johnson', 55000);
INSERT INTO employees VALUES (4, 'Emily', 'Davis', 70000);
INSERT INTO employees VALUES (5, 'Chris', 'Brown', 45000);

COMMIT;
Enter fullscreen mode Exit fullscreen mode

Step 2: PL/SQL Block with BULK COLLECT and FORALL

DECLARE
    -- Define the collection types
    TYPE emp_id_tab IS TABLE OF employees.employee_id%TYPE;
    TYPE salary_tab IS TABLE OF employees.salary%TYPE;

    l_emp_ids emp_id_tab;       -- Collection to hold employee IDs
    l_salaries salary_tab;      -- Collection to hold employee salaries

BEGIN
    -- Step 1: Use BULK COLLECT to fetch data from the employees table
    SELECT employee_id, salary
    BULK COLLECT INTO l_emp_ids, l_salaries
    FROM employees
    WHERE salary < 60000;  -- Fetch only employees with salary less than 60,000

    -- Step 2: Use FORALL to bulk update the fetched employees' salaries
    FORALL i IN l_emp_ids.FIRST .. l_emp_ids.LAST
        UPDATE employees
        SET salary = salary + 5000
        WHERE employee_id = l_emp_ids(i);

    -- Display the updated employee data
    FOR i IN l_emp_ids.FIRST .. l_emp_ids.LAST LOOP
        DBMS_OUTPUT.PUT_LINE('Employee ID: ' || l_emp_ids(i) || 
                             ', New Salary: ' || (l_salaries(i) + 5000));
    END LOOP;

    COMMIT;
END;
/
Enter fullscreen mode Exit fullscreen mode

Explanation:

1. Collection Declaration:

emp_id_tab is a collection type to store employee IDs.

salary_tab is a collection type to store employee salaries.

2. BULK COLLECT:

We use BULK COLLECT INTO to retrieve employees with a salary less than 60,000 and store their IDs in l_emp_ids and their salaries in l_salaries.

3. FORALL:

FORALL is used to perform a bulk update on the employee salaries. It loops over the l_emp_ids collection, updating the salary for each employee by adding 5,000.

4. Output:

After the FORALL statement, a loop goes through the collection and prints the new salary for each employee.

5. Commit:

The COMMIT statement is used to make the changes permanent in the database.


Output:

Assuming the data in the employees table, this block will update the salaries for the employees whose salaries are less than 60,000 and display the updated salaries.

Employee ID: 1, New Salary: 55000
Employee ID: 3, New Salary: 60000
Employee ID: 5, New Salary: 50000
Enter fullscreen mode Exit fullscreen mode

Why Use BULK COLLECT and FORALL?

Performance: BULK COLLECT fetches multiple rows in a single operation, reducing the number of context switches between the SQL and PL/SQL engines.

Efficiency: FORALL allows you to execute DML (Data Manipulation Language) statements like UPDATE, INSERT, and DELETE in bulk. This reduces the overhead associated with individual DML statements executed in a loop.

This combination is particularly useful when you need to update large datasets efficiently.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .