sql >> Base de Datos >  >> RDS >> PostgreSQL

PostgreSQL no puede comenzar/terminar transacciones en PL/pgSQL

Una función plpgsql se ejecuta automáticamente dentro de una transacción. Todo tiene éxito o todo falla. El manual:

Las funciones y los procedimientos desencadenantes siempre se ejecutan dentro de una transacción establecida por una consulta externa; no pueden iniciar o confirmar esa transacción, ya que no habría contexto para que se ejecuten. Sin embargo, un bloque que contiene una EXCEPTION La cláusula forma efectivamente una subtransacción que se puede deshacer sin afectar la transacción externa. Para obtener más información al respecto, consulte la Sección 42.6.6.

Por lo tanto, si lo necesita, puede detectar una excepción que teóricamente podría ocurrir (pero es muy poco probable).
Detalles sobre la detección de errores en el manual.

Tu función revisada y 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$;

Si realmente necesita comenzar/finalizar transacciones como se indica en el título, mire los procedimientos de SQL en Postgres 11 o posterior (CREATE PROCEDURE ). Ver:

  • En PostgreSQL, ¿cuál es la diferencia entre un "procedimiento almacenado" y otros tipos de funciones?