表COLORS是父表,ID列是主键
表FRUITS是子表,COLORID是外键
CREATE TABLE TEST.COLORS
(
ID INTEGER NOT NULL,
COLOR VARCHAR(20) NOT NULL
);
CREATE TABLE TEST.FRUITS
(
ID VARCHAR(20) NOT NULL,
COLORID INTEGER NOT NULL
);
INSERT INTO TEST.COLORS VALUES(1,'RED');
INSERT INTO TEST.COLORS VALUES(2,'BLUE');
INSERT INTO TEST.COLORS VALUES(3,'YELLOW');
INSERT INTO TEST.COLORS VALUES(4,'GREEN');
INSERT INTO TEST.COLORS VALUES(5,'ORANGE');
INSERT INTO TEST.FRUITS VALUES('STRAWBERRY',1);
INSERT INTO TEST.FRUITS VALUES('BLUEBERRY',2);
INSERT INTO TEST.FRUITS VALUES('BANANA',3);
INSERT INTO TEST.FRUITS VALUES('PEAR',4);
ALTER TABLE "TEST"."COLORS"
ADD PRIMARY KEY
("ID");
ALTER TABLE "TEST"."FRUITS"
ADD CONSTRAINT "FK_FRUITS_COLORS" FOREIGN KEY
("COLORID")
REFERENCES "TEST"."COLORS"
("ID")
ON DELETE RESTRICT
ON UPDATE RESTRICT
ENFORCED
ENABLE QUERY OPTIMIZATION;
在RESTRICT的情况下
(1) UPDATE TEST.COLORS SET ID=ID-1 WHERE ID=1;
Category Timestamp Duration Message Line Position
Error 3/22/2015 8:31:53 AM 0:00:00.000 DB2 Database Error: ERROR [23001] [IBM][DB2/NT64] SQL0531N The parent key in a parent row of relationship "TEST.FRUITS.FK_FRUITS_COLORS" cannot be updated. SQLSTATE=23001
43 0
执行不成功,如果更新成功就会让子表的参照列的值丢失,无法保证参照完整性
(2) UPDATE TEST.COLORS SET ID=6 WHERE ID=5;
这个会执行成功,原因是ID为5的值并没有被子表所引用。
(3) UPDATE TEST.COLORS SET ID=ID - 1;
Category Timestamp Duration Message Line Position
Error 3/22/2015 8:35:46 AM 0:00:00.000 DB2 Database Error: ERROR [23001] [IBM][DB2/NT64] SQL0531N The parent key in a parent row of relationship "TEST.FRUITS.FK_FRUITS_COLORS" cannot be updated. SQLSTATE=23001
43 0
这个执行不成功。
如果UPDATE RULE是NO ACTION
(3)会执行成功,而(1)和(2)则和RESTRICT情况相同。
做一个简单的总结,RESTRICT和NO ACTION都会保证参照完整性,RESTRICT是不能对主表中被子表引用的外键列进行更新的,但是NO ACTION是可以更新的,只要能保证这个SQL更新主表之后,还能保证主外键约束就可以了。
如果业务逻辑里面,我们能明确的看出,主表的主键列是不能更新的,用RESTRICT,否则用NO ACTION。