[20160716]主外键与延迟约束.txt
--前几天遇到的问题,因为开发没有在2个存在主外键上的表上建立约束,导致主表记录删除了,而外表数据还在.
--主要开发有需求要删除主表的记录,由于条件写错,导致以上情况出现.实际上oracle支持延迟约束,只有提交的时候才会检查。
--自己通过例子说明:
1.环境:
SCOTT@test01p> @ ver1
PORT_STRING VERSION BANNER CON_ID
--------------------- ---------- -------------------------------------------------------------------------------- ------
IBMPC/WIN_NT64-9.1.0 12.1.0.1.0 Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production 0
2.建立测试环境:
create table p ( x int primary key );
create table c ( x int );
insert into p values ( 1 );
insert into p values ( 2 );
insert into c values ( 1 );
commit;
create index i_c_x on scott.c(X);
3.如果建立约束:
SCOTT@test01p> alter table c add ( constraint fk_c foreign key (x) references p (x) enable validate);
Table altered.
SCOTT@test01p> delete from p where x=1;
delete from p where x=1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_C) violated - child record found
--这样在外键存在记录的情况下删除主键记录会报错. 而执行如下ok.
SCOTT@test01p> delete from p where x=2;
1 row deleted.
SCOTT@test01p> rollback ;
Rollback complete.
4.要实现提交时再判断,可以修改如下.
SCOTT@test01p> alter table c drop constraint fk_c ;
Table altered.
SCOTT@test01p> alter table c add ( constraint fk_c foreign key (x) references p (x) deferrable initially deferred enable validate);
Table altered.
SCOTT@test01p> delete from p where x=1;
1 row deleted.
SCOTT@test01p> commit ;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-02292: integrity constraint (SCOTT.FK_C) violated - child record found
--这样在提交时才报错,而不是在执行时.
SCOTT@test01p> delete from p where x=1;
1 row deleted.
SCOTT@test01p> insert into p values ( 1 );
1 row created.
SCOTT@test01p> commit ;
Commit complete.
--这样不报错.
5.也可以这样执行:
SCOTT@test01p> insert into c values ( 3 );
1 row created.
SCOTT@test01p> insert into p values (3);
1 row created.
SCOTT@test01p> commit ;
Commit complete.
--不知道这样设置是否存在什么问题,对于我完全目前是不得以而为之.
--我们现在的问题主要在于开发不合理的开发模式,本来应该是update的问题,他们采用的做法就是先删除原来数据,再插入.
--开发太不了解oracle了.