Database 禁用触发器Oracle中的触发器

Database 禁用触发器Oracle中的触发器,database,oracle,plsql,triggers,Database,Oracle,Plsql,Triggers,我偶然发现了这样一种情况,在执行更新之前,我需要禁用触发器中的触发器,然后重新启用它 基本上,我有两张桌子: TIME\u SLOTS具有诸如开始时间、结束时间等字段来设置时间 程序的插槽以及要指定的程序ID(外键) 哪个节目 程序包含所有不同可用程序的列表 &他们的细节。还包含持续时间 我有一个现有触发器,当更新或插入到时隙时,触发器从程序中查找持续时间,并确保结束时间=开始时间+持续时间 我还想添加一个新的触发器,当在节目中更改持续时间时,它会更新时隙中的结束时间 我已经设置了这两个触发

我偶然发现了这样一种情况,在执行更新之前,我需要禁用触发器中的触发器,然后重新启用它

基本上,我有两张桌子:

  • TIME\u SLOTS
    具有诸如开始时间、结束时间等字段来设置时间 程序的插槽以及要指定的程序ID(外键) 哪个节目

  • 程序
    包含所有不同可用程序的列表 &他们的细节。还包含持续时间

我有一个现有触发器,当更新或插入到
时隙时,触发器从
程序中查找持续时间,并确保结束时间=开始时间+持续时间

我还想添加一个新的触发器,当在
节目中更改持续时间时,它会更新
时隙中的结束时间

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

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\u SLOTS
上的触发器触发并查找持续时间-持续时间正在变化,我得到的错误如上所述

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

有什么想法吗


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

您几乎可以肯定地使用
立即执行
语句从一个触发器禁用另一个触发器:

EXECUTE IMMEDIATE 'ALTER TRIGGER trigger_name_here DISABLE';
但是,您绝对不应该对应用程序逻辑使用触发器。这是一个混乱的行业,不仅仅是因为触发器不能保证按顺序触发,还因为你正在经历的那种“问题”


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

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

IMHO,使用包变量是一个不错的选择。@EgorSkriptunoff您能在包中存储触发器吗?这将如何工作?变量应该存储在一个包中。不,您不能在包中存储触发器,但应该在您的面前闪烁警告。在触发器中禁用触发器从来都不是正确的选项,并且您得到的错误表明没有正确规范化的数据库@Egor建议您删除触发器中的所有逻辑,并将其放在一个包中,这通常是避免此错误的方法。您在这里做了两件不受欢迎且通常不赞成的事情:将触发器用于审核活动以外的任何活动,以及存储冗余数据(即反规范化).我有点理解你的意思,但我真的不知道如何实现这一点。当第一个表被更改时,我肯定需要一个触发器来更新另一个表吗?您是建议在触发器中调用过程还是?我们都建议的是,不要直接对第一个表发出INSERT或UPDATE语句,然后依赖触发器更新第二个表,您只需调用一个存储过程即可根据需要插入/更新两个表,而不必为此目的使用触发器。@swiss196:我们建议您有一个调用的过程,该过程实现更新数据所需的所有逻辑,包括跨表更新,等等。这种多触发逻辑出错的方式是天文数字。例如,考虑这将如何在多事务环境中工作。如果您认为一个变异表问题很难纠正,我绝对保证保持触发器的协调会更糟。祝你好运。