zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    HTML DOM教程 14HTML DOM Document 对象
    HTML DOM教程 19HTML DOM Button 对象
    HTML DOM教程 22HTML DOM Form 对象
    HTML DOM教程 16HTML DOM Area 对象
    ubuntu 11.04 问题 小结
    VC6.0的 错误解决办法 小结
    boot.img的解包与打包
    shell里 截取字符串
    从零 使用vc
    Imagemagick 对图片 大小 和 格式的 调整
  • 原文地址:https://www.cnblogs.com/tracy/p/2186251.html
Copyright © 2011-2022 走看看