鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 数据库 > mssql > >

T-SQL基础之外键约束

来源:互联网 作者:佚名 时间:2018-03-04 11:09
首先创建测试表 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依赖于t

首先创建测试表

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);
View Code
消息 547,级别 16,状态 0,第 1INSERT 语句与 FOREIGN KEY 约束"fk_id11"冲突。该冲突发生于数据库"test",表"dbo.test01", column 'id1'。
语句已终止。
View Code

如果在创建外键之前就已经在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);
View Code
消息 547,级别 16,状态 0,第 1ALTER TABLE 语句与 FOREIGN KEY 约束"fk_id11"冲突。该冲突发生于数据库"test",表"dbo.test01", column 'id1'
View Code

此时可以通过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;
View Code
消息 547,级别 16,状态 0,第 1UPDATE 语句与 REFERENCE 约束"fk_id11"冲突。该冲突发生于数据库"test",表"dbo.test02", column 'id11'。
语句已终止。
View Code

此时我们可以通过级联操作来同步删除或修改两个表中的数据。

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

 

网友评论
<