La recollida massiva (Bulk Collect) és una característica poderosa de PL/SQL que permet processar múltiples files de dades en una sola operació, millorant significativament el rendiment en comparació amb el processament fila per fila. Aquesta tècnica és especialment útil quan es treballa amb grans volums de dades.

Conceptes Clau

Què és la recollida massiva?

La recollida massiva permet carregar múltiples files de dades en col·leccions PL/SQL (com ara taules indexades, matrius o VARRAYs) en una sola operació SQL. Això redueix el nombre de commutacions de context entre PL/SQL i SQL, millorant així el rendiment.

Beneficis de la recollida massiva

  • Rendiment millorat: Redueix el nombre de commutacions de context entre PL/SQL i SQL.
  • Codi més net: Simplifica el codi en comparació amb els bucles que processen fila per fila.
  • Menys càrrega de xarxa: Menys operacions de xarxa en entorns distribuïts.

Sintaxi de la recollida massiva

La sintaxi bàsica per utilitzar BULK COLLECT és la següent:

SELECT column1, column2, ...
BULK COLLECT INTO collection1, collection2, ...
FROM table_name
WHERE condition;

Exemple pràctic

Suposem que tenim una taula employees i volem carregar tots els noms i salaris en col·leccions PL/SQL.

DECLARE
    TYPE t_name IS TABLE OF employees.name%TYPE;
    TYPE t_salary IS TABLE OF employees.salary%TYPE;
    
    l_names t_name;
    l_salaries t_salary;
BEGIN
    SELECT name, salary
    BULK COLLECT INTO l_names, l_salaries
    FROM employees;
    
    -- Processar les dades recollides
    FOR i IN 1..l_names.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE('Nom: ' || l_names(i) || ', Salari: ' || l_salaries(i));
    END LOOP;
END;
/

Explicació del codi

  1. Declaració de tipus de col·lecció: Es declaren dos tipus de col·lecció, t_name i t_salary, basats en els tipus de dades de les columnes name i salary de la taula employees.
  2. Declaració de variables de col·lecció: Es declaren dues variables de col·lecció, l_names i l_salaries, de tipus t_name i t_salary respectivament.
  3. Recollida massiva: La sentència SELECT utilitza BULK COLLECT per carregar totes les files de les columnes name i salary en les col·leccions l_names i l_salaries.
  4. Processament de les dades: Un bucle FOR recorre les col·leccions i imprimeix els noms i salaris.

Exercicis Pràctics

Exercici 1: Recollida massiva bàsica

Descripció: Escriu un bloc PL/SQL que utilitzi BULK COLLECT per carregar les dades de les columnes department_id i department_name de la taula departments en col·leccions PL/SQL i imprimeixi els resultats.

Solució:

DECLARE
    TYPE t_dept_id IS TABLE OF departments.department_id%TYPE;
    TYPE t_dept_name IS TABLE OF departments.department_name%TYPE;
    
    l_dept_ids t_dept_id;
    l_dept_names t_dept_name;
BEGIN
    SELECT department_id, department_name
    BULK COLLECT INTO l_dept_ids, l_dept_names
    FROM departments;
    
    FOR i IN 1..l_dept_ids.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE('Department ID: ' || l_dept_ids(i) || ', Department Name: ' || l_dept_names(i));
    END LOOP;
END;
/

Exercici 2: Recollida massiva amb condicions

Descripció: Escriu un bloc PL/SQL que utilitzi BULK COLLECT per carregar les dades de les columnes employee_id i last_name de la taula employees on el salari sigui superior a 5000 en col·leccions PL/SQL i imprimeixi els resultats.

Solució:

DECLARE
    TYPE t_emp_id IS TABLE OF employees.employee_id%TYPE;
    TYPE t_last_name IS TABLE OF employees.last_name%TYPE;
    
    l_emp_ids t_emp_id;
    l_last_names t_last_name;
BEGIN
    SELECT employee_id, last_name
    BULK COLLECT INTO l_emp_ids, l_last_names
    FROM employees
    WHERE salary > 5000;
    
    FOR i IN 1..l_emp_ids.COUNT LOOP
        DBMS_OUTPUT.PUT_LINE('Employee ID: ' || l_emp_ids(i) || ', Last Name: ' || l_last_names(i));
    END LOOP;
END;
/

Errors Comuns i Consells

Errors Comuns

  • Desbordament de memòria: La recollida massiva pot consumir molta memòria si es carreguen grans volums de dades. Utilitza límits (LIMIT) per controlar la quantitat de dades carregades en cada operació.
  • Manca de gestió d'excepcions: Assegura't de gestionar les excepcions per evitar que el programa falli en cas d'errors inesperats.

Consells

  • Utilitza límits: Per evitar desbordaments de memòria, utilitza la clàusula LIMIT amb BULK COLLECT.
  • Processament en lots: Divideix les operacions de recollida massiva en lots més petits per millorar l'eficiència i la gestió de memòria.
DECLARE
    TYPE t_name IS TABLE OF employees.name%TYPE;
    TYPE t_salary IS TABLE OF employees.salary%TYPE;
    
    l_names t_name;
    l_salaries t_salary;
    CURSOR c_employees IS SELECT name, salary FROM employees;
BEGIN
    OPEN c_employees;
    LOOP
        FETCH c_employees BULK COLLECT INTO l_names, l_salaries LIMIT 100;
        EXIT WHEN l_names.COUNT = 0;
        
        FOR i IN 1..l_names.COUNT LOOP
            DBMS_OUTPUT.PUT_LINE('Nom: ' || l_names(i) || ', Salari: ' || l_salaries(i));
        END LOOP;
    END LOOP;
    CLOSE c_employees;
END;
/

Conclusió

La recollida massiva és una tècnica essencial per optimitzar el rendiment de les aplicacions PL/SQL que treballen amb grans volums de dades. Mitjançant l'ús de BULK COLLECT, pots reduir significativament el temps d'execució i la càrrega de xarxa, alhora que mantens el codi net i fàcil de mantenir. Practica amb els exercicis proporcionats per dominar aquesta tècnica i aplicar-la de manera efectiva en els teus projectes.

© Copyright 2024. Tots els drets reservats