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

时间:2013-03-01 15:20:21

标签: oracle plsql oracle11g

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

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

1 个答案:

答案 0 :(得分:3)

不要去那里。

ORA-04091: table XXXX is mutating通常是一个很好的指标,无论您尝试做什么都太复杂,无法使用触发器可靠

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

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

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

例如,您的更新程序将是原子进程:

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