funkcja plpgsql automatycznie uruchamia się wewnątrz transakcji. Wszystko się udaje albo wszystko się nie udaje. Instrukcja:
Funkcje i procedury wyzwalające są zawsze wykonywane w ramach transakcji ustanowionej przez zapytanie zewnętrzne — nie mogą rozpocząć ani zatwierdzić tej transakcji, ponieważ nie byłoby kontekstu, w którym mogłyby zostać wykonane. Jednak blok zawierający EXCEPTION
klauzula skutecznie tworzy podtransakcję, którą można wycofać bez wpływu na transakcję zewnętrzną. Więcej informacji na ten temat znajdziesz w sekcji 42.6.6.
Tak więc, jeśli zajdzie taka potrzeba, możesz złapać wyjątek, który teoretycznie może wystąpić (ale jest bardzo mało prawdopodobny).
Szczegóły dotyczące błędów zalewkowania w instrukcji.
Twoja funkcja sprawdzona i uproszczona:
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$;
Jeśli rzeczywiście musisz rozpocząć/zakończyć transakcje jak wskazano w tytule, spójrz na procedury SQL w Postgres 11 lub nowszym (CREATE PROCEDURE
). Zobacz:
- Jaka jest różnica między „procedurą składowaną” w PostgreSQL a innymi typami funkcji?