如何使用单个命令禁用Oracle中的所有表约束?这可以是单个表,表列表,也可以是所有表.
最好避免写出临时假脱机文件.使用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; /
要计算约束之间的依赖关系:
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; /
这不是一个单一的命令,但这是我如何做到的.以下脚本已设计为在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中进行选择.
注意 - 出于某种原因,我不能使下划线不像上一段中的斜体那样.如果有人知道如何修复它,请随时编辑此答案.
使用以下游标禁用所有约束..并更改查询以启用约束...
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; /