该列引用了自身。
因此,添加行本身可以确保存在匹配的行。这个约束永远不会失败。
事实上,在查看执行计划时,SQL Server 意识到这一点,甚至不再检查它。没有出现assert
操作符。
![Plan](https://istack.dev59.com/Qxt66.webp)
如果我们创建一个更典型的Employee表,那么有不同的插入计划可能会违反约束条件,如下所示。
create table EMP2(Eid int primary key, boss_id int null);
alter table EMP2 add constraint fk_EMP2_Eid
foreign key (boss_id) references EMP2(Eid)
insert into EMP2 values(1,null)
insert into EMP2 values(2,1)
![Plan](https://istack.dev59.com/TNPwe.webp)
如果您尝试多行插入,计划将添加阻塞卷轴,因此直到所有行都插入后才会检查约束条件。
insert into EMP2 values (3,2),(4,3)
![Plan](https://istack.dev59.com/vjj4D.webp)
为了完整性,正如在评论中提到的那样,我们来看一下向引用不同表的FK的表插入数据的情况...
CREATE TABLE EmpSalaryHistory
(
Eid INT NOT NULL REFERENCES EMP(Eid),
EffectiveDate DATETIME NOT NULL,
Salary INT,
PRIMARY KEY (Eid,EffectiveDate)
)
INSERT INTO EmpSalaryHistory
VALUES (1,GETDATE(),50000),
(2,GETDATE(),50000)
在这种情况下,计划中不会添加缓存,它可以在插入每一行时进行检查,而不是在最后检查所有内容,因此如果某一行失败,它可以更早地回滚(最终结果将是相同的)。
![Plan](https://istack.dev59.com/EXdkn.webp)
12e2
插入到您的EMP
表中(以及其Eid
列中),那么该值确实存在-因此引用得到满足... - marc_sEmployee(ID INT, ReportsTo INT)
,并且ReportsTo
列会自我引用Employee(ID)
,以便你可以建模员工-->老板关系。但是在同一列上进行自我引用...你的情况是什么,你想要做什么? - marc_s