INSERT语句与FOREIGN KEY约束问题冲突

时间:2019-07-04 10:49:36

标签: sql sql-server entity-framework tsql ef-migrations

我有下面的脚本,这给了我一个错误: “ INSERT语句与FOREIGN KEY约束“ FK_dbo.PlanShiftAssignments_dbo.User_UserId”发生冲突。冲突发生在数据库“ SWS”的表“ dbo.User”的“ Id”列中。 该语句已终止。”

如您所见,在WHERE子句中,我检查dbo.User中是否存在UserId。错误的其他可能原因是什么?

更新:我还想知道select语句中的哪一行导致错误。在调试此查询的任何建议将不胜感激。我正在使用MS SQL Server Management Studio。

CREATE TABLE [dbo].[PlanShiftAssignments] (
    [PlanShiftId] [uniqueidentifier] NOT NULL,
    [Status] [int] NOT NULL,
    [UserId] [int],
    CONSTRAINT [PK_dbo.PlanShiftAssignments] PRIMARY KEY ([PlanShiftId])
)
CREATE INDEX [IX_PlanShiftId] ON [dbo].[PlanShiftAssignments]([PlanShiftId])
CREATE INDEX [IX_UserId] ON [dbo].[PlanShiftAssignments]([UserId])
ALTER TABLE [dbo].[PlanShiftAssignments] ADD CONSTRAINT [FK_dbo.PlanShiftAssignments_dbo.PlanShifts_PlanShiftId] FOREIGN KEY ([PlanShiftId]) REFERENCES [dbo].[PlanShifts] ([Id])
ALTER TABLE [dbo].[PlanShiftAssignments] ADD CONSTRAINT [FK_dbo.PlanShiftAssignments_dbo.User_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User] ([Id])
insert into dbo.PlanShiftAssignments
                    select ps.Id as PlanShiftId, ISNULL(ps.AssigneeId, psi.UserId) as UserId, ISNULL(psi.[Status], 1) as [Status] from dbo.PlanShifts ps
                    left join 
                    dbo.PlanShiftInvitations psi
                    on ps.Id = psi.PlanShiftId
                    where (psi.UserId is not null and psi.UserId IN (select Id from dbo.[User])) 
                    or (ps.AssigneeId is not null and ps.AssigneeId IN (select Id from dbo.[User]))

3 个答案:

答案 0 :(得分:3)

确保您始终始终在每个INSERT语句中包含目标的列列表。

insert into dbo.PlanShiftAssignments (
    PlanShiftId,
    UserId,
    Status)
SELECT
    ps.Id as PlanShiftId, 
    ISNULL(ps.AssigneeId, psi.UserId) as UserId, 
    ISNULL(psi.[Status], 1) as [Status]
...

您的表的创建顺序为PlanShiftId, Status, UserId,而当前SELECT的列顺序为PlanShiftId, UserId, Status,因此很混乱。

答案 1 :(得分:1)

如果UserIdAssigneeId在基础表中尚未引用User,则您有一个奇怪的数据模型。

无论如何,您的where子句是

where (psi.UserId is not null and psi.UserId IN (select Id from dbo.[User])) or
      (ps.AssigneeId is not null and ps.AssigneeId IN (select Id from dbo.[User]))

这打开了psi.UserId匹配但ps.AssigneeId不匹配的可能性。

为确保逻辑匹配,请使用与select中相同的表达式:

where coalesce(ps.AssigneeId, psi.UserId) in (select Id from dbo.[User])

答案 2 :(得分:0)

是否可能是因为您在WHERE子句中指定了OR,所以AssigneeId或UserId不在User表中,所以不在另一个表中,因此使FK约束无效。