使用 PL/SQL 在触发器中中止插入/更新操作

Posted

技术标签:

【中文标题】使用 PL/SQL 在触发器中中止插入/更新操作【英文标题】:Abort insert/update operation in trigger using PL/SQL 【发布时间】:2013-03-01 15:20:21 【问题描述】:

我要编写一个触发器来检查一些插入/更新的信息,将它们与数据库中的数据进行比较,如果它们不正确,则停止整个操作。我在触发器(针对每个)之前编写,然后如果出现问题则抛出应用程序异常,但它不起作用,因为我从更新的表中读取,所以我得到 ORA-04091 错误。

现在我想知道如何解决这个问题?现在我唯一的想法是编写一个前触发器,将一些必要的数据插入到包中,并使用后触发器读取它们,这不是每个都适用的。但是有一个问题如何中止这个版本?如果我进行回滚,它将撤消此事务中我认为不明智的所有操作。你将如何解决这个问题?

【问题讨论】:

你能用触发器语法编辑你的问题吗? 【参考方案1】:

不要去那里。

ORA-04091: table XXXX is mutating 通常是一个很好的指标,表明您尝试执行的任何操作都过于复杂,无法通过触发器可靠完成。

当然,您可以使用 package array variable and a handful of triggers (ugh!) 来解决此错误,但您的代码很可能会:

由于其复杂性和触发器的不可预测性而无法维护 对多用户环境反应不佳

这就是为什么您在遇到此错误时应该重新考虑您的方法。我建议您构建一组很好地分组在一个包中的程序来处理行间一致性。撤销所有权限以直接对表进行 DML,并仅使用这些过程对其进行修改。

例如,您的更新过程将是一个原子过程,它会:

    获取锁以防止对同一组行进行并发更新(例如锁定酒店预订应用程序中的房间记录)。 检查要插入的行是否验证了所有业务逻辑 制作所有相关的 DML 在发生错误时回滚其所有更改(并且仅回滚其更改 -- 而不是整个事务)(使用 PL/SQL 很容易,只需引发错误)。

【讨论】:

以上是关于使用 PL/SQL 在触发器中中止插入/更新操作的主要内容,如果未能解决你的问题,请参考以下文章

更新同一表中的值的 PL/SQL 插入和删除触发器

PL/SQL 触发器插入下一个值

如何使用触发器在同一张表中插入新行(Oracle PL/SQL 10G)?

pl/sql 触发器完整性约束问题

PL/SQL ORACLE:删除时触发更新

在使用 Entity Framework 数据库优先在表上插入行之前,如何从 PL/SQL 执行触发器?