CodeGym /Corsi /SQL SELF /Uso dei cicli: LOOP, FOR, WHILE in PL/pgSQL

Uso dei cicli: LOOP, FOR, WHILE in PL/pgSQL

SQL SELF
Livello 51 , Lezione 1
Disponibile

I cicli ti permettono di eseguire un blocco di codice più volte di fila, finché si verifica una certa condizione oppure mentre fai un'iterazione su un set di dati. È super utile per automatizzare task, lavorare con grandi quantità di dati o fare operazioni ripetitive.

Immagina di dover dare le caramelle a mano a tutti i bambini di un gruppo. Sarebbe un casino! Invece puoi semplicemente scorrere la lista dei bambini e dare una caramella a ciascuno, uno dopo l'altro. In questo scenario, lo "scorrere la lista" è proprio un ciclo.

In PostgreSQL ci sono diversi tipi di cicli:

  1. LOOP — ciclo universale che va avanti finché non lo fermi esplicitamente.
  2. FOR — ciclo con un numero definito di iterazioni su un range di numeri o sul risultato di una query.
  3. WHILE — ciclo che continua finché la condizione è vera.

Dai, vediamo ogni tipo uno per uno.

Ciclo infinito: LOOP

LOOP è la forma base del ciclo in PL/pgSQL, che ripete l'esecuzione di un blocco di codice. Questo ciclo va avanti all'infinito, e devi fermarlo manualmente con il comando EXIT.

Sintassi:

LOOP
    -- Il tuo codice qui
END LOOP;

Ecco un esempio. Calcoliamo la somma dei numeri da 1 a 10 usando LOOP:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    LOOP
        sum := sum + counter; -- aggiungiamo il valore attuale del contatore
        counter := counter + 1; -- aumentiamo il contatore

        -- Fermiamo il ciclo se il contatore è maggiore di 10
        IF counter > 10 THEN
            EXIT;
        END IF;
    END LOOP;

    RAISE NOTICE 'Somma dei numeri da 1 a 10: %', sum;
END $$;
  1. La variabile counter viene incrementata a ogni iterazione.
  2. La condizione IF counter > 10 THEN EXIT; ferma il ciclo quando il contatore supera 10.
  3. Alla fine viene stampata la somma dei numeri.

Ciclo su un range o su un set di dati: FOR

Il secondo tipo di ciclo, FOR, si usa per iterare su:

  1. Un range di numeri.
  2. Il risultato di una query SQL.

Ciclo su un range di numeri

Sintassi:

FOR variable IN [REVERSE] start..end LOOP
    -- Il tuo codice qui
END LOOP;

Stampiamo i numeri da 1 a 5:

DO $$
BEGIN
    FOR i IN 1..5 LOOP
        RAISE NOTICE 'Valore attuale: %', i;
    END LOOP;
END $$;

Esempio con ordine inverso:

DO $$
BEGIN
    FOR i IN REVERSE 5..1 LOOP
        RAISE NOTICE 'Ordine inverso: %', i;
    END LOOP;
END $$;

Ciclo sul risultato di una query SQL

Questa variante è utile per lavorare sulle righe di una tabella.

Sintassi:

FOR variable IN QUERY (SELECT ...) LOOP
    -- Il tuo codice qui
END LOOP;

Ecco un esempio di iterazione sulle righe della tabella students:

DO $$
DECLARE
    student_name TEXT;
BEGIN
    FOR student_name IN QUERY (SELECT name FROM students) LOOP
        RAISE NOTICE 'Ciao, %!', student_name;
    END LOOP;
END $$;

Ciclo condizionale: WHILE

WHILE viene eseguito finché la condizione specificata è vera.

Sintassi:

WHILE condizione LOOP
    -- Il tuo codice qui
END LOOP;

Calcoliamo la somma dei numeri da 1 a 10 usando WHILE:

DO $$
DECLARE
    counter INT := 1;
    sum INT := 0;
BEGIN
    WHILE counter <= 10 LOOP
        sum := sum + counter;
        counter := counter + 1;
    END LOOP;

    RAISE NOTICE 'Somma dei numeri da 1 a 10: %', sum;
END $$;

Esempi dalla vita reale

Ora che abbiamo capito le basi dei cicli, vediamo qualche esempio pratico di come usarli.

Esempio 1: generazione della tabella pitagorica

DO $$
DECLARE
    i INT;
    j INT;
BEGIN
    FOR i IN 1..5 LOOP
        FOR j IN 1..5 LOOP
            RAISE NOTICE '% x % = %', i, j, i * j;
        END LOOP;
    END LOOP;
END $$;

Esempio 2: iterazione sui risultati di una query. Supponiamo di avere una tabella products con i campi id e price. Aggiorniamo tutti i prezzi aumentandoli del 10%.

DO $$
DECLARE
    prod RECORD;
BEGIN
    FOR prod IN QUERY (SELECT id, price FROM products) LOOP
        UPDATE products
        SET price = prod.price * 1.1
        WHERE id = prod.id;
    END LOOP;
END $$;

Errori tipici e come evitarli

Ciclo infinito in LOOP o WHILE. Se ti dimentichi di aggiungere una condizione di uscita (EXIT o una condizione corretta in WHILE), il ciclo non finirà mai. È un po' come guidare senza freni.

Errore durante l'iterazione sul risultato di una query. Se la struttura dei dati risultanti non è quella che ti aspetti, puoi beccarti un errore nel ciclo FOR IN QUERY.

Query non ottimizzate dentro i cicli. Per esempio, fare un UPDATE a ogni iterazione può rallentare un sacco l'esecuzione. In questi casi, meglio usare una singola query SQL invece di un ciclo.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION