该列引用自身。
因此,添加行本身可以保证存在匹配的行。这种约束永远不会失败。
事实上,查看执行计划 SQL Server 意识到了这一点,甚至懒得检查它。没有assert
操作员在场。

如果我们创建一个更典型的 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) /*Can't violate constraint as NULL*/
insert into EMP2 values(2,1) /*Can violate constraint as NOT NULL*/

如果您尝试多行,则会将阻塞线轴添加到计划中,因此在插入所有行之前不会检查约束。
insert into EMP2 values (3,2),(4,3) /*Can violate constraint - multiple rows*/

并且只是为了完整起见,正如评论中提出的那样,查看插入到具有 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)
在这种情况下,不会将线轴添加到计划中,因为它插入每一行而不是最后插入所有行,因此它可以在行失败时更早回滚(最终结果将相同)
