使用 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 在触发器中中止插入/更新操作的主要内容,如果未能解决你的问题,请参考以下文章