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