En aquesta secció, explorarem diversos estudis de cas que il·lustren com PL/SQL es pot utilitzar per resoldre problemes del món real. Aquests exemples pràctics t'ajudaran a comprendre millor com aplicar els conceptes apresos al llarg del curs en situacions reals.
Estudi de cas 1: Gestió d'inventari
Descripció del problema
Una empresa de comerç electrònic necessita gestionar el seu inventari de productes. Volen una solució que permeti:
- Actualitzar les quantitats de productes en estoc.
- Registrar les vendes i les devolucions.
- Generar informes d'inventari.
Solució amb PL/SQL
Estructura de la base de dades
CREATE TABLE productes (
    id_producte NUMBER PRIMARY KEY,
    nom_producte VARCHAR2(100),
    quantitat_en_estoc NUMBER
);
CREATE TABLE vendes (
    id_venda NUMBER PRIMARY KEY,
    id_producte NUMBER,
    quantitat_venda NUMBER,
    data_venda DATE,
    FOREIGN KEY (id_producte) REFERENCES productes(id_producte)
);
CREATE TABLE devolucions (
    id_devolucio NUMBER PRIMARY KEY,
    id_producte NUMBER,
    quantitat_devolucio NUMBER,
    data_devolucio DATE,
    FOREIGN KEY (id_producte) REFERENCES productes(id_producte)
);Procediment per actualitzar l'inventari
CREATE OR REPLACE PROCEDURE actualitzar_inventari (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    UPDATE productes
    SET quantitat_en_estoc = quantitat_en_estoc + p_quantitat
    WHERE id_producte = p_id_producte;
END;
/Procediment per registrar una venda
CREATE OR REPLACE PROCEDURE registrar_venda (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    INSERT INTO vendes (id_venda, id_producte, quantitat_venda, data_venda)
    VALUES (vendes_seq.NEXTVAL, p_id_producte, p_quantitat, SYSDATE);
    actualitzar_inventari(p_id_producte, -p_quantitat);
END;
/Procediment per registrar una devolució
CREATE OR REPLACE PROCEDURE registrar_devolucio (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    INSERT INTO devolucions (id_devolucio, id_producte, quantitat_devolucio, data_devolucio)
    VALUES (devolucions_seq.NEXTVAL, p_id_producte, p_quantitat, SYSDATE);
    actualitzar_inventari(p_id_producte, p_quantitat);
END;
/Generació d'informes d'inventari
CREATE OR REPLACE PROCEDURE generar_informe_inventari IS
    CURSOR c_productes IS
        SELECT id_producte, nom_producte, quantitat_en_estoc
        FROM productes;
BEGIN
    FOR r_producte IN c_productes LOOP
        DBMS_OUTPUT.PUT_LINE('ID Producte: ' || r_producte.id_producte);
        DBMS_OUTPUT.PUT_LINE('Nom Producte: ' || r_producte.nom_producte);
        DBMS_OUTPUT.PUT_LINE('Quantitat en Estoc: ' || r_producte.quantitat_en_estoc);
        DBMS_OUTPUT.PUT_LINE('-----------------------------');
    END LOOP;
END;
/Exercici pràctic
- Crea les taules productes,vendesidevolucionsa la teva base de dades.
- Implementa els procediments actualitzar_inventari,registrar_vendairegistrar_devolucio.
- Insereix alguns productes a la taula productes.
- Registra algunes vendes i devolucions.
- Executa el procediment generar_informe_inventariper veure l'estat actual de l'inventari.
Solució
-- Creació de les taules
CREATE TABLE productes (
    id_producte NUMBER PRIMARY KEY,
    nom_producte VARCHAR2(100),
    quantitat_en_estoc NUMBER
);
CREATE TABLE vendes (
    id_venda NUMBER PRIMARY KEY,
    id_producte NUMBER,
    quantitat_venda NUMBER,
    data_venda DATE,
    FOREIGN KEY (id_producte) REFERENCES productes(id_producte)
);
CREATE TABLE devolucions (
    id_devolucio NUMBER PRIMARY KEY,
    id_producte NUMBER,
    quantitat_devolucio NUMBER,
    data_devolucio DATE,
    FOREIGN KEY (id_producte) REFERENCES productes(id_producte)
);
-- Procediment per actualitzar l'inventari
CREATE OR REPLACE PROCEDURE actualitzar_inventari (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    UPDATE productes
    SET quantitat_en_estoc = quantitat_en_estoc + p_quantitat
    WHERE id_producte = p_id_producte;
END;
/
-- Procediment per registrar una venda
CREATE OR REPLACE PROCEDURE registrar_venda (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    INSERT INTO vendes (id_venda, id_producte, quantitat_venda, data_venda)
    VALUES (vendes_seq.NEXTVAL, p_id_producte, p_quantitat, SYSDATE);
    actualitzar_inventari(p_id_producte, -p_quantitat);
END;
/
-- Procediment per registrar una devolució
CREATE OR REPLACE PROCEDURE registrar_devolucio (
    p_id_producte IN NUMBER,
    p_quantitat IN NUMBER
) IS
BEGIN
    INSERT INTO devolucions (id_devolucio, id_producte, quantitat_devolucio, data_devolucio)
    VALUES (devolucions_seq.NEXTVAL, p_id_producte, p_quantitat, SYSDATE);
    actualitzar_inventari(p_id_producte, p_quantitat);
END;
/
-- Generació d'informes d'inventari
CREATE OR REPLACE PROCEDURE generar_informe_inventari IS
    CURSOR c_productes IS
        SELECT id_producte, nom_producte, quantitat_en_estoc
        FROM productes;
BEGIN
    FOR r_producte IN c_productes LOOP
        DBMS_OUTPUT.PUT_LINE('ID Producte: ' || r_producte.id_producte);
        DBMS_OUTPUT.PUT_LINE('Nom Producte: ' || r_producte.nom_producte);
        DBMS_OUTPUT.PUT_LINE('Quantitat en Estoc: ' || r_producte.quantitat_en_estoc);
        DBMS_OUTPUT.PUT_LINE('-----------------------------');
    END LOOP;
END;
/Estudi de cas 2: Gestió de reserves d'hotel
Descripció del problema
Un hotel necessita un sistema per gestionar les reserves de les habitacions. El sistema ha de permetre:
- Registrar noves reserves.
- Cancel·lar reserves.
- Generar informes de reserves.
Solució amb PL/SQL
Estructura de la base de dades
CREATE TABLE habitacions (
    id_habitacio NUMBER PRIMARY KEY,
    tipus_habitacio VARCHAR2(50),
    preu_per_nit NUMBER
);
CREATE TABLE reserves (
    id_reserva NUMBER PRIMARY KEY,
    id_habitacio NUMBER,
    data_inici DATE,
    data_fi DATE,
    client_nom VARCHAR2(100),
    client_email VARCHAR2(100),
    FOREIGN KEY (id_habitacio) REFERENCES habitacions(id_habitacio)
);Procediment per registrar una reserva
CREATE OR REPLACE PROCEDURE registrar_reserva (
    p_id_habitacio IN NUMBER,
    p_data_inici IN DATE,
    p_data_fi IN DATE,
    p_client_nom IN VARCHAR2,
    p_client_email IN VARCHAR2
) IS
BEGIN
    INSERT INTO reserves (id_reserva, id_habitacio, data_inici, data_fi, client_nom, client_email)
    VALUES (reserves_seq.NEXTVAL, p_id_habitacio, p_data_inici, p_data_fi, p_client_nom, p_client_email);
END;
/Procediment per cancel·lar una reserva
CREATE OR REPLACE PROCEDURE cancel·lar_reserva (
    p_id_reserva IN NUMBER
) IS
BEGIN
    DELETE FROM reserves
    WHERE id_reserva = p_id_reserva;
END;
/Generació d'informes de reserves
CREATE OR REPLACE PROCEDURE generar_informe_reserves IS
    CURSOR c_reserves IS
        SELECT id_reserva, id_habitacio, data_inici, data_fi, client_nom, client_email
        FROM reserves;
BEGIN
    FOR r_reserva IN c_reserves LOOP
        DBMS_OUTPUT.PUT_LINE('ID Reserva: ' || r_reserva.id_reserva);
        DBMS_OUTPUT.PUT_LINE('ID Habitació: ' || r_reserva.id_habitacio);
        DBMS_OUTPUT.PUT_LINE('Data Inici: ' || r_reserva.data_inici);
        DBMS_OUTPUT.PUT_LINE('Data Fi: ' || r_reserva.data_fi);
        DBMS_OUTPUT.PUT_LINE('Client Nom: ' || r_reserva.client_nom);
        DBMS_OUTPUT.PUT_LINE('Client Email: ' || r_reserva.client_email);
        DBMS_OUTPUT.PUT_LINE('-----------------------------');
    END LOOP;
END;
/Exercici pràctic
- Crea les taules habitacionsireservesa la teva base de dades.
- Implementa els procediments registrar_reservaicancel·lar_reserva.
- Insereix algunes habitacions a la taula habitacions.
- Registra algunes reserves.
- Executa el procediment generar_informe_reservesper veure l'estat actual de les reserves.
Solució
-- Creació de les taules
CREATE TABLE habitacions (
    id_habitacio NUMBER PRIMARY KEY,
    tipus_habitacio VARCHAR2(50),
    preu_per_nit NUMBER
);
CREATE TABLE reserves (
    id_reserva NUMBER PRIMARY KEY,
    id_habitacio NUMBER,
    data_inici DATE,
    data_fi DATE,
    client_nom VARCHAR2(100),
    client_email VARCHAR2(100),
    FOREIGN KEY (id_habitacio) REFERENCES habitacions(id_habitacio)
);
-- Procediment per registrar una reserva
CREATE OR REPLACE PROCEDURE registrar_reserva (
    p_id_habitacio IN NUMBER,
    p_data_inici IN DATE,
    p_data_fi IN DATE,
    p_client_nom IN VARCHAR2,
    p_client_email IN VARCHAR2
) IS
BEGIN
    INSERT INTO reserves (id_reserva, id_habitacio, data_inici, data_fi, client_nom, client_email)
    VALUES (reserves_seq.NEXTVAL, p_id_habitacio, p_data_inici, p_data_fi, p_client_nom, p_client_email);
END;
/
-- Procediment per cancel·lar una reserva
CREATE OR REPLACE PROCEDURE cancel·lar_reserva (
    p_id_reserva IN NUMBER
) IS
BEGIN
    DELETE FROM reserves
    WHERE id_reserva = p_id_reserva;
END;
/
-- Generació d'informes de reserves
CREATE OR REPLACE PROCEDURE generar_informe_reserves IS
    CURSOR c_reserves IS
        SELECT id_reserva, id_habitacio, data_inici, data_fi, client_nom, client_email
        FROM reserves;
BEGIN
    FOR r_reserva IN c_reserves LOOP
        DBMS_OUTPUT.PUT_LINE('ID Reserva: ' || r_reserva.id_reserva);
        DBMS_OUTPUT.PUT_LINE('ID Habitació: ' || r_reserva.id_habitacio);
        DBMS_OUTPUT.PUT_LINE('Data Inici: ' || r_reserva.data_inici);
        DBMS_OUTPUT.PUT_LINE('Data Fi: ' || r_reserva.data_fi);
        DBMS_OUTPUT.PUT_LINE('Client Nom: ' || r_reserva.client_nom);
        DBMS_OUTPUT.PUT_LINE('Client Email: ' || r_reserva.client_email);
        DBMS_OUTPUT.PUT_LINE('-----------------------------');
    END LOOP;
END;
/Conclusió
Els estudis de cas presentats mostren com PL/SQL pot ser utilitzat per resoldre problemes reals en diferents contextos. A través de la creació de procediments, funcions i la gestió de dades, PL/SQL proporciona una eina poderosa per desenvolupar aplicacions robustes i eficients. Practicar amb aquests exemples t'ajudarà a consolidar els teus coneixements i a preparar-te per afrontar reptes similars en el teu entorn laboral.
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
