首先創建測試表
use test; create table test01 ( id1 int not null, id2 int not null ); create table test02 ( id11 int not null, id22 int not null ); alter table test01 add constraint pk_id1 primary key(id1);
考慮如下關係
test02表中的id11依賴於test01中的id1,因此爲test02創建外鍵
alter table test02 add constraint fk_id11 foreign key(id11) references test01(id1);
注意:test01表中的id1必須爲主鍵或者唯一索引,否則無法創建基於id1的外鍵。
創建外鍵之後,我們將發現無法在test02中輸入不在test01的id1範圍內的數據
insert into test02 values(1,1);
消息 547,級別 16,狀態 0,第 1 行 INSERT 語句與 FOREIGN KEY 約束"fk_id11"衝突。該衝突發生於數據庫"test",表"dbo.test01", column 'id1'。 語句已終止。
如果在創建外鍵之前就已經在test02中有了不在test01的id1範圍內的數據,則創建外鍵會失敗
alter table test02 drop constraint fk_id11; insert into test02 values(1,1); alter table test02 add constraint fk_id11 foreign key(id11) references test01(id1);
消息 547,級別 16,狀態 0,第 1 行 ALTER TABLE 語句與 FOREIGN KEY 約束"fk_id11"衝突。該衝突發生於數據庫"test",表"dbo.test01", column 'id1'。
此時可以通過with nocheck選項,強制跳過現有數據檢查
alter table test02 with nocheck add constraint fk_id11 foreign key(id11) references test01(id1);
雖然在test01表中id1設置爲了主鍵,不允許null,但是在test02表中的id2可以允許null值
alter table test02 alter column id11 int null; insert into test02 values(null,1);
當我們從test01進行刪除或修改數據操作的時候,如果在test02表中也有相關數據則會報錯,拒絕操作;
insert into test01 values(2,1); insert into test02 values(2,1); update test01 set id1=3 where id1=2;
消息 547,級別 16,狀態 0,第 1 行 UPDATE 語句與 REFERENCE 約束"fk_id11"衝突。該衝突發生於數據庫"test",表"dbo.test02", column 'id11'。 語句已終止。
此時我們可以通過級聯操作來同步刪除或修改兩個表中的數據。
alter table test02 drop constraint fk_id11; alter table test02 with nocheck add constraint fk_id11 foreign key(id11) references test01(id1) on update cascade; update test01 set id1=3 where id1=2;
這樣test02表中的數據也會相應修改
級聯操作包括cascade/set null/set default,跟在操作on delete/on update之後
其中cascade是做相同修改;set null是test02表中相應數據修改爲null;set default則是相應數據修改爲默認值。