【问题标题】:EXCEPTION not raised in trigger function triggered on DELETE FROM (postgresql 13)在 DELETE FROM 上触发的触发器函数中未引发异常(postgresql 13)
【发布时间】:2020-12-15 10:23:23
【问题描述】:

我有两张桌子:

CREATE TABLE Registered(student TEXT, course CHAR(6))


CREATE TABLE WaitingList(student TEXT, course CHAR(6), position INT)

(student, course) 是两个表中的主键对,student 和 course 都是从其他表引用的单独外键。

我也有观点

CREATE VIEW Registrations(student, course, status)

哪个是状态为等待或已注册的两个表的联合,具体取决于(学生、课程)对来自哪个表。

然后我创建一个触发器和函数:

 CREATE FUNCTION unregistration_function() RETURNS TRIGGER AS $$
    BEGIN
        IF (EXISTS(SELECT * FROM WaitingList WHERE student = OLD.student AND course = OLD.course)) THEN
              --delete OLD.student from WaitingList and then update WaitingList position;

        ELSIF (EXISTS(SELECT * FROM Registered WHERE student = OLD.student AND course = OLD.course)) THEN
              --delete OLD.student from Registered;
        
        ELSE 
              RAISE EXCEPTION 'Student % is not registered or on waitinglist for course %', OLD.student, OLD.course;

        END IF;
        RETURN OLD;
     END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER unregistration 
    INSTEAD OF DELETE FROM Registrations
    FOR EACH ROW 
    EXECUTE PROCEDURE unregistration_function();

触发功能有效,因为它成功地从课程中取消注册学生或将他们从候补名单中删除。但是,如果学生未注册课程并且不在课程的候补名单上,则不会引发异常,但即使没有任何内容未注册,仍会报告成功取消注册。

我不确定我缺少什么,因为在这种情况下 WHERE 条件应该在 IF 和 ELSIF 子句中返回 false 并且应该引发异常。据我从文档中了解到,引发异常应该中止当前事务?

仅仅是因为这是一个 DELETE 语句,因此中止事务会导致 DELETE 简单地退出并删除 0 个仍被视为“成功”的行,因此不会显示我的错误消息?

【问题讨论】:

  • 尝试IS NOT DISTINCT FROM而不是=进行比较。

标签: sql postgresql


【解决方案1】:

为将要删除的每一行调用DELETE

如果你执行:

delete from registrations
    where student = XXX;

student不在表或视图中,则不调用触发器。

您需要查看已删除的行数以查看是否删除了任何内容。

【讨论】:

  • 当然……如此简单,但我错过了,谢谢。
  • @KnutKnutsson 。 . .我承认需要一些思考才能确定这是问题所在。这是一个微妙的点(虽然当你看到它时很明显)。
猜你喜欢
  • 2012-04-07
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
  • 2015-03-08
  • 2019-11-29
  • 2012-11-18
  • 2020-01-11
  • 1970-01-01
相关资源
最近更新 更多