PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

PostgreSQL non può iniziare/terminare transazioni in PL/pgSQL

Una funzione plpgsql viene eseguito automaticamente all'interno di una transazione. Tutto riesce o tutto fallisce. Il manuale:

Le funzioni e le procedure di attivazione vengono sempre eseguite all'interno di una transazione stabilita da una query esterna:non possono avviare o impegnare tale transazione, poiché non ci sarebbe alcun contesto in cui eseguirle. Tuttavia, un blocco contenente un EXCEPTION La clausola costituisce effettivamente una sottotransazione di cui è possibile eseguire il rollback senza influire sulla transazione esterna. Per ulteriori informazioni, vedere la Sezione 42.6.6.

Quindi, se necessario, puoi rilevare un'eccezione che teoricamente potrebbe verificarsi (ma è molto improbabile).
Dettagli sugli errori di intercettazione nel manuale.

La tua funzione rivista e semplificata:

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

Se hai effettivamente bisogno di iniziare/terminare transazioni come indicato nel titolo, guarda alle procedure di SQL in Postgres 11 o successivo (CREATE PROCEDURE ). Vedi:

  • In PostgreSQL, qual è la differenza tra una "Stored Procedure" e altri tipi di funzioni?