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_name
it_salary
, basats en els tipus de dades de les columnesname
isalary
de la taulaemployees
. - Declaració de variables de col·lecció: Es declaren dues variables de col·lecció,
l_names
il_salaries
, de tipust_name
it_salary
respectivament. - Recollida massiva: La sentència
SELECT
utilitzaBULK COLLECT
per carregar totes les files de les columnesname
isalary
en les col·leccionsl_names
il_salaries
. - 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
ambBULK 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