Funkce plpgsql automaticky běží uvnitř transakce. Všechno se to podaří nebo všechno selže. Manuál:
Funkce a spouštěcí procedury se vždy provádějí v rámci transakce vytvořené vnějším dotazem — nemohou tuto transakci spustit nebo potvrdit, protože by pro ně neexistoval žádný kontext, v němž by se mohly spustit. Blok obsahující
EXCEPTION
clauseeffectively tvoří dílčí transakci, kterou lze vrátit zpět, aniž by to ovlivnilo vnější transakci. Více o tom viz Sekce 42.6.6.
Pokud tedy potřebujete, můžete zachytit výjimku, která by teoreticky mohla nastat (ale je velmi nepravděpodobná).
Podrobnosti o zachycení chyb v příručce.
Vaše funkce zkontrolována a zjednodušena:
CREATE FUNCTION foo(v_weather text
, v_timeofday text
, v_speed text
, v_behavior text)
RETURNS SETOF custombehavior
LANGUAGE plpgsql AS
$func$
BEGIN
DELETE FROM custombehavior
WHERE weather = 'RAIN'
AND timeofday = 'NIGHT'
AND speed = '45MPH';
INSERT INTO custombehavior (weather, timeofday, speed, behavior)
SELECT v_weather, v_timeofday, v_speed, v_behavior
WHERE NOT EXISTS (
SELECT FROM defaultbehavior
WHERE a = 'RAIN'
AND b = 'NIGHT'
AND c = '45MPH'
);
RETURN QUERY
SELECT * FROM custombehavior WHERE ... ;
END
$func$;
Pokud skutečně potřebujete zahájit/ukončit transakce jak je uvedeno v nadpisu, podívejte se na postupy SQL v Postgres 11 nebo novějším (CREATE PROCEDURE
). Viz:
- Jaký je v PostgreSQL rozdíl mezi „uloženou procedurou“ a jinými typy funkcí?