【发布时间】: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