oracle 禁用与特定表关联的所有外键约束

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41265367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 03:21:17  来源:igfitidea点击:

Disable all foreign key constraints associated to specific table

sqloracle

提问by Mojimi

I have table 'MY_TABLE' which has a primary key 'CODE' , this primary key has several foreign key constraints referencing it and I need to disable them all temporarily.

我有一个表 'MY_TABLE',它有一个主键 'CODE',这个主键有几个引用它的外键约束,我需要暂时禁用它们。

Trying to expand on this answer here : Fix ORA-02273: this unique/primary key is referenced by some foreign keys, except not by constraint_name

尝试在此处扩展此答案:修复 ORA-02273:此唯一/主键由某些外键引用,但不是由约束名称引用

I'm trying to select all foreign_key constraints that reference 'CODE' of 'MY_TABLE' and disable them (eventually enable, I'm assuming you just switch disable for enable in the syntax)

我正在尝试选择所有引用“MY_TABLE”的“CODE”的外键约束并禁用它们(最终启用,我假设您只是在语法中将禁用切换为启用)

采纳答案by Aleksej

Say you have tables like these:

假设你有这样的表:

create table MY_TABLE ( CODE number primary key);
create table anotherTable ( code_ref number);
alter table  anotherTable add constraint ck1 foreign key ( code_ref) references my_table ( code);
create table yetAnotherTable ( code_ref number);
alter table  yetAnotherTable add constraint ck2 foreign key ( code_ref) references my_table ( code);

You can use something like the following to loop through all the constraints referring to a given column of a table and disable/enable them with:

您可以使用类似以下内容来循环引用表的给定列的所有约束,并使用以下命令禁用/启用它们:

begin
    for s in (
                SELECT 'alter table ' || c2.table_name || ' modify constraint ' || c2.constraint_name || ' disable' as statement
                FROM all_constraints c
                       INNER JOIN all_constraints c2
                         ON ( c.constraint_name = c2.r_constraint_name AND c.owner = c2.owner)
                       INNER JOIN all_cons_columns col
                         ON ( c.constraint_name = col.constraint_name AND c.owner = col.owner) 
                WHERE c2.constraint_type = 'R'
                  AND c.table_name = 'MY_TABLE'
                  AND c.owner = 'ALEK'
                  AND col.column_name = 'CODE'
             )
    loop
        dbms_output.put_line(s.statement);
        execute immediate s.statement;
    end loop;
end;

This gives (and executes):

这给出(并执行):

alter table YETANOTHERTABLE modify constraint CK2 disable
alter table ANOTHERTABLE modify constraint CK1 disable

回答by Nick Krasnov

You can avoid PL/SQL code and several dynamically constructed alter tablestatements. In order to disable all foreign keys that depend on a particular table's primary key, simply disable primary key with cascadeclause and then re-enable(if you need to) it again.

您可以避免使用 PL/SQL 代码和几个动态构造的alter table语句。为了禁用依赖于特定表的主键的所有外键,只需使用cascade子句禁用主键,然后重新启用(如果需要)。

Here is an example:

下面是一个例子:

--drop table t3;
--drop table t2;
--drop table t1;
create table t1(c1 number primary key);
create table t2(c1 number references t1(c1));
create table t3(c1 number references t1(c1));

select table_name
     , constraint_type
     , status
  from user_constraints
  where table_name in ('T1','T2', 'T3')

TABLE C STATUS    
----- - ----------
T2    R ENABLED   
T1    P ENABLED   
T3    R ENABLED   

3 rows selected.

Disabling foreign keys:

禁用外键:

alter table t1 disable primary key cascade;
alter table t1 enable  primary key;

Result:

结果:

select table_name
     , constraint_type
     , status
  from user_constraints
  where table_name in ('T1','T2', 'T3')

TABLE C STATUS    
----- - ----------
T2    R DISABLED  
T1    P ENABLED   
T3    R DISABLED  

3 rows selected.

Note: It's not possible to enable all foreign key constraints again in cascade mode. It'd have to be done manually.

注意:在级联模式下不可能再次启用所有外键约束。它必须手动完成。

回答by Kacper

Try that query to generate all alters you need:

尝试该查询以生成您需要的所有更改:

SELECT  'alter table ' || table_name || ' disable constraint ' ||  constraint_name || ';' from (
  select distinct a.table_name, a.constraint_name
  FROM all_cons_columns a
  JOIN all_constraints c ON a.owner = c.owner
                    AND a.constraint_name = c.constraint_name
  JOIN all_constraints c_pk ON c.r_owner = c_pk.owner
                       AND c.r_constraint_name = c_pk.constraint_name
  WHERE c.constraint_type = 'R'
  AND c_pk.table_name = 'MY_TABLE');

回答by Xavi Alavedra

You must put the name of the table into

您必须将表的名称放入

select 'alter table '||table_name||' disable constraint '|| constraint_name||'; 'from user_constraint
where r_constraint_name in
(select constraint_name
    from user_constraints
    where table_name='TCLIENTSALBARANS'
    and constraint_type='P');