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 FUNCTIONverifică doar sintaxa, nu și existența tabelelor. - Scrii
SELECT ... INTOpentru 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.