PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

PostgreSQL não pode iniciar/terminar transações em PL/pgSQL


Uma função do plpgsql é executado automaticamente dentro de uma transação. Tudo dá certo ou tudo falha. O manual:

Funções e procedimentos de gatilho são sempre executados dentro de uma transação estabelecida por uma consulta externa — eles não podem iniciar ou confirmar essa transação, pois não haveria contexto para eles serem executados. No entanto, um bloco contendo uma EXCEPTION cláusula forma efetivamente uma subtransação que pode ser revertida sem afetar a transação externa. Para saber mais sobre isso, consulte a Seção 42.6.6.

Então, se você precisar, você pode pegar uma exceção que teoricamente pode ocorrer (mas é muito improvável).
Detalhes sobre erros de interceptação no manual.

Sua função revisada e simplificada:
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 você realmente precisar iniciar/terminar transações como indicado no título, procure procedimentos SQL no Postgres 11 ou posterior (CREATE PROCEDURE ). Ver:
  • No PostgreSQL, qual é a diferença entre um “procedimento armazenado” e outros tipos de funções?