PostgreSQL如何编写触发器

时间:2016-02-12 15:35:22

标签: postgresql

说我有这样的下表: http://i.stack.imgur.com/qU3gh.png 其中sid代表水手ID,而竞标代表船ID。

我想写一个触发器和一个函数来检测新输入是否无效。看看桌子,第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();

我该如何纠正?

1 个答案:

答案 0 :(得分:0)

  1. 为简单起见,请考虑使用时间戳字段而不是单独的日期和时间字段。您可以轻松地将时间戳格式化为日期或时间。

  2. 更新和插入触发器必须在成功时返回NEW,否则为FALSE / NULL

  3. 为了使用触发器强制执行约束,您必须运行BEFORE 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
    $$