【问题标题】:Deleting rows on a complex view which is used by a trigger删除触发器使用的复杂视图上的行
【发布时间】:2012-01-07 01:37:06
【问题描述】:

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

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 表上删除某些内容时工作。如果有人有不同的解决方案,我愿意接受。

【问题讨论】:

    标签: sql oracle view triggers sql-delete


    【解决方案1】:

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

    更新

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

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

    【讨论】:

    • 如果我以某种方式使用 JOIN,有可能吗?
    • @ayadew:不,我认为它不适用于表的数据结构和推断逻辑。基本问题是 DELETE 旨在对单个表进行操作,但您希望它对两个表进行操作。我会在答案中添加一个额外的建议。
    • 谢谢,我会调查的。在我接受答案前几天会继续提出问题。
    • 我通过为两个表创建单独的触发器来解决它。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 2010-10-01
    • 2015-06-05
    • 1970-01-01
    相关资源
    最近更新 更多