Un par de problemas con la función de activación:
-
Use
IF EXISTS (...) THENen lugar de contar todas las ocurrencias. Más rápido, más simple. Ver: -
Una función desencadenante
AFTERINSERT OR UPDATEsimplemente puede devolverNULL.RETURN NEWsolo 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
EXCEPTIONbloquear.
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: