CodeGym /Corsi /SQL SELF /Interazione tra funzioni e procedure

Interazione tra funzioni e procedure

SQL SELF
Livello 55, Lezione 1
Disponibile

Qualche livello fa abbiamo già accennato a funzioni e procedure in PostgreSQL. Ora è il momento di approfondire un po’ di più.

Funzioni e procedure possono lavorare in modo indipendente, ma spesso la loro interazione determina il successo dell’intero sistema. Il bello è che puoi chiamare una funzione dall’altra, passare dati e persino ottenere il risultato dell’esecuzione.

Funzioni vs Procedure: qual è la differenza?

Facciamo un ripasso veloce su cosa distingue le funzioni dalle procedure in PostgreSQL:

  • Funzioni (FUNCTION):

    • Restituiscono valori.
    • Si possono usare dentro SELECT.
    • Spesso servono per calcoli o trasformazioni di dati.
  • Procedure (PROCEDURE):

    • Non restituiscono valori direttamente.
    • Si usano per operazioni come inserimento, aggiornamento o cancellazione di dati.
    • Si chiamano con il comando CALL.

Passaggio di dati tra funzioni

Andando sul pratico, partiamo da un esempio base di passaggio dati tra funzione e procedura. In sostanza, i dati tra funzioni si passano tramite parametri e valori di ritorno.

Ecco come si chiama una funzione dentro un’altra funzione:

CREATE OR REPLACE FUNCTION get_student_name(student_id INT)
RETURNS TEXT AS $$
DECLARE
    student_name TEXT;
BEGIN
    -- Prendiamo il nome dello studente tramite il suo ID
    SELECT name INTO student_name FROM students WHERE id = student_id;

    -- Restituiamo il nome
    RETURN student_name;
END;
$$ LANGUAGE plpgsql;

Questa funzione si può chiamare da un’altra funzione:

CREATE OR REPLACE FUNCTION welcome_student(student_id INT)
RETURNS TEXT AS $$
DECLARE
    message TEXT;
BEGIN
    -- Otteniamo il nome dello studente tramite un’altra funzione
    message := 'Benvenuto, ' || get_student_name(student_id) || '!';

    -- Restituiamo il messaggio di benvenuto
    RETURN message;
END;
$$ LANGUAGE plpgsql;
  1. La funzione get_student_name restituisce il nome dello studente tramite il suo identificativo (student_id).
  2. Nell’altra funzione — welcome_student — questo nome viene usato per creare un messaggio di benvenuto.

Nota: L’estrazione dei dati tramite SELECT INTO salva il risultato della query in una variabile PL/pgSQL.

Esempio di chiamata di procedure da funzioni

Vediamo ora come chiamare una procedura da una funzione. Supponiamo di avere una procedura che registra l’orario di accesso di uno studente al sistema:

CREATE OR REPLACE PROCEDURE log_student_entry(student_id INT)
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO log_entries(student_id, entry_time)
    VALUES (student_id, NOW());
END;
$$;

Ora chiamiamo questa procedura da una funzione, dove registriamo l’accesso e restituiamo un messaggio:

CREATE OR REPLACE FUNCTION student_login(student_id INT)
RETURNS TEXT AS $$
BEGIN
    -- Chiamiamo la procedura per il logging
    CALL log_student_entry(student_id);

    -- Restituiamo il messaggio
    RETURN 'Accesso studente registrato con successo.';
END;
$$ LANGUAGE plpgsql;

Esempi pratici di interazione

Esempio 1: calcolo del totale ordine e logging

Immagina di lavorare con un sistema di ordini online. Per calcolare il totale di un ordine hai una funzione:

CREATE OR REPLACE FUNCTION calculate_order_total(order_id INT)
RETURNS NUMERIC AS $$
DECLARE
    total NUMERIC;
BEGIN
    -- Sommiamo tutte le voci dell’ordine
    SELECT SUM(price * quantity) INTO total
    FROM order_items
    WHERE order_id = order_id;

    RETURN total;
END;
$$ LANGUAGE plpgsql;

Per salvare il totale dell’ordine si usa una procedura:

CREATE OR REPLACE PROCEDURE log_order_total(order_id INT, total NUMERIC)
LANGUAGE plpgsql
AS $$
BEGIN
    INSERT INTO order_totals(order_id, total)
    VALUES (order_id, total);
END;
$$;

Ora le colleghiamo insieme:

CREATE OR REPLACE FUNCTION process_order(order_id INT)
RETURNS TEXT AS $$
DECLARE
    total NUMERIC;
BEGIN
    -- Chiamiamo la funzione per calcolare il totale
    total := calculate_order_total(order_id);

    -- Logghiamo il totale tramite la procedura
    CALL log_order_total(order_id, total);

    RETURN 'Ordine processato con successo.';
END;
$$ LANGUAGE plpgsql;

Esempio 2: ottenere il rating massimo dello studente e aggiornare il profilo

Funzione per ottenere il rating massimo:

CREATE OR REPLACE FUNCTION get_highest_rating(student_id INT)
RETURNS INT AS $$
DECLARE
    max_rating INT;
BEGIN
    -- Troviamo il rating massimo dello studente
    SELECT MAX(rating) INTO max_rating
    FROM ratings
    WHERE student_id = student_id;

    RETURN max_rating;
END;
$$ LANGUAGE plpgsql;

Procedura per aggiornare il profilo dello studente:

CREATE OR REPLACE PROCEDURE update_student_profile(student_id INT, max_rating INT)
LANGUAGE plpgsql
AS $$
BEGIN
    UPDATE students
    SET highest_rating = max_rating
    WHERE id = student_id;
END;
$$;

Funzione per chiamare queste operazioni:

CREATE OR REPLACE FUNCTION refresh_student_profile(student_id INT)
RETURNS TEXT AS $$
DECLARE
    max_rating INT;
BEGIN
    -- Otteniamo il rating massimo
    max_rating := get_highest_rating(student_id);

    -- Aggiorniamo il profilo dello studente
    CALL update_student_profile(student_id, max_rating);

    RETURN 'Profilo aggiornato con successo.';
END;
$$ LANGUAGE plpgsql;

Errori tipici nell’interazione

Uno degli errori più comuni è la non corrispondenza dei tipi di dato tra funzione e procedura. Ad esempio, se la tua procedura si aspetta un parametro di tipo NUMERIC, ma tu passi un INTEGER, PostgreSQL segnalerà un errore di tipo. Controlla sempre che i tipi coincidano.

Un altro errore è la chiamata ciclica tra funzioni, quando la funzione A chiama la funzione B, che a sua volta richiama A. Questo porta a chiamate infinite e crash del sistema.

Importanza pratica

Perché ci serve questa interazione? Nella vita reale funzioni e procedure sono come “mattoncini” di sistemi complessi. Permettono di dividere il codice in parti indipendenti, facilitando il debug, il riutilizzo e i test. Ad esempio:

  • Al colloquio potrebbero chiederti di scrivere una funzione che chiama una procedura per eseguire un’operazione complessa. Dimostrare queste skill pratiche è un bel punto a favore.
  • Nello sviluppo di applicazioni reali, come e-commerce, sistemi di logging o CRM, saper organizzare bene la logica tramite l’interazione tra funzioni e procedure rende il codice molto più semplice.

Per approfondire l’interazione tra funzioni e procedure puoi dare un’occhiata alla documentazione ufficiale di PL/pgSQL.

2
Compito
SQL SELF, livello 55, lezione 1
Bloccato
Aggiornamento del profilo studente in base al rating
Aggiornamento del profilo studente in base al rating
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION