Oracle外來鍵級聯刪除和級聯更新

2022-09-01 08:36:11 字數 4275 閱讀 5670

oracle在外鍵的刪除上有no action(類似restrict)、cascade和set null三種行為。

以下以學生-班級為例說明不同情況下的外來鍵刪除,學生屬於班級。班級的主鍵是學生的外來鍵。

-- 班級表

crate table tb_class

( id number not null, --班級主鍵

name varchar2(50), --班級名稱

constraint pk_tb_class primary key (id)

);-- 學生表

create table tb_student

( id number not null, --學生主鍵

name varchar2(50), --學生姓名

class_id number, --學生所屬班級,外來鍵

--主鍵約束

constraint pk_tb_student primary key (id),

--外來鍵約束

--設定級聯刪除為no action

constraint fk_tb_student_class_id foreign key (class_id) references tb_class (id)

);-- 加入班級資料

insert into tb_class (id, name) values (1, '一班');

insert into tb_class (id, name) values (2, '二班');

insert into tb_class (id, name) values (3, '三班');

-- 加入學生資料

insert into tb_student (id, name, class_id) values (1, '小明', 1);

insert into tb_student (id, name, class_id) values (2, '小剛', 1);

insert into tb_student (id, name, class_id) values (3, '小王', 1);

insert into tb_student (id, name, class_id) values (4, '二明', 2);

insert into tb_student (id, name, class_id) values (5, '二剛', 2);

insert into tb_student (id, name, class_id) values (6, '二王', 2);

insert into tb_student (id, name, class_id) values (7, '大明', 3);

insert into tb_student (id, name, class_id) values (8, '大剛', 3);

insert into tb_student (id, name, class_id) values (9, '大王', 3);

初始班級資料

初始學生資料

no action指當刪除主表中被引用列的資料時,假設子表的引用列中包括該值。則禁止該操作執行。

如今學生外來鍵級聯刪除是no action。執行刪除班級操作。

--刪除三班

delete from tb_class where id=3;

oracle會提示違反完整性約束,如圖所看到的。

假設想要刪除三班。必須先刪除三班的學生。

--刪除三班學生

delete from tb_student where class_id=3;

--刪除三班

delete from tb_class where id=3;

set null指當刪除主表中被引用列的資料時。將子表中對應引用列的值設定為null值。

set null有個前提就是外來鍵引用列必須能夠設定為null。

把學生表(tb_student)的外來鍵刪除行為改為set null。oracle似乎沒有modify constraint操作。僅僅能先刪除外來鍵。然後建立新的。

--刪除學生表(tb_student)表的外來鍵

alter table tb_student drop constraint fk_tb_student_class_id;

--刪除加入on delete set null外來鍵

alter table tb_student add constraint fk_tb_student_class_id foreign key (class_id) references tb_class (id) on delete set null;

--刪除一班

delete from tb_class where id=1;

因為外來鍵的on delete是set null。所以當刪除一班時,一班學生的class_id被設定為null,如圖所看到的。

cascade指當刪除主表中被引用列的資料時,級聯刪除子表中對應的資料行。

把學生表(tb_student)的外來鍵刪除行為改為cascade。

--刪除tb_student表上的no action外來鍵

alter table tb_student drop constraint fk_tb_student_class_id;

--刪除加入on delete cascade外來鍵

alter table tb_student add constraint fk_tb_student_class_id foreign key (class_id) references tb_class (id) on delete cascade;

--刪除二班

delete from tb_class where id=2;

因為外來鍵的on delete是cascade。所以當刪除二班時,二班下的學生也會被刪除。

oracle本身並不支援外來鍵的級聯更新,只是能夠依照例如以下方法達到級聯更新的效果。

首先要先了解oracle延遲約束和非延遲約束。非延遲約束就是在改動記錄的時候會立馬進行約束條件的檢視,是否由於違反了某些約束條件而不能執行改動。延遲約束不會在剛進行改動的時候進行約束檢視,僅僅有提交的時候才會檢查。oracle的級聯更新就是使用這個特性來實現的。

oracle的外來鍵預設是非延遲約束。改動學生的外來鍵為延遲約束。

--刪除學生表(tb_student)上的已有外來鍵

alter table tb_student drop constraint fk_tb_student_class_id;

--加入延遲約束外來鍵

alter table tb_student add constraint fk_tb_student_class_id foreign key (class_id) references tb_class (id) on delete cascade deferrable;

設定觸發器。當班級表(tb_class)的主鍵改變了,就更新學生表(tb_student)的外來鍵(class_id)。

create or replace trigger tgr_tb_class_update 

after update of id on tb_class

for each row

begin

if :old.id<>:new.id then

update tb_student set class_id=:new.id where class_id=:old.id;

end if;

end;

注意:oracle外來鍵級聯更新方法能夠用於外來鍵和外來鍵引用的主鍵在不同表上。只是會常常遇到下面情況,就是在資料庫中儲存具有層級關係的資料時。表的外來鍵引用同乙個表的主鍵。這時候無法用觸發器實現級聯更新。

Oracle外來鍵級聯刪除和級聯更新

oracle在外鍵的刪除上有no action 類似restrict cascade和set null三種行為。下面以學生 班級為例說明不同情況下的外來鍵刪除,學生屬於班級,班級的主鍵是學生的外來鍵。班級表 crate table tb class id number not null,班級主鍵 n...

Oracle外來鍵級聯刪除和級聯更新

oracle在外鍵的刪除上有no action 類似restrict cascade和set null三種行為。下面以學生 班級為例說明不同情況下的外來鍵刪除,學生屬於班級,班級的主鍵是學生的外來鍵。班級表 crate table tb class id number not null,班級主鍵 n...

Oracle外來鍵級聯刪除和級聯更新

oracle外來鍵級聯刪除和級聯更新 oracle在外鍵的刪除上有no action 類似restrict cascade和set null三種行為。1.1 no action no action指當刪除主表中被引用列的資料時,如果子表的引用列中包含該值,則禁止該操作執行。現在學生外來鍵級聯刪除是n...