【问题标题】:How to disable all triggers that concerns a table in Oracle?如何禁用所有与 Oracle 中的表相关的触发器?
【发布时间】:2011-04-01 23:27:35
【问题描述】:

在 Postgresql 中,如果我执行 ALTER TABLE mytable DISBLE TRIGGERS ALL,所有与该表相关的触发器和约束都将暂停。

特别是从其他表到mytable的外键被挂起,我可以毫无问题地从mytable中删除。我有破坏数据库一致性的风险,但我知道我在做什么,而且我必须拥有超级用户权限。

我如何在 Oracle 中做同样的事情?我的印象是,Oracle 中的ALTER TABLE mytable DISBLE ALL TRIGGERS 将暂停所有属于 mytable 的触发器和约束,但不会暂停那些与 mytable 相关但属于其他表(尤其是外键)的触发器和约束。

我是对的吗?在 Oracle 中实现与 Postgresql 相同结果的方法是什么?

【问题讨论】:

    标签: oracle postgresql


    【解决方案1】:

    该语法确实禁用了 Oracle 中的触发器:

    SQL> select trigger_name, status from user_triggers
      2  where table_name='TEST'
      3  /
    
    TRIGGER_NAME                   STATUS
    ------------------------------ --------
    TEST_TRIGGER                   ENABLED
    
    SQL> ALTER TABLE test DISABLE ALL TRIGGERS
      2  /
    
    Table altered.
    
    SQL> select trigger_name, status from user_triggers
      2  where table_name='TEST'
      3  /
    
    TRIGGER_NAME                   STATUS
    ------------------------------ --------
    TEST_TRIGGER                   DISABLED
    
    SQL>
    

    但是它不会对外键或任何其他约束做任何事情。这是因为 Oracle 不使用触发器来强制执行此类操作。好的,在幕后约束和用户定义的触发器可能共享某些低级内核代码。但在我们所说的层面上,它们是两个不同的东西。

    如果你想禁用表上的所有外键,恐怕你需要使用这样的东西:

    SQL> select constraint_name, status from user_constraints
      2  where table_name = 'EMP'
      3  and constraint_type = 'R'
      4  /
    
    CONSTRAINT_NAME                STATUS
    ------------------------------ --------
    FK_DEPTNO                      ENABLED
    
    
    SQL> begin
      2      for r in ( select constraint_name, status from user_constraints
      3                 where table_name = 'EMP'
      4                 and constraint_type = 'R' )
      5      loop
      6          execute immediate 'alter table emp disable constraint '||r.constraint_name;
      7      end loop;
      8* end;
      9  /
    
    PL/SQL procedure successfully completed.
    
    SQL> select constraint_name, status from user_constraints
      2  where table_name = 'EMP'
      3  and constraint_type = 'R'
      4  /
    
    CONSTRAINT_NAME                STATUS
    ------------------------------ --------
    FK_DEPTNO                      DISABLED
    
    SQL>
    

    这是您可能想要包装在用户定义函数中的东西,该函数将 TABLE_NAME 作为参数。此外,您还需要一个类似的函数来重新启用约束。

    【讨论】:

    • 事实上我有点太快来验证答案......这将禁用属于 mytable 的约束,而不是与 mytable 相关的约束。在 Postgresql 中禁用触发器的全部实现是禁用指向 mytable 的外键...
    • 好的,这里是相关的sql来禁用指向mytable的外键:select 'alter table '||a.owner||'.'||a.table_name|| ' disable constraint '||a.constraint_name||';' from all_constraints a, all_constraints b where a.constraint_type = 'R' and a.r_constraint_name = b.constraint_name and a.r_owner = b.owner and b.table_name = 'mytable';
    猜你喜欢
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2020-04-15
    • 1970-01-01
    • 2020-09-24
    • 2016-11-27
    相关资源
    最近更新 更多