在Oracle的主外键表之间实现级联更新

前段时间有问到这个问题,有位仁兄告诉我说使用延迟约束可以实现,但一直没有实践一下,今天突然想起,便做了一下试验,果然如此!呵呵,现将过程共享一下
问题:在oracle里建外键的时候可以指定随主表的主键记录删除而删除或改为NULL或不做任何操作这样三种选择,因此我们可以很容易实现比sqlserver更为灵活的级联删除功能,但在sqlserver里还有一种功能叫级联更新,即我修改了主表的主键值,从表相关的外键值也随之更新,而oracle里没有!虽然建立主外键关系之后,主表的主键值不应该经常修改,可有时候需求就是这么怪怎么办?
解决方式:
1.在建外键时使用延迟约束,即完整性会等到提交时再检查
2.在主表建立触发器,after update时判断主键是否被修改,如果发现主键被修改,则主动将从表的外键值进行相应的修改
目的:在程序里修改主表主键值时变得很简单了,只要直接修改提交即可,无需理会从表中的外键值是否正确匹配了。
试验过程:
sys@182.183> conn scott/tiger
Connected.
scott@182.183> create table t1(a varchar2(5) primary key);

Table created.

scott@182.183> create table t2(k number primary key,a varchar2(5),constraint fk_t2 foreign key(a) references t1(a) on delete cascade initially deferred);

Table created.

scott@182.183> create or replace trigger t1_update_cascade
  2  after update on t1
  3  for each row
  4  begin
  5  if :old.a<>:new.a then
  6  update t2 set a=:new.a where a=:old.a;
  7  end if;
  8  end;
  9  /

Trigger created.

scott@182.183> insert into t1 values('11111');

1 row created.

scott@182.183> insert into t1 values('22222');

1 row created.

scott@182.183> insert into t2 values(1,'11111');

1 row created.

scott@182.183> insert into t2 values(2,'11111');

1 row created.

scott@182.183> insert into t2 values(3,'22222');

1 row created.

scott@182.183> commit;

Commit complete.

scott@182.183> select * from t1;

A
-----
11111
22222

scott@182.183> select * from t2;

         K A
---------- -----
         1 11111
         2 11111
         3 22222

scott@182.183> update t1 set a='33333' where a='22222';--级联更新

1 row updated.

scott@182.183> commit;

Commit complete.

scott@182.183> select * from t1;

A
-----
11111
33333

scott@182.183> select * from t2;

         K A
---------- -----
         1 11111
         2 11111
         3 33333

scott@182.183> delete t1 where a='11111';--级联删除,这个本来就很容易实现的

1 row deleted.

scott@182.183> commit;

Commit complete.

scott@182.183> select * from t1;

A
-----
33333

scott@182.183> select * from t2;

         K A
---------- -----
         3 33333

转载于:https://www.cnblogs.com/yangdihuan/archive/2011/04/14/2016017.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值