【问题标题】:Disable a trigger from a trigger Oracle从触发器 Oracle 禁用触发器
【发布时间】:2013-02-09 04:33:16
【问题描述】:

我偶然发现了一种情况,我需要在进行更新之前从触发器中禁用触发器,然后再重新启用它。

基本上,我有两张桌子:

  • TIME_SLOTS有开始时间、结束时间等字段,可以设置时间 程序的插槽以及程序 ID(外键)指定 哪个节目。

  • PROGRAMMES 包含所有不同可用程序的列表 及其详细信息。还包含持续时间。

我有一个现有触发器,当更新或插入TIME_SLOTS 时,触发器会从PROGRAMMES 查找持续时间,并确保结束时间 = 开始时间 + 持续时间。

我还想添加一个新触发器,用于在更改 PROGRAMMES 中的持续时间时更新 TIME_SLOTS 中的结束时间。

我已经设置了这两个触发器,但是当我改变持续时间时:

One error saving changes to table "SE217"."PROGRAMMES":
Row 1: ORA-04091: table SE217.PROGRAMMES is mutating, trigger/function may not see it
ORA-06512: at "SE217.SCHEDULES_VALID_TIMES", line 19
ORA-04088: error during execution of trigger 'SE217.SCHEDULES_VALID_TIMES'
ORA-06512: at "SE217.UPDATE_END_TIME", line 5
ORA-04088: error during execution of trigger 'SE217.UPDATE_END_TIME'

这显然是因为当我更改持续时间时,第二个触发器会更新TIME_SLOTS 中的结束时间。 TIME_SLOTS 上的触发器触发并查找持续时间 - 持续时间正在变化,我收到上述错误。

在我看来,当我使用新计算的结束时间更新 TIME_SLOTS 行时,我应该在更新之前禁用触发器并在更新之后重新启用 - 但由于这是触发器,我无法更改触发器。 .

有什么想法吗?

编辑:我有一个想法,我可以设置一个全局变量并在我不想运行的触发器中检查这个 var 等 - 但不确定如何最好地实现?

【问题讨论】:

  • 恕我直言,使用包变量是一个不错的选择。
  • @EgorSkriptunoff 你能在包中存储触发器吗?这将如何运作?
  • 变量应该存储在一个包中。
  • 不,您不能将触发器存储在一个包中,但您的面前应该有闪烁的警告。禁用触发器内的触发器永远不是正确的选择,您得到的错误表明没有正确规范化的数据库。 @Egor 建议您从触发器中删除所有逻辑并将其放在一个包中,这通常是解决此错误的方法。
  • 您在这里做了两件不受欢迎且通常不受欢迎的事情:将触发器用于除审计活动之外的任何事情,以及存储冗余数据(即反规范化)。

标签: database oracle plsql triggers


【解决方案1】:

您几乎可以肯定地使用EXECUTE IMMEDIATE 语句从另一个触发器中禁用一个触发器:

EXECUTE IMMEDIATE 'ALTER TRIGGER trigger_name_here DISABLE';

但是,您绝对不应该将触发器用于应用程序逻辑。这是一项混乱的业务,不仅因为触发器不能保证按顺序触发,还因为您遇到的“问题”。

将您描述的所有功能移动到存储过程或包中并仅在必要时使用触发器进行验证会更容易,也更安全。

【讨论】:

  • 我有点理解你的意思,但并不真正了解如何实现这一点。当第一个表被更改时,我肯定需要一个触发器来更新另一个表吗?您是建议在触发器中调用该过程还是?
  • 我们都建议的是,不要直接对第一个表发出 INSERT 或 UPDATE 语句,然后依靠触发器来更新第二个表,而应该简单地调用一个存储过程来 INSERT/根据需要更新两个表,并且根本不为此目的使用触发器。
  • @swiss196:我们的建议是你有一个你调用的过程,它实现了更新数据所需的all逻辑,包括跨表更新等。这种多触发逻辑可能出错的方式数量是天文数字。例如,考虑这将如何在多事务环境中工作。如果您认为变异表问题难以纠正,我绝对保证保持触发器协调会变得更糟。祝你好运。
【解决方案2】:

当您必须自定义现有功能并且您只能完全控制数据库时,就会出现这些问题。因此,您无法通过过程替换插入/更新,您可以做出反应。在这种情况下,您在两个表上都有触发器,并在表之间双向传播值。

【讨论】:

    猜你喜欢
    • 2020-09-24
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2013-02-12
    • 2020-12-30
    • 1970-01-01
    • 2013-03-29
    • 2016-12-27
    相关资源
    最近更新 更多