2016-12-01 4 views
0

В моем проекте, у меня есть два отношения:
1. Фестиваль (название, дата_начала end_date)
2. событий (название, event_date)

PL/PgSQL Триггеры - Вставка Update только действительные кортежи

Я должен добавить триггер, который проверяет каждый раз, когда новый кортеж вставляется \ обновляется до связи событий, если event_date устанавливаются между датой_начал и датой_окончание в соответствующем фестивале.
Если строка события недействительна, триггер должен поднять уведомление, в противном случае кортеж должен быть вставлен \ обновлен регулярно.
Спусковой я сделал (в PL/PgSQL):

create function trigf() returns trigger as $$ 
begin 
if((NEW.event_date) < (select start_date from festival where festival.title = NEW.title) or 
    (NEW.event_date) > (select end_date from festival where festival.title = NEW.title)) then 
    raise notice 'The new event date is invalid'; 
end if; 
return null; 
end; 
$$language plpgsql; 

create trigger T 
before insert or update on event 
for each row 
    execute procedure trigf(); 

Проблема заключается в том, что моя функция способна обнаружить неверную дату, но не вставляет \ обновления действительных кортежей.
Что мне нужно изменить в триггере для достижения этого?

ответ

0

Вам нужно:

  • raise 'The new event date is invalid' вместо raise notice 'The new event date is invalid', чтобы заставить ошибку на неверную дату вместо того, чтобы просто заметить, что только вошли, а затем игнорируются.
  • return NEW, не return NULL:

на уровне строк триггеров вызываются перед может возвратить нуль, чтобы сигнализировать менеджер триггера, чтобы пропустить остальную часть операции для этой строки (то есть, последующие триггера не обожженными, и INSERT/UPDATE/DELETE не возникает для этой строки).

+0

спасибо! Один вопрос: когда я использую 'raise' вместо 'raise notice', и есть недопустимая строка, все попытки вставки строки отменены, но я просто хочу отменить вставку недопустимой строки. Итак, как я могу это сделать с помощью «рейза»? –

+0

Вы не должны игнорировать ошибки - вам будет жаль. Но если вам действительно нужно, то вы можете просто удалить рейз и сделать 'if ... then return NULL; else return NEW; end if; ' – Tometzky