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
- Declaració de tipus de col·lecció: Es declaren dos tipus de col·lecció,
t_nameit_salary, basats en els tipus de dades de les columnesnameisalaryde la taulaemployees. - Declaració de variables de col·lecció: Es declaren dues variables de col·lecció,
l_namesil_salaries, de tipust_nameit_salaryrespectivament. - Recollida massiva: La sentència
SELECTutilitzaBULK COLLECTper carregar totes les files de les columnesnameisalaryen les col·leccionsl_namesil_salaries. - Processament de les dades: Un bucle
FORrecorre 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
LIMITambBULK 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.
Curs de PL/SQL
Mòdul 1: Introducció a PL/SQL
Mòdul 2: Fonaments de PL/SQL
- Estructura del bloc PL/SQL
- Variables i tipus de dades
- Estructures de control
- Cursors
- Gestió d'excepcions
