Un par de problemas con la función de activación:
-
Use
IF EXISTS (...) THEN
en lugar de contar todas las ocurrencias. Más rápido, más simple. Ver: -
Una función desencadenante
AFTER
INSERT OR UPDATE
simplemente puede devolverNULL
.RETURN NEW
solo es relevante para activadores llamadosBEFORE
. El manual : -
Comilla simple no balanceada.
-
Como explicó @Pavel , no puede controlar las transacciones desde dentro de una función plpgsql. Cualquier excepción no controlada obliga a que toda la transacción se revierta automáticamente. Entonces, simplemente elimine la
EXCEPTION
bloquear.
Tu disparador hipotético reescrito:
CREATE OR REPLACE FUNCTION check_room()
RETURNS TRIGGER AS
$func$
BEGIN
IF EXISTS (
SELECT FROM "Sesion" -- are you sure it's not "Session"?
WHERE "Room_Name" = NEW."Room_Name"
AND "Date" = NEW."Date") THEN
RAISE EXCEPTION 'The room is rented at that date';
END IF;
RETURN NULL;
END
$func$ LANGUAGE plpgsql;
UN BEFORE
disparador tiene más sentido.
Pero a UNIQUE INDEX ON ("Room_Name", "Date")
haría lo mismo, más eficientemente. Luego, cualquier fila en violación genera una excepción de clave duplicada y revierte la transacción (a menos que se detecte y maneje). En Postgres moderno, alternativamente puede omitir o desviar tales INSERT
intentos con INSERT ... ON CONFLICT ...
. Ver:
Uso avanzado: