2016-02-12 4 views
0

Скажите, что у меня есть следующая таблица: http://i.stack.imgur.com/qU3gh.png где sid означает идентификатор моряка и стенд для лодок.PostgreSQL как написать триггер

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

В настоящее время я написал следующий код, но как я новичок в этом, я действительно не знаю, является ли это правильно:

CREATE FUNCTION update() RETURNS TRIGGER AS $logupdate$ 
DECLARE 
judge boolean; 
BEGIN 
judge := EXECUTE ('SELECT starttime,endtime,NEW.starttime,NEW.endtime FROM reserves WHERE bid = NEW.bid AND startdate = NEW.startdate AND (starttime,endtime) overlaps(NEW.starttime,NEW.endtime) IS NULL'); 
IF judge = f THEN RAISE EXCEPTION 'failed due to some reasons'; 
END IF; 
RETURN NEW; 
END; 
$logupdate$ LANGUAGE plpgsql; 

CREATE TRIGGER logupdate 
before UPDATE ON reserves 
FOR EACH ROW 
EXECUTE PROCEDURE update(); 

Как я могу это исправить?

+0

Вам не нужен триггер для этого. Вы можете использовать ограничение исключения: http://www.postgresql.org/docs/current/static/rangetypes.html#RANGETYPES-CONSTRAINT –

+0

Я использую это как триггер, и я действительно удивляюсь, почему триггер не работает , –

ответ

0
  1. Рассмотрите возможность использования поля временной метки вместо отдельных полей даты и времени для простоты. вы можете легко форматировать временную метку в дату или время.

  2. обновление и вставки триггера должны вернуться NEW успеха, или FALSE/NULL

  3. для обеспечения выполнения ограничения с триггером необходимо запустить перед срабатыванием UPDATE, в противном случае строки уже добавлено.

    CREATE TRIGGER logupdate 
    BEFORE UPDATE ON reserves 
    FOR EACH ROW EXECUTE PROCEDURE update(); 
    
    CREATE FUNCTION update() RETURNS TRIGGER AS $$ 
    BEGIN 
        minstart := EXECUTE ('SELECT MAX(endtime) FROM reserves WHERE bid = NEW.bid AND startdate = NEW.startdate') ; 
        IF minstart < NEW.starttime THEN RETURN FALSE; 
        RETURN NEW; 
    END 
    $$ 
    
+0

всякий раз, когда я вставляю неправильный ввод, он все еще вставлен, который не должен происходить. –

+0

см. Наверху, я сделал обновленный код там –

+0

Вам не нужно 'execute()' вы можете просто использовать 'SELECT MAX (endtime) в minstart FROM reserve WHERE bid = NEW.bid AND startdate = NEW. startdate' –

Смежные вопросы