Няколко проблема с вашата тригерна функция:
-
Използвайте
IF EXISTS (...) THEN
вместо да брои всички събития. По-бързо, по-лесно. Вижте: -
Задействаща функция
AFTER
INSERT 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 ...
. Вижте:
Разширено използване: