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 umaEXCEPTION
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?