T-SQL外鍵約束

首先創建測試表

複製代碼

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則是相應數據修改爲默認值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章