sql >> Databasteknik >  >> RDS >> PostgreSQL

PostgreSQL kan inte påbörja/avsluta transaktioner i PL/pgSQL

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?


  1. PDO anslutningstest

  2. Fel när databas släpps (Kan inte skicka '.test\', felnr:17)

  3. Hur kan jag lista har samma id-data som while loop i PHP?

  4. En dedikerad lagrad procedur för att få den senaste statusen för databassäkerhetskopiering