En aquest tema, explorarem diverses tècniques per optimitzar el codi PL/SQL. L'objectiu és millorar el rendiment i l'eficiència del codi, reduint el temps d'execució i l'ús de recursos. A continuació, es presenten les tècniques clau per a l'optimització del codi PL/SQL.

  1. Utilitzar Cursors Implícits i Explícits de Manera Eficient

Cursors Implícits

Els cursors implícits són creats automàticament per Oracle per a sentències SQL individuals. Són fàcils d'utilitzar però poden ser menys eficients en operacions complexes.

Cursors Explícits

Els cursors explícits són definits pel programador i ofereixen més control sobre el procés de recuperació de dades. Són útils per a operacions que requereixen un control més fi sobre el conjunt de resultats.

Exemple de Cursor Explícit:

DECLARE
    CURSOR emp_cursor IS
        SELECT employee_id, first_name, last_name FROM employees;
    emp_record emp_cursor%ROWTYPE;
BEGIN
    OPEN emp_cursor;
    LOOP
        FETCH emp_cursor INTO emp_record;
        EXIT WHEN emp_cursor%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE(emp_record.first_name || ' ' || emp_record.last_name);
    END LOOP;
    CLOSE emp_cursor;
END;
/

Explicació:

  • DECLARE: Es declara un cursor explícit emp_cursor.
  • OPEN: S'obre el cursor.
  • FETCH: Es recuperen les dades fila per fila.
  • EXIT WHEN: Es surt del bucle quan no hi ha més files.
  • CLOSE: Es tanca el cursor.

  1. Utilitzar la Recollida Massiva (Bulk Collect)

La recollida massiva permet recuperar múltiples files en una sola operació, reduint el nombre de commutacions de context entre PL/SQL i SQL.

Exemple de Recollida Massiva:

DECLARE
    TYPE emp_table_type IS TABLE OF employees%ROWTYPE;
    emp_table emp_table_type;
BEGIN
    SELECT * BULK COLLECT INTO emp_table FROM employees;
    FOR i IN emp_table.FIRST .. emp_table.LAST LOOP
        DBMS_OUTPUT.PUT_LINE(emp_table(i).first_name || ' ' || emp_table(i).last_name);
    END LOOP;
END;
/

Explicació:

  • TYPE: Es defineix un tipus de taula per emmagatzemar les files.
  • BULK COLLECT INTO: Es recuperen totes les files en una sola operació.
  • FOR LOOP: Es processen les files recuperades.

  1. Utilitzar la Sentència FORALL

La sentència FORALL permet executar una operació DML (INSERT, UPDATE, DELETE) en múltiples files amb una sola instrucció, millorant significativament el rendiment.

Exemple de Sentència FORALL:

DECLARE
    TYPE emp_id_table IS TABLE OF employees.employee_id%TYPE;
    emp_ids emp_id_table := emp_id_table(100, 101, 102);
BEGIN
    FORALL i IN emp_ids.FIRST .. emp_ids.LAST
        DELETE FROM employees WHERE employee_id = emp_ids(i);
    COMMIT;
END;
/

Explicació:

  • TYPE: Es defineix un tipus de taula per emmagatzemar els identificadors d'empleats.
  • FORALL: S'executa una operació DELETE per a cada identificador d'empleat en la taula.

  1. Evitar l'ús Innecessari de Cursors

L'ús innecessari de cursors pot degradar el rendiment. Utilitza operacions SQL directes sempre que sigui possible.

Exemple d'Operació SQL Directa:

BEGIN
    UPDATE employees SET salary = salary * 1.1 WHERE department_id = 10;
    COMMIT;
END;
/

Explicació:

  • Es realitza una operació UPDATE directa sense utilitzar un cursor.

  1. Utilitzar la Funció NOCOPY

La funció NOCOPY pot millorar el rendiment passant paràmetres per referència en lloc de per valor, reduint la sobrecàrrega de còpia de dades.

Exemple d'Ús de NOCOPY:

CREATE OR REPLACE PROCEDURE update_salary (p_salary IN OUT NOCOPY NUMBER) IS
BEGIN
    p_salary := p_salary * 1.1;
END;
/

Explicació:

  • IN OUT NOCOPY: El paràmetre p_salary es passa per referència, millorant el rendiment.

Exercicis Pràctics

Exercici 1: Utilitzar Recollida Massiva

Escriu un bloc PL/SQL que utilitzi la recollida massiva per recuperar totes les files de la taula departments i mostri el nom de cada departament.

Solució:

DECLARE
    TYPE dept_table_type IS TABLE OF departments%ROWTYPE;
    dept_table dept_table_type;
BEGIN
    SELECT * BULK COLLECT INTO dept_table FROM departments;
    FOR i IN dept_table.FIRST .. dept_table.LAST LOOP
        DBMS_OUTPUT.PUT_LINE(dept_table(i).department_name);
    END LOOP;
END;
/

Exercici 2: Utilitzar la Sentència FORALL

Escriu un bloc PL/SQL que utilitzi la sentència FORALL per actualitzar el salari de tots els empleats en un conjunt d'identificadors d'empleats.

Solució:

DECLARE
    TYPE emp_id_table IS TABLE OF employees.employee_id%TYPE;
    emp_ids emp_id_table := emp_id_table(100, 101, 102);
BEGIN
    FORALL i IN emp_ids.FIRST .. emp_ids.LAST
        UPDATE employees SET salary = salary * 1.1 WHERE employee_id = emp_ids(i);
    COMMIT;
END;
/

Resum

En aquesta secció, hem explorat diverses tècniques per optimitzar el codi PL/SQL, incloent l'ús eficient de cursors, la recollida massiva, la sentència FORALL, l'evitació de l'ús innecessari de cursors i l'ús de la funció NOCOPY. Aquestes tècniques poden ajudar a millorar significativament el rendiment del teu codi PL/SQL. En el proper tema, explorarem les millors pràctiques per escriure codi PL/SQL eficient i mantenible.

© Copyright 2024. Tots els drets reservats