CREATE FUNCTION (LANGUAGE plpgsql) în PostgreSQL

Creează o funcție în PL/pgSQL, limbajul procedural al PostgreSQL: variabile, IF, bucle, tratarea erorilor.

Sintaxă SQL
CREATE [OR REPLACE] FUNCTION nume(param tip, ...) RETURNS tip
LANGUAGE plpgsql
AS $$
DECLARE
    variabila tip [:= valoare];
BEGIN
    ... instrucțiuni ...
    RETURN valoare;
END
$$;

Ce face CREATE FUNCTION (LANGUAGE plpgsql)

PL/pgSQL adaugă peste SQL ce lipsește pentru logică mai complexă: variabile (DECLARE), condiții (IF ... ELSIF ... ELSE, CASE), bucle (LOOP, WHILE, FOR ... IN SELECT), mesaje (RAISE) și tratarea erorilor (EXCEPTION).

Rezultatul unei interogări se pune într-o variabilă cu SELECT ... INTO variabila. Funcțiile care returnează mai multe rânduri folosesc RETURNS TABLE sau RETURNS SETOF și RETURN QUERY.

Toată funcția rulează în tranzacția celui care o apelează. Dacă vrei COMMIT în mijlocul codului, ai nevoie de o procedură (CREATE PROCEDURE).

Parametri

Parametru Descriere
DECLARE Secțiunea cu variabile: total numeric := 0;.
SELECT ... INTO var Pune rezultatul interogării în variabilă.
IF / ELSIF / ELSE Condiții.
FOR r IN SELECT ... LOOP Parcurge rândurile unei interogări.
RETURN / RETURN QUERY Returnează valoarea, respectiv rândurile unei interogări.

Ce returnează

Mesajul CREATE FUNCTION.

Exemple

Exemplul 1: Categoria unui client după total

CREATE FUNCTION categorie_client(p_client_id integer)
    RETURNS text
    LANGUAGE plpgsql
AS $$
DECLARE
    total_cumparat numeric;
BEGIN
    SELECT coalesce(sum(total), 0) INTO total_cumparat
    FROM comenzi WHERE client_id = p_client_id;

    IF total_cumparat >= 5000 THEN
        RETURN 'aur';
    ELSIF total_cumparat >= 1000 THEN
        RETURN 'argint';
    ELSE
        RETURN 'standard';
    END IF;
END
$$;

SELECT nume, categorie_client(id) FROM clienti ORDER BY id;

Rezultat în psql

CREATE FUNCTION
 nume  | categorie_client 
-------+------------------
 Ana   | aur
 Mihai | standard
 Ioana | argint
(3 rows)

Exemplul 2: Buclă peste rânduri și RETURN QUERY

CREATE FUNCTION produse_de_comandat(p_prag integer)
    RETURNS TABLE (cod text, lipsa integer)
    LANGUAGE plpgsql
AS $$
BEGIN
    RETURN QUERY
        SELECT p.cod, p_prag - p.stoc
        FROM produse p
        WHERE p.stoc < p_prag
        ORDER BY p.stoc;
END
$$;

SELECT * FROM produse_de_comandat(10);

Rezultat în psql

CREATE FUNCTION
   cod    | lipsa 
----------+-------
 LAPTE-01 |    10
 OUA-10   |     7
 PAINE-01 |     2
(3 rows)

Greșeli frecvente

  • Variabilele sau parametrii au același nume ca o coloană: PostgreSQL dă column reference "cod" is ambiguous. Folosește prefixe (p_, v_) și alias-uri de tabel.
  • Uiți că erorile din corpul funcției apar abia la prima rulare: CREATE FUNCTION verifică doar sintaxa, nu și existența tabelelor.
  • Scrii SELECT ... INTO pentru o interogare care poate returna mai multe rânduri: se păstrează doar primul, fără eroare. Adaugă STRICT (INTO STRICT) ca să primești eroare.

Comenzi înrudite

  • CREATE FUNCTION (LANGUAGE sql): Creează o funcție scrisă direct în SQL, pe care o poți folosi apoi în SELECT, WHERE sau în indecși.
  • DO (bloc anonim): 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.
  • RAISE și EXCEPTION (PL/pgSQL): RAISE afișează mesaje sau oprește codul cu o eroare; blocul EXCEPTION prinde erorile și le tratează.
  • CREATE TRIGGER: Rulează automat o funcție la INSERT, UPDATE sau DELETE pe un tabel, de exemplu pentru a completa coloana actualizat_la sau pentru jurnal de audit.
  • 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.