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则是相应数据修改为默认值。

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