sql - SQL 唯一约束允许违反空值
问题描述
我有一个表,它在 3 列“MenuId”、“Name”和“ParentId”上有一个非聚集唯一索引。
问题是,我可以在该表中插入违反唯一约束的多行 - 当 ParentId 设置为 NULL 时,如下所示。
如果我尝试添加重复行并且 ParentId 不为空,则唯一约束将按预期工作。
我对唯一索引的理解是它只允许参与索引的列的单个唯一组合,所以我希望在下图中能够插入第一行,但它应该抛出一个违反的异常插入第二(和第三)行时的索引 - 但事实并非如此。
我哪里错了?
我正在使用 SQL 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 Explorer 属性窗口中探索 Unique 约束时,这个 WHERE 子句并不明显——我只是检查了 Unique 约束是否存在,并且我期望的列包含在其中——但这还不够。感谢下面的评论者,他无法复制并让我实际检查脚本以查找此 WHERE 子句变得明显的索引。我现在已将我的问题转移到与 EF 为什么在我的情况下产生此问题有关的问题: https ://github.com/aspnet/EntityFrameworkCore/issues/17586
解决方案
感谢@萧为元提示我更详细地查看 Unique 约束,而不仅仅是在属性窗口中!
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 为你做事并假设他们做你想做的事情时遇到的问题类型——给自己一巴掌
推荐阅读
- php - 如何通过php正则表达式获取data-cfemail标签内的字符串?
- node.js - Git 询问“请告诉我你是谁”。无法自动检测电子邮件地址?
- excel - 检测文本相同但文本格式不同的单元格之间的差异
- twilio - 是否可以从 Twilio 接收流式音频数据?
- swift - 将处理程序传递给 Swift 中的 UICollectionView 单元格
- r - 逻辑索引中 '=' 和 '==' 的区别
- linux-device-driver - 来自 PL 的 zynq linux IRQ
- html - (index):13 Uncaught ReferenceError: LoginUser is not defined at HTMLButtonElement.onclick
- php - 将1个数组的值合并到另一个键相同的数组
- python - Pandas groupby 函数返回 NaN 值