CodeGym /Corsi /SQL SELF /Basi della sintassi di PL/pgSQL

Basi della sintassi di PL/pgSQL

SQL SELF
Livello 49 , Lezione 3
Disponibile

Andiamo a scavare un po’ più a fondo in PL/pgSQL e iniziamo a usarlo sul serio.

Blocco di codice

Un blocco di codice in PL/pgSQL è il mattone fondamentale del linguaggio. Puoi pensarlo come lo scheletro su cui si reggono funzioni, procedure e tutta la magia che ci serve. Il blocco gestisce la logica, l’elaborazione dei dati, la gestione degli errori, tutto dentro un unico “contenitore”.

I blocchi PL/pgSQL sono strutturati e hanno tre parti principali:

  1. DECLARE: dichiarazione delle variabili (opzionale).
  2. BEGIN ... END: il blocco principale dove gira la logica.
  3. EXCEPTION: gestione degli errori (opzionale).

Per chi ama le analogie: pensa a una ricetta di cucina. Anche se la ricetta inizia con la lista degli ingredienti, la vera magia succede durante la preparazione. In termini PL/pgSQL:

  • DECLARE — è la lista degli ingredienti (le variabili).
  • BEGIN ... END — è dove si mescola, si frigge e si bolle.
  • EXCEPTION — è il piano B se qualcosa si brucia.

Sintassi di un blocco PL/pgSQL

Prima guardiamo la struttura generale del blocco, tipo lo “scheletro”. Poi ci mettiamo la carne (o il formaggio veg, se preferisci) — cioè la logica vera e propria.

DO $$
DECLARE
    -- Qui si dichiarano le variabili
    student_count INT;
BEGIN
    -- Qui va la logica
    SELECT COUNT(*) INTO student_count FROM students;
    RAISE NOTICE 'Numero totale di studenti: %', student_count;
EXCEPTION
    -- Qui si gestiscono gli errori
    WHEN OTHERS THEN
        RAISE NOTICE 'Si è verificato un errore.';
END;
$$;

Vediamo passo passo cosa succede qui.

  1. DECLARE — qui dichiariamo le nostre variabili. La cosa bella è che PL/pgSQL supporta quasi tutti i tipi di dato di PostgreSQL — dai semplici INTEGER ai più esotici JSONB. Per dichiarare una variabile, basta scrivere il nome, il tipo di dato e, se vuoi, un valore iniziale.

Esempio:

DECLARE
    student_name TEXT;    -- Variabile per il nome dello studente
    course_count INT := 0; -- Impostiamo il valore iniziale a 0
    is_graduated BOOLEAN; -- Variabile booleana

Nota che le variabili possono essere inizializzate (come course_count) oppure no.

  1. BEGIN ... END — il blocco principale di esecuzione.

Questa parte del blocco si occupa della logica vera e propria. Qui puoi:

  • Eseguire query SQL (SELECT, INSERT, ecc.).
  • Manipolare i dati.
  • Usare strutture di controllo (IF, LOOP, ecc.).
  • Stampare messaggi di debug con RAISE.

Esempio:

BEGIN
    SELECT COUNT(*) INTO student_count FROM students;
    IF student_count > 0 THEN
        RAISE NOTICE 'Abbiamo degli studenti!';
    ELSE
        RAISE NOTICE 'Nessuno studente trovato.';
    END IF;
END;
  1. EXCEPTION — gestione degli errori (opzionale).

Se durante l’esecuzione del blocco succede un errore, la sezione EXCEPTION ti permette di intercettarlo e fare qualcosa di utile — tipo stampare un messaggio o eseguire codice alternativo.

Esempio:

BEGIN
    SELECT COUNT(*) INTO student_count FROM non_existing_table; -- Errore!
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE 'Ops, qualcosa è andato storto!';
END;

Esempio reale: conteggio degli studenti

Ora mettiamo tutto insieme in un esempio che può tornare utile davvero. Scriviamo un blocco PL/pgSQL che conta quanti studenti ci sono nella tabella students e stampa un messaggio.

DO $$
DECLARE
    total_students INT; -- Variabile per il numero di studenti
BEGIN
    -- Contiamo il numero di studenti
    SELECT COUNT(*) INTO total_students FROM students;

    -- Stampiamo il messaggio col risultato
    RAISE NOTICE 'Numero di studenti: %', total_students;
EXCEPTION
    -- Gestiamo eventuali errori, tipo se la tabella non esiste
    WHEN OTHERS THEN
        RAISE NOTICE 'Si è verificato un errore durante il conteggio degli studenti.';
END;
$$;

L’esecuzione di questo blocco stampa un messaggio in console. Tipo: Numero di studenti: 42.

Particolarità nell’uso delle variabili

Vediamo qualche punto importante:

Assegnare valori alle variabili. Per mettere dati in una variabile, puoi usare l’operatore SELECT INTO:

SELECT COUNT(*) INTO total_students FROM students;

Inizializzazione delle variabili. Se non assegni un valore alla variabile quando la dichiari, il suo valore di default sarà NULL.

Esempio:

DECLARE
    my_var INT; -- Valore NULL

Variabili di tipo RECORD. Questo è un tipo di variabile universale, dove puoi mettere una riga di una tabella. Esempio:

DECLARE
    student RECORD;
BEGIN
    SELECT * INTO student FROM students WHERE id = 1;
    RAISE NOTICE 'Nome studente: %, Età: %', student.name, student.age;
END;

Esempio: conteggio dei corsi per uno studente

Ora risolviamo un problema pratico: contare quanti corsi sono iscritti a uno studente e stampare il risultato.

DO $$
DECLARE
    student_id INT := 1;   -- ID dello studente
    course_count INT;      -- Variabile per il numero di corsi
BEGIN
    -- Contiamo il numero di corsi
    SELECT COUNT(*) INTO course_count
    FROM enrollments
    WHERE student_id = student_id;

    -- Stampiamo il messaggio
    RAISE NOTICE 'Lo studente con ID % è iscritto a % corsi.', student_id, course_count;
EXCEPTION
    WHEN OTHERS THEN
        RAISE NOTICE 'Si è verificato un errore durante l\'elaborazione dello studente ID %', student_id;
END;
$$;

Questo blocco è flessibile: puoi cambiare student_id per vedere quanti corsi sono iscritti studenti diversi.

Errori e come evitarli

Se dentro di te PL/pgSQL sta già saltando come un hot dog nel microonde, tranquillo. All’inizio è normale beccarsi i “classici” errori. Ecco qualche esempio:

Dimenticare di dichiarare una variabile. Se ti scordi di dichiarare una variabile con DECLARE, PL/pgSQL ti dirà che la variabile “non esiste”.

Usare NULL come valore. Se la variabile è dichiarata ma non ha un valore, sarà NULL. Questo può portare a comportamenti strani. Esempio:

IF my_var = NULL THEN -- NON funziona!

Usa IS NULL:

IF my_var IS NULL THEN

Uso sbagliato della sezione EXCEPTION. A volte i programmatori intercettano tutti gli errori (WHEN OTHERS), ma non scrivono cosa fare. Così rischi di nascondere il vero problema. Meglio stampare un messaggio d’errore:

RAISE NOTICE 'Errore: %', SQLERRM;
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION