lych528 发表于 2014-12-9 11:06:45

ORACLE 约束延迟验证的特性deferred的作用与场景?

之前约束这一块都由开发那边管,今天接手约束,突然有一个疑问?约束deferred延迟验证的作用是什么?适合于什么应用场景?因为基于事务的特性,任何一个事务要么成功,要么失败,即使你整个事务前面999万条insert记录都不违反约束,但是如果第一千万条insert记录违反了约束,那么基于这个错误会回滚整个事务。既然如此为什么oracle要引出约束的延迟验证这一个属性?这不是白白浪费了执行insert 999万条记录所产生的资源损耗吗?这样还不如执行启用约束立即验证,反而能提前结束事务,释放系统资源。那么deferred还有什么神秘的面纱吗?

Liu Maclean(刘相兵 发表于 2014-12-9 20:10:00

SQL> create table p ( pk int primary key );

Table created.



SQL>  create table c( t1 int,fk int constraint c_fk references p(pk) deferrable initially immediate);

Table created.


SQL> insert into p values ( 1 );

1 row created.

SQL> insert into p values ( 3 );

1 row created.

SQL> insert into c values ( 2,1 );

1 row created.

SQL> commit;

Commit complete.

SQL> select * from p;

        PK
----------
         1
         3

SQL> select * from c;

        T1         FK
---------- ----------
         2          1
                 

此时若你想将  P 和 C表中的PK=1 FK=1  都更新为PK=2 FK=2 如何做呢?



SQL> update p set pk=2 where pk=1;
update p set pk=2 where pk=1
*
ERROR at line 1:
ORA-02292: integrity constraint (SYS.C_FK) violated - child record found



SQL> update c set fk=2 where fk=1;
update c set fk=2 where fk=1
*
ERROR at line 1:
ORA-02291: integrity constraint (SYS.C_FK) violated - parent key not found



你单独更新 P 和 C 表都不可以, 要么你删除数据后 重新插入

要么:

set constraint c_fk deferred;


SQL> set constraint c_fk deferred;

Constraint set.

SQL> update p set pk=2 where pk=1;

1 row updated.

SQL> update c set fk=2 where fk=1;

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from p;

        PK
----------
         2
         3

SQL> select * from c;

        T1         FK
---------- ----------
         2          2
                 
                 
                 
                 
                 这样够清楚了吗?

lych528 发表于 2014-12-9 20:18:29

没想过这种场景!原来还有这种用法,我就说这deferred的作用是啥!秒懂!感谢,刘大
页: [1]
查看完整版本: ORACLE 约束延迟验证的特性deferred的作用与场景?