前段时间有问到这个问题,有位仁兄告诉我说使用延迟约束可以实现,但一直没有实践一下,今天突然想起,便做了一下试验,果然如此!呵呵,现将过程共享一下
问题:在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
posted on 2011-04-14 14:44  嘿^ Lynn  阅读(2025)  评论(0编辑  收藏  举报