首页 > 解决方案 > 在 DELETE FROM 上触发的触发器函数中未引发异常(postgresql 13)

问题描述

我有两张桌子:

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 个仍被视为“成功”的行,因此不显示我的错误消息?

标签: sqlpostgresql

解决方案


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

如果你执行:

delete from registrations
    where student = XXX;

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

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


推荐阅读