SQL唯一约束允许使用空值进行违反

时间:2019-08-31 10:56:08

标签: sql sql-server-express localdb

我有一个表,该表在“ MenuId”,“ Name”和“ ParentId”三列上具有非聚集的唯一索引。

问题是,我可以在表中插入违反唯一约束的多行-当ParentId设置为NULL时,如下所示。

如果我尝试添加重复的行并且ParentId不为null,则唯一约束将按预期工作。

我对唯一索引的理解是,它只会允许参与索引的列的唯一唯一组合,因此我希望在下图中可以插入第一行,但它应该引发异常用于在插入第二行(第三行)时违反索引-但这不是。

我要去哪里错了?

我正在使用SQL LocalDb。

Table in LocalDb

更新:我正在使用EF Core从代码生成数据库,并且在这种情况下,似乎使用WHERE子句创建了唯一约束,以在ParentId或Name为NULL时忽略:

CREATE UNIQUE NONCLUSTERED INDEX [IX_MenuItem_MenuId_ParentId_Name]
    ON [dbo].[MenuItem]([MenuId] ASC, [ParentId] ASC, [Name] ASC) 
WHERE ([ParentId] IS NOT NULL AND [Name] IS NOT NULL);

令人尴尬的是,当我在SQL Server资源管理器属性窗口中浏览“唯一性”约束时,此WHERE子句并不明显-我只是检查了“唯一性”约束是否存在,以及我希望包含在其中的列-但这还不够。谢谢下面的评论者,他无法复制并使我实际上检查此WHERE子句出现的索引的脚本。我现在将问题移至与EF为什么在我的案例中产生此问题有关的问题: https://github.com/aspnet/EntityFrameworkCore/issues/17586

2 个答案:

答案 0 :(得分:1)

感谢@萧为元,它促使我更详细地查看“唯一性”约束,而不仅仅是在属性窗口中!

UNIQUE索引具有WHERE子句,该子句导致它忽略对父ID或名称具有NULL值的记录:

CREATE UNIQUE NONCLUSTERED INDEX [IX_MenuItem_MenuId_ParentId_Name]
    ON [dbo].[MenuItem]([MenuId] ASC, [ParentId] ASC, [Name] ASC) 
WHERE ([ParentId] IS NOT NULL AND [Name] IS NOT NULL);

这是由EF产生的-这是您依靠ORM为您做事并假设他们做您想要的事情时遇到的问题的类型- s手腕

答案 1 :(得分:0)

将-1作为默认值设置为Camera
或者

ParentId
相关问题