En plpgsql funktion körs automatiskt i en transaktion. Allt lyckas eller så misslyckas det. Manualen:
Funktioner och triggerprocedurer exekveras alltid inom en transaktion som upprättats av en yttre fråga — de kan inte starta eller utföra den transaktionen, eftersom det inte skulle finnas något sammanhang för dem att exekvera i. Men ett block som innehåller en
EXCEPTION
klausul bildar i praktiken en deltransaktion som kan återställas utan att påverka den yttre transaktionen. För mer om det, se avsnitt 42.6.6.
Så om du behöver kan du fånga ett undantag som teoretiskt sett kan inträffa (men är mycket osannolikt).
Detaljer om fällningsfel i manualen.
Din funktion granskad och förenklad:
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$;
Om du verkligen behöver börja/avsluta transaktioner som anges i rubriken titta på SQL procedurer i Postgres 11 eller senare (CREATE PROCEDURE
). Se:
- Vad är skillnaden mellan en "Lagrad procedur" och andra typer av funktioner i PostgreSQL?