首先创建测试表
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则是相应数据修改为默认值。
时间: 2024-10-05 19:41:28