【问题标题】:Can i disable a trigger inside a trigger in oracle?我可以在 oracle 的触发器中禁用触发器吗?
【发布时间】:2025-12-04 04:05:01
【问题描述】:

我有 2 个触发器和两个表。 一个(触发器)是在插入第一个表中的一行时插入另一个表的一个列中,另一个阻止在该列中插入和更新。 我想知道是否有一种方法可以禁用第二个触发器,以防止在第一个触发器执行期间插入/更新。

【问题讨论】:

  • 你自己试过了吗?有没有发现什么错误?
  • 当我在触发器内写“alter trigger name_of_trigger disable”时,我告诉我我不能在触发器内这样做。在“alter”下方显示语法错误
  • Alter 触发器是 DDL,如果要从 PL/SQL 代码执行 DDL,则必须使用 EXECUTE IMMEDIATE 'ALTER TRIGGER triggername DISABLE'。尝试使用 EXECUTE IMMEDIATE。
  • Oracle 没有在触发器@hkandpal 中执行它。 Oracle 只是跳过了那条线。
  • DDL 不能在单个 DML 事务的范围内执行:您不能将它嵌入到本来是 DML 一部分的触发器中。您必须先单独执行 DDL,以便为所有事务禁用触发器,然后执行 DML,提交,然后重新启用触发器。在第二个触发器中包含逻辑以确定何时应该和不应该允许插入/更新会更简单。

标签: oracle


【解决方案1】:

这就是我对问题的理解。看看有没有帮助。

示例表:

SQL> create table test (id number);

Table created.

SQL> create table test_2 (id number);

Table created.

test_2 上的触发器可防止插入:

SQL> create or replace trigger trg2
  2    before insert or update on test_2
  3    for each row
  4  begin
  5    raise_application_error(-20000, 'Not allowed');
  6  end;
  7  /

Trigger created.

有效吗?

SQL> insert into test_2 (id) values (1);
insert into test_2 (id) values (1)
            *
ERROR at line 1:
ORA-20000: Not allowed
ORA-06512: at "SCOTT.TRG2", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRG2'

是的,它有效。


现在,test 上的触发器应该 a) 禁用 trg2 触发器和 b) 将值插入 test_2。一个简单的代码将是

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  begin
  5    execute immediate 'alter trigger trg2 disable';
  6    insert into test_2 (id) values (:new.id);
  7  end;
  8  /

Trigger created.

让我们测试一下:

SQL> insert into test (id) values (1);
insert into test (id) values (1)
            *
ERROR at line 1:
ORA-04092: cannot COMMIT in a trigger
ORA-06512: at "SCOTT.TRG1", line 2
ORA-04088: error during execution of trigger 'SCOTT.TRG1'

啊哈。不能在触发器中COMMIT。它在哪里?在动态 SQL 的 alter trigger 中 - 它是一个 DDL,它隐式提交。如何“修复”它?使其(触发器)成为自主事务:

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  declare
  5    pragma autonomous_transaction;
  6  begin
  7    execute immediate 'alter trigger trg2 disable';
  8    insert into test_2 (id) values (:new.id);
  9  end;
 10  /

Trigger created.

SQL> insert into test (id) values (1);
insert into test (id) values (1)
            *
ERROR at line 1:
ORA-06519: active autonomous transaction detected and rolled back
ORA-06512: at "SCOTT.TRG1", line 6
ORA-04088: error during execution of trigger 'SCOTT.TRG1'

这是另一个错误;它说——如果我们有一个自治事务——我们必须要么提交要么回滚。让我们提交(因为这可能是您想要做的):

SQL> create or replace trigger trg1
  2    before insert on test
  3    for each row
  4  declare
  5    pragma autonomous_transaction;
  6  begin
  7    execute immediate 'alter trigger trg2 disable';
  8    insert into test_2 (id) values (:new.id);
  9    commit;
 10  end;
 11  /

Trigger created.

SQL> insert into test (id) values (100);

1 row created.

SQL> select * From test;

        ID
----------
       100

SQL> select * from test_2;

        ID
----------
       100

SQL>

对;现在它工作了

我建议您重新阅读问题下方发布的 cmets,查看此示例并选择要执行的操作。

【讨论】:

  • 完美男人,非常感谢。