PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

PostgreSQL kann keine Transaktionen in PL/pgSQL beginnen/beenden

Eine plpgsql Funktion läuft automatisch innerhalb einer Transaktion. Alles gelingt oder alles scheitert. Das Handbuch:

Funktionen und Auslöseprozeduren werden immer innerhalb einer Transaktion ausgeführt, die durch eine äußere Abfrage eingerichtet wurde – sie können diese Transaktion nicht starten oder festschreiben, da es keinen Kontext für ihre Ausführung gäbe. Allerdings enthält ein Block eine EXCEPTION -Klausel bildet effektiv eine Untertransaktion, die rückgängig gemacht werden kann, ohne die äußere Transaktion zu beeinflussen. Weitere Informationen dazu finden Sie in Abschnitt 42.6.6.

Wenn Sie also müssen, können Sie eine Ausnahme abfangen, die theoretisch auftreten könnte (aber sehr unwahrscheinlich ist).
Details zum Abfangen von Fehlern im Handbuch.

Ihre Funktion überprüft und vereinfacht:

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$;

Wenn Sie tatsächlich Transaktionen beginnen/beenden müssen wie im Titel angegeben auf SQL Prozeduren schauen in Postgres 11 oder höher (CREATE PROCEDURE ). Siehe:

  • Was ist in PostgreSQL der Unterschied zwischen einer „gespeicherten Prozedur“ und anderen Arten von Funktionen?