The ALTER TABLE statement conflicted with the FOREIGN KEY constraint

Sim*_*ice 5 foreign-key sql-server

I am trying to add a new foreign key to an existing table where there is data in the column I am wanting to make a change to.

In dev, I have tried this where data does and does not exist. Where there is no data this works fine.

ALTER TABLE [rpt].ReportLessonCompetency WITH CHECK
ADD CONSTRAINT [FK_Grade_TraineeGrade_Id]
FOREIGN KEY (Grade) REFERENCES [rpt].TraineeGrade(Id)
Run Code Online (Sandbox Code Playgroud)

Where there is data I get the following error

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Grade_TraineeGrade_Id". The conflict occurred in database "T_test", table "Core.Report.TraineeGrade", column 'Id'.

I would be grareful if someone could let me know what I need to do in order to ensure that this works where data does and does not exist as I cannot control if the live database will or will not have any existing data.

Thanks

Simon

Tho*_*ers 13

您收到错误可能是因为您在 [rpt].[ReportLessonCompetency] 表中有孤立的记录。孤立记录是子表中的记录,在父表中没有相应的父记录。在您的情况下, [rpt].[ReportLessonCompetency] 将包含 [rpt].TraineeGrade(Id) 表中不存在的 [Grade] 值。

有 2 个选项可以创建外键(尽管 imo 只有 1 个有效选项)。

清理您的数据
首先,您可以在子表中查找没有相应父记录的记录。接下来,您应该删除/更新子表中的那些记录,或者将缺少的父记录添加到您的父表中。之后,您将能够创建外键约束。这是迄今为止最好的选择,因为您的引用完整性得到保证并且您的外键将被信任。
您可以通过执行以下查询来查找孤立记录:

SELECT *
FROM [rpt].ReportLessonCompetency rlc
WHERE NOT EXISTS
(
    SELECT 1 
    FROM [rpt].TraineeGrade tg
    WHERE tg.Id = rlc.Grade
)
Run Code Online (Sandbox Code Playgroud)

WITH NOCHECK
一种选择是使用WITH NOCKECK. SQL Server 将在不验证表中现有数据的情况下创建外键。当您在子表中更新/插入数据时,仍将检查这些记录。因此,您的外键将被标记为不受信任,并且查询优化器不会考虑您的约束来生成执行计划。您可以
在此处找到有关如何影响性能的示例。