Oracle系列--級聯刪除和級聯更新


必須聲明:此博客轉載於Oracle外鍵級聯刪除和級聯更新 http://www.2cto.com/database/201507/417496.html

鑒於此前收藏的精彩博客無料被刪除了,很是痛心,所以還是要復制一下

一、級聯刪除

Oracle在外鍵的刪除上有NO ACTION(類似RESTRICT)、CASCADE和SET NULL三種行為。

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

 1 -- 班級表
 2 CRATE TABLE TB_CLASS
 3 (
 4   ID    NUMBER NOT NULL, --班級主鍵
 5   NAME  VARCHAR2(50), --班級名稱
 6   CONSTRAINT PK_TB_CLASS PRIMARY KEY (ID)
 7 );
 8  
 9 -- 學生表
10 CREATE TABLE TB_STUDENT
11 (
12   ID        NUMBER NOT NULL,   --學生主鍵
13   NAME      VARCHAR2(50),      --學生姓名
14   CLASS_ID  NUMBER,            --學生所屬班級,外鍵
15    
16   --主鍵約束
17   CONSTRAINT PK_TB_STUDENT PRIMARY KEY (ID),
18    
19   --外鍵約束
20   --設置級聯刪除為NO ACTION
21   CONSTRAINT FK_TB_STUDENT_CLASS_ID FOREIGN KEY (CLASS_ID) REFERENCES TB_CLASS (ID)
22 );
23  
24 -- 添加班級數據
25 INSERT INTO TB_CLASS (ID, NAME) VALUES (1, '一班');
26 INSERT INTO TB_CLASS (ID, NAME) VALUES (2, '二班');
27 INSERT INTO TB_CLASS (ID, NAME) VALUES (3, '三班');
28  
29 -- 添加學生數據
30 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (1, '小明', 1);
31 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (2, '小剛', 1);
32 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (3, '小王', 1);
33 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (4, '二明', 2);
34 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (5, '二剛', 2);
35 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (6, '二王', 2);
36 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (7, '大明', 3);
37 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (8, '大剛', 3);
38 INSERT INTO TB_STUDENT (ID, NAME, CLASS_ID) VALUES (9, '大王', 3);

1、NO ACTION

NO ACTION指當刪除主表中被引用列的數據時,如果子表的引用列中包含該值,則禁止該操作執行。

現在學生外鍵級聯刪除是NO ACTION,執行刪除班級操作。

2、SET NULL

SET NULL指當刪除主表中被引用列的數據時,將子表中相應引用列的值設置為NULL值。SET NULL有個前提就是外鍵引用列必須可以設置為NULL。

把學生表(TB_STUDENT)的外鍵刪除行為改為SET NULL。ORACLE似乎沒有MODIFY CONSTRAINT操作,只能先刪除外鍵,然后創建新的。

3、CASCADE

CASCADE指當刪除主表中被引用列的數據時,級聯刪除子表中相應的數據行。

把學生表(TB_STUDENT)的外鍵刪除行為改為CASCADE。

二、級聯更新

Oracle本身並不支持外鍵的級聯更新,不過可以按照如下方法達到級聯更新的效果。

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

Oracle的外鍵默認是非延遲約束,修改學生的外鍵為延遲約束。

1 --刪除學生表(TB_STUDENT)上的已有外鍵
2 ALTER TABLE TB_STUDENT DROP CONSTRAINT FK_TB_STUDENT_CLASS_ID;
3 --添加延遲約束外鍵
4 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)。

1 CREATE OR REPLACE TRIGGER TGR_TB_CLASS_UPDATE 
2 AFTER UPDATE OF ID ON TB_CLASS
3 FOR EACH ROW
4 BEGIN
5   IF :OLD.ID<>:NEW.ID THEN
6     UPDATE TB_STUDENT SET CLASS_ID=:NEW.ID WHERE CLASS_ID=:OLD.ID;
7   END IF;
8 END;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM