Ce face CREATE FUNCTION (LANGUAGE sql)
O funcție SQL salvează o expresie sau o interogare sub un nume. Corpul se scrie între $$ (dollar quoting), ca să nu fie nevoie să dublezi apostrofurile din interior. Rezultatul este valoarea ultimei interogări.
Cu RETURNS TABLE funcția returnează mai multe rânduri și se folosește în FROM, ca un tabel. Din PostgreSQL 14 corpul se poate scrie și în stil standard SQL (RETURN expresie sau BEGIN ATOMIC ... END), verificat la creare.
Marcajul de volatilitate ajută planificatorul: IMMUTABLE = același rezultat pentru aceleași argumente, mereu (poate fi folosită în indecși); STABLE = nu modifică date și dă același rezultat într-o interogare; VOLATILE (implicit) = orice altceva.
Parametri
| Parametru | Descriere |
|---|---|
OR REPLACE |
Înlocuiește funcția existentă cu aceeași listă de parametri (tipul returnat nu se poate schimba). |
RETURNS tip |
Tipul valorii returnate; SETOF tip sau RETURNS TABLE (...) pentru mai multe rânduri. |
IMMUTABLE / STABLE / VOLATILE |
Cât de stabil este rezultatul. |
STRICT |
Dacă un argument este NULL, rezultatul este NULL fără să ruleze funcția. |
Ce returnează
Mesajul CREATE FUNCTION.
Exemple
Exemplul 1: Preț cu TVA
CREATE FUNCTION pret_cu_tva(pret numeric)
RETURNS numeric
LANGUAGE sql
IMMUTABLE
RETURN round(pret * 1.21, 2);
SELECT pret_cu_tva(100), pret_cu_tva(5.50);
Rezultat în psql
CREATE FUNCTION
pret_cu_tva | pret_cu_tva
-------------+-------------
121.00 | 6.66
(1 row)
Exemplul 2: Funcție care returnează un tabel
CREATE FUNCTION clienti_din(p_oras text)
RETURNS TABLE (id integer, nume text)
LANGUAGE sql
STABLE
AS $$
SELECT c.id, c.nume FROM clienti c WHERE c.oras = p_oras ORDER BY c.nume;
$$;
SELECT * FROM clienti_din('Iași');
Rezultat în psql
CREATE FUNCTION
id | nume
----+-------
1 | Ana
4 | Ioana
7 | Vlad
(3 rows)
Exemplul 3: Schimbarea tipului returnat
CREATE OR REPLACE FUNCTION pret_cu_tva(pret numeric)
RETURNS text
LANGUAGE sql
RETURN round(pret * 1.21, 2)::text || ' lei';
Rezultat în psql
ERROR: cannot change return type of existing function
HINT: Use DROP FUNCTION pret_cu_tva(numeric) first.
Greșeli frecvente
- Marchezi
IMMUTABLEo funcție care citește din tabele sau foloseștenow(). Rezultatele pot fi greșite, mai ales în indecși. - Dai parametrilor același nume ca și coloanelor (
oras) și interogarea devine ambiguă. Folosește un prefix (p_oras) sau alias de tabel.
Comenzi înrudite
CREATE FUNCTION (LANGUAGE plpgsql): Creează o funcție în PL/pgSQL, limbajul procedural al PostgreSQL: variabile, IF, bucle, tratarea erorilor.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.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.