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?