DO (bloc anonim) în PostgreSQL

Rulează o singură dată un bloc de cod PL/pgSQL, fără să creeze o funcție. Util pentru scripturi de întreținere și migrări.

Sintaxă SQL
DO [LANGUAGE plpgsql] $$
DECLARE
    ...
BEGIN
    ...
END
$$;

Ce face DO (bloc anonim)

DO execută cod procedural pe loc: variabile, bucle, condiții, SQL dinamic. Nu rămâne nimic salvat în baza de date, spre deosebire de CREATE FUNCTION.

Blocul nu primește parametri și nu returnează rezultate. Pentru a afișa informații folosește RAISE NOTICE; mesajele apar în psql înainte de confirmarea DO.

Cazuri tipice: migrări care trebuie să verifice o condiție înainte (IF NOT EXISTS ... THEN ALTER TABLE ...), acordarea de drepturi pe multe tabele, crearea partițiilor pe un an întreg.

Parametri

Parametru Descriere
LANGUAGE Limbajul blocului; implicit plpgsql.
$$ ... $$ Codul blocului, cu aceleași reguli ca în corpul unei funcții PL/pgSQL.

Ce returnează

Mesajul DO (plus eventualele mesaje NOTICE).

Exemple

Exemplul 1: Afișarea unei statistici

DO $$
DECLARE
    n integer;
BEGIN
    SELECT count(*) INTO n FROM clienti WHERE oras = 'Iași';
    RAISE NOTICE 'Clienți din Iași: %', n;
END
$$;

Rezultat în psql

NOTICE:  Clienți din Iași: 3
DO

Exemplul 2: Migrare care rulează doar dacă e nevoie

DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'status_comanda') THEN
        CREATE TYPE status_comanda AS ENUM ('noua', 'platita', 'livrata');
        RAISE NOTICE 'Tip creat';
    ELSE
        RAISE NOTICE 'Tipul există deja';
    END IF;
END
$$;

Rezultat în psql

NOTICE:  Tipul există deja
DO

Exemplul 3: Partiții pentru fiecare lună din 2027

DO $$
DECLARE
    luna date;
BEGIN
    FOR luna IN SELECT generate_series(date '2027-01-01', date '2027-12-01', interval '1 month') LOOP
        EXECUTE format(
            'CREATE TABLE IF NOT EXISTS %I PARTITION OF comenzi FOR VALUES FROM (%L) TO (%L)',
            'comenzi_' || to_char(luna, 'YYYY_MM'), luna, luna + interval '1 month'
        );
    END LOOP;
END
$$;

Rezultat în psql

DO

Greșeli frecvente

  • Încerci să returnezi un rezultat cu RETURN valoare sau SELECT: un bloc DO nu returnează nimic. Un SELECT fără INTO dă eroare (query has no destination for result data); folosește PERFORM sau SELECT ... INTO.
  • Scrii textul blocului între apostrofuri în loc de $$ și trebuie să dublezi toate apostrofurile din cod. Folosește dollar quoting.

Comenzi înrudite

  • CREATE FUNCTION (LANGUAGE plpgsql): Creează o funcție în PL/pgSQL, limbajul procedural al PostgreSQL: variabile, IF, bucle, tratarea erorilor.
  • RAISE și EXCEPTION (PL/pgSQL): RAISE afișează mesaje sau oprește codul cu o eroare; blocul EXCEPTION prinde erorile și le tratează.
  • format: Construiește un text dintr-un șablon cu %s, %I și %L. Este modul sigur de a crea SQL dinamic în PL/pgSQL.
  • CREATE PROCEDURE și CALL: O procedură este ca o funcție, dar se apelează cu CALL și poate face COMMIT sau ROLLBACK în interior, de exemplu pentru prelucrări pe loturi.