• Oracle:DEFERRABLE 约束和级联更新


    DEFERRABLE 约束和级联更新
    从Oracle8.0 开始,我们还能够延迟约束检查,对于许多操作来说,这很有好处。首先能想到的是,
    可能需要将一个主键的UPDATE 级联到子键。也许很多人会说:这没有必要,因为主键是不可变的(我就是
    这些人之一),但是还有人坚持要有级联UPDATE。有了可延迟的约束,就使得级联更新成为可能。
    注意一般认为,完成更新级联来修改主键是很不好的做法。这会破坏主键的意图。如果你必须做一
    次级联更新来修正不对的信息,这倒是可以的;但是如果你发现自己在不停地完成级联更新,并
    把这当做应用的一部分,那就是另一码事了,你应该退一步,重新考虑一下这个过程。倘若真是
    这样,能你就是错把鸡毛当令箭了!
    在以前的版本中,确实也可以完成CASCADE UPDATE,但是为此需要做大量的工作,而且存在某些限
    制。有了可延迟的约束后,这就变得易如反掌了。代码如下:
    ops$tkyte@ORA10G> insert into t values ( 2 );
    1 row created.
    ops$tkyte@ORA10G> update t set x = x+1;
    2 rows updated.
    ops$tkyte@ORA10G> create table p
    2 ( pk int primary key )
    3 /
    Table created.
    ops$tkyte@ORA10G> create table c
    2 ( fk constraint c_fk
    3 references p(pk)
    4 deferrable
    5 initially immediate
    319
    / 849
    我们有一个父表P,还有一个子表C。表C 引用了表P,保证这个规则的约束是C_FK(子外键)。这个
    约束创建为一个DEFERRABLE 约束,但是设置为INITIALLY IMMEDIATE。这说明,可以把这个约束延迟到
    COMMIT 或另外某个时间才检查。不过,默认情况下,这个约束在语句级验证。这是可延迟约束最常见的用
    法。大多数现有的应用不会在COMMIT 语句上检查约束冲突,你最好也不要这么做。根据定义,表C 与一般
    的表一样有正常的表现,不过我们可以显式地改变它的行为。下面,在这些表上尝试一些DML,看看会发
    生什么:
    由于约束是IMMEDIATE 模式,这个UPDATE 会失败。下面换个模式再试一次:
    现在更新成功了。为了便于说明,下面将显示如何在提交前显式地检查了一个延迟约束,才中了解
    我们所做的修改与业务规则是否一致(换句话说,检查目前确实没有违反约束)。应该在提交之前或者在
    6 )
    7 /
    Table created.
    ops$tkyte@ORA10G> insert into p values ( 1 );
    1 row created.
    ops$tkyte@ORA10G> insert into c values ( 1 );
    1 row created.
    ops$tkyte@ORA10G> update p set pk = 2;
    update p set pk = 2
    *
    ERROR at line 1:
    ORA-02292: integrity constraint (OPS$TKYTE.C_FK) violated - child record found
    ops$tkyte@ORA10G> set constraint c_fk deferred;
    Constraint set.
    ops$tkyte@ORA10G> update p set pk = 2;
    1 row updated.
    320
    / 849
    把控制交给程序的另外某个部分(这一部分可能不希望有延迟约束)之前做这个工作,这是一个很好的主
    意:
    不出所料,它会失败,并立即返回一个错误,因为我们知道以上更新会违反约束。对P 的UPDATE 没
    有回滚(否则会违反语句级原子性);它仍在进行。还要注意,我们的事务仍把C_FK 当作延迟约束,因为
    SET CONSTRAINT 命令失败了。下面继续将UPDATE 级联到C:
    这就是级联更新的做法。注意,要延迟一个约束,必须这样来创建它们:先将其删除,再重新创建约
    束,这样才能把不可延迟的约束改变为可延迟约束。

    ---------------------------------------Example----------------------------------------------------

    create table p
     ( pk int primary key )
     
     --Normally 
       create table c
     ( fk constraint c_fk
     references p(pk))
     
     --Deferrable
      create table c
     ( fk constraint c_fk
     references p(pk)
     deferrable
     initially immediate)
     
     
     set constraint c_fk deferred
     
     insert into p values ( 1 );
     
     insert into c values ( 1 );
     
     update c set fk=2;
     
      update p set pk=2;

  • 相关阅读:
    DevOps实施方法论,为什么大企业一定要使用DevOps?
    SpringCloudAlibaba基础入门,基于Nacos构建分布式与配置,Sentinel服务治理
    艾编程Java进阶架构师必看:15次架构演进详解
    实战笔记:来一起探究下Kafka是如何实现万亿级海量数据的高并发写入的?
    520疯狂之后我彻底蒙了,老板让我做技术选型,数据处理选kafka还是RocketMQ?
    如何实现Redis数据持久化以及内存管理之缓存过期机制
    SpringBoot源码深度解析
    分布式缓存Redis高级应用实战:为什么要用缓存机制
    全面上云实战教程:基于阿里云安装配置部署docker详解
    Solr学习笔记(2)—— solr-7.0.0 安装与目录说明
  • 原文地址:https://www.cnblogs.com/tracy/p/2186251.html
Copyright © 2020-2023  润新知