Няколко проблема с вашата тригерна функция:
-
Използвайте
IF EXISTS (...) THENвместо да брои всички събития. По-бързо, по-лесно. Вижте: -
Задействаща функция
AFTERINSERT OR UPDATEможе просто да върнеNULL.RETURN NEWе подходящ само за задействания, наречениBEFORE. Ръководството : -
Небалансирани единични кавички.
-
Както @Pavel обясни , не можете да контролирате транзакции от plpgsql функция. Всяко необработено изключение принуждава цялата ви транзакция да бъде върната автоматично. Така че просто премахнете
EXCEPTIONблокирай.
Вашият хипотетичен тригер е пренаписан:
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;
A BEFORE задействането има повече смисъл.
Но a UNIQUE INDEX ON ("Room_Name", "Date") би направил същото, по-ефективно. След това всеки ред в нарушение предизвиква изключение за дублиран ключ и връща обратно транзакцията (освен ако не бъде уловен и обработен). В съвременния Postgres можете алтернативно да пропуснете или отклоните такъв INSERT опити с INSERT ... ON CONFLICT ... . Вижте:
Разширено използване: