3

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

基本上,我有两张桌子:

  • TIME_SLOTS具有开始时间、结束时间等字段来设置节目的时隙以及节目ID(外键)来指定哪个节目。

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

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

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

我已经设置了这两个触发器,但是在更改我得到的持续时间时:

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 等 - 但不确定如何最好地实现?

4

2 回答 2

5

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

EXECUTE IMMEDIATE 'ALTER TRIGGER trigger_name_here DISABLE';

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

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

于 2013-02-23T22:34:18.823 回答
0

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

于 2016-03-10T10:45:55.980 回答