好吧,假设你有两张table, Table1 以及 Table2 . Table1 的主键是的外键 Table2 . 如果将主键约束放在 Table1 然后用 Alter Table 命令,表2上的外键是否也会自动重新启用?
Table1
Table2
Alter Table
0g0grzrc1#
让我们试试会发生什么。首先创建表t1和t2。
CREATE TABLE t1 (parent_id NUMBER);Table createdCREATE TABLE t2 (child_id NUMBER);Table created
CREATE TABLE t1 (parent_id NUMBER);
Table created
CREATE TABLE t2 (child_id NUMBER);
然后创建两个约束
ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY (parent_id) USING INDEX;Table alteredALTER TABLE t2 ADD CONSTRAINT t2_fk FOREIGN KEY (child_id) REFERENCES t1;Table altered
ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY (parent_id) USING INDEX;
Table altered
ALTER TABLE t2 ADD CONSTRAINT t2_fk FOREIGN KEY (child_id) REFERENCES t1;
现在查看字典并选择这两个表的约束
SELECT c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE, c.R_CONSTRAINT_NAMEFROM User_Constraints c WHERE c.TABLE_NAME IN ('T1', 'T2');CONSTRAINT_NAME CONSTRAINT_TYPE R_CONSTRAINT_NAME------------------------------ --------------- ------------------------------T1_PK P T2_FK R T1_PK
SELECT c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE, c.R_CONSTRAINT_NAME
FROM User_Constraints c WHERE c.TABLE_NAME IN ('T1', 'T2');
CONSTRAINT_NAME CONSTRAINT_TYPE R_CONSTRAINT_NAME
------------------------------ --------------- ------------------------------
T1_PK P
T2_FK R T1_PK
我们看到1个主键(p)和1个外键(r),然后删除pk
ALTER TABLE t1 DROP CONSTRAINT t1_pk CASCADE;Table altered
ALTER TABLE t1 DROP CONSTRAINT t1_pk CASCADE;
cascade关键字指示oracle隐式删除所有引用要删除的pk的fk约束。如果没有cascade,您将得到ora-02273:这个唯一/主键被一些外键引用,pk不会被删除。再次查看字典并选择这两个表的约束
SELECT c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE, c.R_CONSTRAINT_NAMEFROM User_Constraints c WHERE c.TABLE_NAME IN ('T1', 'T2');CONSTRAINT_NAME CONSTRAINT_TYPE R_CONSTRAINT_NAME------------------------------ --------------- ------------------------------
没有行-pk和fk都没有了。重新创建pk
ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY (parent_id) USING INDEX;Table altered
再看看字典
SELECT c.CONSTRAINT_NAME, c.CONSTRAINT_TYPE, c.R_CONSTRAINT_NAMEFROM User_Constraints c WHERE c.TABLE_NAME IN ('T1', 'T2');CONSTRAINT_NAME CONSTRAINT_TYPE R_CONSTRAINT_NAME------------------------------ --------------- ------------------------------T1_PK P
只创建pk。清理测试用例
DROP TABLE t2;Table droppedDROP TABLE t1;Table dropped
DROP TABLE t2;
Table dropped
DROP TABLE t1;
t0ybt7op2#
让我们做一个你所要求的测试用例。我希望我正确理解了前提:我有一个表myu pk,在c1列上有一个主键我有一个表myfk,其中包含列c1上的主键,它也是表mypk中列c1的外键。您想禁用或删除表my\u fk中的主键,以查看外键的情况。我们来玩:
SQL> create table my_pk ( c1 number primary key , c2 number );Table created.SQL> create table my_fk ( c1 number primary key , c2 number, constraint my_fk_constraint foreign key (c1) references my_pk (c1) ) ;Table created.SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) and owner = 'MYOWNER' ;TABLE_NAME CONSTRAINT_NAME C STATUS------------------------------ ------------------------------ - --------MY_PK SYS_C00141013 P ENABLEDMY_FK SYS_C00141016 P ENABLEDMY_FK MY_FK_CONSTRAINT R ENABLED
SQL> create table my_pk ( c1 number primary key , c2 number );
Table created.
SQL> create table my_fk ( c1 number primary key , c2 number, constraint my_fk_constraint foreign key (c1) references my_pk (c1) ) ;
SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) and owner = 'MYOWNER' ;
TABLE_NAME CONSTRAINT_NAME C STATUS
------------------------------ ------------------------------ - --------
MY_PK SYS_C00141013 P ENABLED
MY_FK SYS_C00141016 P ENABLED
MY_FK MY_FK_CONSTRAINT R ENABLED
那么,让我们照你说的做:禁用表my\u fk中的主键,它也是表my\u pk的外键
SQL> alter table my_fk disable primary key ;Table altered.SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) and owner = 'MY_OWNER';TABLE_NAME CONSTRAINT_NAME C STATUS------------------------------ ------------------------------ - --------MY_PK SYS_C00141013 P ENABLEDMY_FK SYS_C00141016 P DISABLEDMY_FK MY_FK_CONSTRAINT R ENABLED
SQL> alter table my_fk disable primary key ;
Table altered.
SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) and owner = 'MY_OWNER';
MY_FK SYS_C00141016 P DISABLED
让我们评估外键是否仍然被强制执行,即使pk被禁用。您可以在上面看到,fk在字典中显示为已启用。
SQL> insert into my_pk values ( 1 , 1 );1 row created.SQL> commit;Commit complete.SQL> insert into my_fk values ( 2, 1 );insert into my_fk values ( 2, 1 )* ERROR at line 1:ORA-02291: integrity constraint (MYOWNER.MY_FK_CONSTRAINT) violated - parentkey not found
SQL> insert into my_pk values ( 1 , 1 );
1 row created.
SQL> commit;
Commit complete.
SQL> insert into my_fk values ( 2, 1 );
insert into my_fk values ( 2, 1 )
*
ERROR at line 1:
ORA-02291: integrity constraint (MYOWNER.MY_FK_CONSTRAINT) violated - parent
key not found
外键仍然是强制的,尽管pk是禁用的,如果需要,您仍然可以插入重复项
SQL> insert into my_fk values ( 1 , 1 );1 row created.SQL> rollback;Rollback complete.SQL>
SQL> insert into my_fk values ( 1 , 1 );
SQL> rollback;
Rollback complete.
SQL>
我们重新启用表my\u fk中的pk
SQL> alter table my_fk enable primary key ;Table altered.SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) ;TABLE_NAME CONSTRAINT_NAME C STATUS------------------------------ ------------------------------ - --------MY_PK SYS_C00141013 P ENABLEDMY_FK SYS_C00141016 P ENABLEDMY_FK MY_FK_CONSTRAINT R ENABLED
SQL> alter table my_fk enable primary key ;
SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) ;
删除表my\u fk中的主键,它也是my\u pk的外键
SQL> alter table my_fk drop primary key ;Table altered.SQL> select table_name, constraint_name, constraint_type, status from dba_constraints where table_name in ( 'MY_FK' , 'MY_PK' ) ;TABLE_NAME CONSTRAINT_NAME C STATUS------------------------------ ------------------------------ - --------MY_PK SYS_C00141013 P ENABLEDMY_FK MY_FK_CONSTRAINT R ENABLEDSQL> insert into my_pk values ( 2 , 2 );1 row created.SQL> select * from my_pk ; C1 C2---------- ---------- 1 1 2 2SQL> insert into my_fk values ( 2 ,2 );1 row created.SQL> select * from my_fk ; C1 C2---------- ---------- 1 1 2 2SQL> insert into my_fk values ( 3 , 3 );insert into my_fk values ( 3 , 3 )* ERROR at line 1:ORA-02291: integrity constraint (MYOWNER.MY_FK_CONSTRAINT) violated - parentkey not found
SQL> alter table my_fk drop primary key ;
SQL> select table_name, constraint_name, constraint_type, status from dba_constraints
where table_name in ( 'MY_FK' , 'MY_PK' ) ;
SQL> insert into my_pk values ( 2 , 2 );
SQL> select * from my_pk ;
C1 C2
---------- ----------
1 1
2 2
SQL> insert into my_fk values ( 2 ,2 );
SQL> select * from my_fk ;
SQL> insert into my_fk values ( 3 , 3 );
insert into my_fk values ( 3 , 3 )
因此,无论是禁用主键约束还是在表my\u fk中删除主键约束,外键仍然是强制的。显然,您可以在禁用主键的同时向表中添加重复项。在我的测试用例中,我没有使用cascade选项,它改变了另一个答案中提供的场景。
2条答案
按热度按时间0g0grzrc1#
让我们试试会发生什么。
首先创建表t1和t2。
然后创建两个约束
现在查看字典并选择这两个表的约束
我们看到1个主键(p)和1个外键(r),然后删除pk
cascade关键字指示oracle隐式删除所有引用要删除的pk的fk约束。如果没有cascade,您将得到ora-02273:这个唯一/主键被一些外键引用,pk不会被删除。
再次查看字典并选择这两个表的约束
没有行-pk和fk都没有了。重新创建pk
再看看字典
只创建pk。清理测试用例
t0ybt7op2#
让我们做一个你所要求的测试用例。我希望我正确理解了前提:
我有一个表myu pk,在c1列上有一个主键
我有一个表myfk,其中包含列c1上的主键,它也是表mypk中列c1的外键。
您想禁用或删除表my\u fk中的主键,以查看外键的情况。
我们来玩:
那么,让我们照你说的做:
禁用表my\u fk中的主键,它也是表my\u pk的外键
让我们评估外键是否仍然被强制执行,即使pk被禁用。您可以在上面看到,fk在字典中显示为已启用。
外键仍然是强制的,尽管pk是禁用的,如果需要,您仍然可以插入重复项
我们重新启用表my\u fk中的pk
删除表my\u fk中的主键,它也是my\u pk的外键
因此,无论是禁用主键约束还是在表my\u fk中删除主键约束,外键仍然是强制的。显然,您可以在禁用主键的同时向表中添加重复项。在我的测试用例中,我没有使用cascade选项,它改变了另一个答案中提供的场景。