2017-02-04 4 views
0

Так что у меня есть проблема с функцией триггера перед вставкой на производительность таблицы.postgresql триггер функция для проверки даты концерта

В таблице производительности У меня есть

id_performance(PK) 
id_performer(foreign key) 
id_concert(FK) 
id_song(FK) 
role (it can be violine, sopran, alt etc) 

В таблице концерта у меня есть:

id(PK), 
name, 
date 
id_location(FK). 

В таблице исполнителя у меня есть:

id(PK), 
FirstName 
LastName. 

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

Вот изображение E-R диаграммы: http://prntscr.com/e4cf92

ответ

0

Следующая функция триггера следует за логикой, как указано. Это может быть futher оптимизировано (вы на самом деле не нужны запросы), но я думаю, что это способы его легче понять:

CREATE FUNCTION check_only_one_concert_per_day() RETURNS trigger AS 
$$ 
DECLARE 
    -- These are two variables used later on 
    _present_concert_date date ; 
    _concert_count_same_date integer ; 
BEGIN 
    -- Check the concert date, and store it in variable 
    -- NOTE that our current concert id is stored in NEW.id_concert, 
    -- the id_concert of the row about to be inserted. 
    SELECT 
     concert.date 
    INTO 
     _present_concert_date 
    FROM 
     concert 
    WHERE 
     concert.id = NEW.id_concert ; 

    -- Check to see how many performances has our performer booked 
    -- for the day of the current concert 
    -- NOTE that the current "performer" is NEW.id_performer 
    SELECT 
     count(*) 
    INTO  
     _concert_count_same_date 
    FROM 
     performance 
     JOIN concert ON concert.id = performance.id_concert 
    WHERE 
      performance.id_performer = NEW.id_performer 
     AND concert.date = _present_concert_date ; 

    -- If the count of concerts is > 0, complain! 
    if _concert_count_same_date > 0 then 
     -- This will raise an exception, and abort current transaction 
     RAISE EXCEPTION 'Cannot have more than one concert per day, already % concert(s) is/are booked for %', _concert_count_same_date, _present_concert_date ; 
     -- As an alternative, a RETURN null could also be possible. 
    end if ; 
    RETURN NEW ; -- If no exception, go on and return the row untouched 
END 
$$ 
LANGUAGE plpgsql ; 

И это, как вы связать эту функцию с «ON ПЕРЕД» триггер на вашем performance стол:

CREATE TRIGGER check_one_concert_per_day 
    BEFORE INSERT 
    ON performance 
    FOR EACH ROW EXECUTE PROCEDURE p.check_only_one_concert_per_day(); 

Вам необходимо проверить следующие части документации, чтобы получить полную картину:

  1. Documentation on triggers
  2. CREATE TRIGGER
  3. Documentation on exceptions
  4. PL/pgSQL language
1

Самый простой способ будет добавить к date спектаклей и использовать constraint впоследствии. Ограничение UNIQUE кажется лучшим.

The UNIQUE constraint uniquely identifies each record in a database table.

этого вам придется добавить ограничение на единственность на id_performer AND date. Таким образом, исполнитель мог бы быть только один раз в день, независимо от того, на каком концерте он будет выступать.

+0

Это действительно самый простой способ, но мой учитель явно любит функцию триггера, и он настаивает на том, что мы делаем это с функцией триггера, и я действительно не знаю, как это сделать что. – carloraics

+0

Еще не видел эту часть моего курса. Вы должны будете ждать кого-то еще, мои извинения. – Faegy

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