删除触发器使用的复杂视图上的行

时间:2011-11-26 20:54:17

标签: sql oracle view triggers sql-delete

尝试删除视图中的行时出现此错误

ORA-01732:数据操作操作在此视图中不合法

发出的SQL命令是

DELETE FROM RegisterHelper
WHERE StudentID = 111111111 AND CourseID = 'ASD123';

这会产生错误。我已经仔细检查过这些值是否存在。

我的观点是

CREATE VIEW RegisterHelper AS
SELECT studentId, courseID, NULL as position, 'registered' AS status
FROM registeredOn
UNION
SELECT studentId, courseID, position, 'waiting' AS status
FROM waitingOn;

此视图会创建所有课程中等待和注册学生的完整列表,以及他们的状态(在触发器中使用)。此处给出的所有数据对于触发器都是必不可少的。

触发器是

CREATE OR REPLACE TRIGGER CourseUnregistration
INSTEAD OF DELETE ON RegisterHelper
etc

表格如下

CREATE TABLE RegisteredOn (
    StudentID REFERENCES Student(StudentID) NOT NULL,
    CourseID REFERENCES Course(CourseID) NOT NULL
);

CREATE TABLE WaitingOn (
    StudentID  REFERENCES Student(StudentID) NOT NULL,
    CourseID REFERENCES Course(CourseID) NOT NULL,
    Position INT NOT NULL,

    PRIMARY KEY(StudentID, CourseID)
);

由于我只从具有引用值的表中删除,因此删除引用的值(显然)没有问题 - 这应该没有问题。

有趣的是,几小时前它实际上在RegisterHelper视图上发出了DELETE命令。由于某种原因,它已停止工作,我不记得改变它。

RegisterHelper视图上存在触发器的原因是因为在RegisteredOn和WaitingOn表上插入和删除了学生。插入工作正常,删除没有,因为我得到错误。

简单地说,我只是希望触发器在RegisteredOn或WaitingOn表上删除某些内容时起作用。如果有人有不同的解决方案,我愿意接受。

1 个答案:

答案 0 :(得分:3)

您无法从具有不同联合表的视图中删除。您需要执行两个不同的delete语句,每个表一个。

<强>更新

为了使代码与您现在正在寻找的单个删除语句一样简单,我建议您创建一个存储过程来执行删除并将学生和课程信息传递给此过程。

无论如何,这是一个很好的通用设计,因为如果你添加额外的表,其数据可能需要在将来以相同的逻辑(例如实验室注册)删除,那么你只需要修改存储过程而不是动态SQL。