当前位置:  开发笔记 > 数据库 > 正文

禁用Oracle中的所有表约束

如何解决《禁用Oracle中的所有表约束》经验,为你挑选了4个好方法。

如何使用单个命令禁用Oracle中的所有表约束?这可以是单个表,表列表,也可以是所有表.



1> WW...:

最好避免写出临时假脱机文件.使用PL/SQL块.您可以从SQL*Plus运行它或将此内容放入包或过程中.与USER_TABLES的连接是为了避免视图约束.

您不太可能真的想要禁用所有约束(包括NOT NULL,主键等).您应该考虑将constraint_type放在WHERE子句中.

BEGIN
  FOR c IN
  (SELECT c.owner, c.table_name, c.constraint_name
   FROM user_constraints c, user_tables t
   WHERE c.table_name = t.table_name
   AND c.status = 'ENABLED'
   AND NOT (t.iot_type IS NOT NULL AND c.constraint_type = 'P')
   ORDER BY c.constraint_type DESC)
  LOOP
    dbms_utility.exec_ddl_statement('alter table "' || c.owner || '"."' || c.table_name || '" disable constraint ' || c.constraint_name);
  END LOOP;
END;
/

再次启用约束有点麻烦 - 您需要先启用主键约束,然后才能在外键约束中引用它们.这可以使用constraint_type上的ORDER BY来完成.'P'=主键,'R'=外键.

BEGIN
  FOR c IN
  (SELECT c.owner, c.table_name, c.constraint_name
   FROM user_constraints c, user_tables t
   WHERE c.table_name = t.table_name
   AND c.status = 'DISABLED'
   ORDER BY c.constraint_type)
  LOOP
    dbms_utility.exec_ddl_statement('alter table "' || c.owner || '"."' || c.table_name || '" enable constraint ' || c.constraint_name);
  END LOOP;
END;
/


是不是第一个代码段在禁用外键之前尝试禁用主键?
警告:如果您已经禁用了禁用,则将使用该PL/SQL过程激活所有约束.您必须在哪里过滤这些限制,以确保他们保持禁用状态.

2> 小智..:

要计算约束之间的依赖关系:

SET Serveroutput ON
BEGIN
    FOR c IN
    (SELECT c.owner,c.table_name,c.constraint_name
    FROM user_constraints c,user_tables t
    WHERE c.table_name=t.table_name
    AND c.status='ENABLED'
    ORDER BY c.constraint_type DESC,c.last_change DESC
    )
    LOOP
        FOR D IN
        (SELECT P.Table_Name Parent_Table,C1.Table_Name Child_Table,C1.Owner,P.Constraint_Name Parent_Constraint,
            c1.constraint_name Child_Constraint
        FROM user_constraints p
        JOIN user_constraints c1 ON(p.constraint_name=c1.r_constraint_name)
        WHERE(p.constraint_type='P'
        OR p.constraint_type='U')
        AND c1.constraint_type='R'
        AND p.table_name=UPPER(c.table_name)
        )
        LOOP
            dbms_output.put_line('. Disable the constraint ' || d.Child_Constraint ||' (on table '||d.owner || '.' ||
            d.Child_Table || ')') ;
            dbms_utility.exec_ddl_statement('alter table ' || d.owner || '.' ||d.Child_Table || ' disable constraint ' ||
            d.Child_Constraint) ;
        END LOOP;
    END LOOP;
END;
/



3> Mike McAllis..:

这不是一个单一的命令,但这是我如何做到的.以下脚本已设计为在SQL*Plus中运行.请注意,我故意将其编写为仅在当前架构中工作.

set heading off

spool drop_constraints.out

select
    'alter table ' || 
    owner || '.' || 
    table_name || 
    ' disable constraint ' || -- or 'drop' if you want to permanently remove
    constraint_name || ';'
from
    user_constraints;

spool off

set heading on

@drop_constraints.out

要限制删除的内容,请在select语句中添加where子句: -

对constraint_type进行过滤以仅删除特定类型的约束

在table_name上过滤仅对一个或几个表执行此操作.

要运行多于当前模式,请修改select语句以从all_constraints而不是user_constraints中进行选择.

注意 - 出于某种原因,我不能使下划线不像上一段中的斜体那样.如果有人知道如何修复它,请随时编辑此答案.



4> 小智..:

使用以下游标禁用所有约束..并更改查询以启用约束...

DECLARE

cursor r1 is select * from user_constraints;
cursor r2 is select * from user_tables;

BEGIN
  FOR c1 IN r1
  loop
    for c2 in r2
    loop
       if c1.table_name = c2.table_name and c1.status = 'ENABLED' THEN
        dbms_utility.exec_ddl_statement('alter table ' || c1.owner || '.' || c1.table_name || ' disable constraint ' || c1.constraint_name);
       end if;
    end loop;
  END LOOP;
END;
/

推荐阅读
放ch养奶牛
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有