2017-02-04 38 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

以下触发函数遵循指定的逻辑。这又可以进一步优化(你其实并不需要查询),但我认为这方面它更易于理解:

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 ; 

这是如何将此功能与“之前”触发相关联的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