Sql server 可以在可为空的字段上设置唯一约束吗?

Sql server 可以在可为空的字段上设置唯一约束吗?,sql-server,sql-server-2008,Sql Server,Sql Server 2008,我有一张桌子,有下面的桌子 CREATE TABLE MyTable ( ID INTEGER DEFAULT(1,1), FirstIdentifier INTEGER NULL, SecondIdentifier INTEGER NULL, --.... some other fields ..... ) 现在FirstIdentifier和SecondIdentifier都是唯一的,但可以为空。我想对每一列都设置一

我有一张桌子,有下面的桌子

CREATE TABLE MyTable  
(  
  ID                INTEGER DEFAULT(1,1),  
  FirstIdentifier   INTEGER NULL,  
  SecondIdentifier  INTEGER NULL,  
--.... some other fields .....  
) 

现在FirstIdentifier和SecondIdentifier都是唯一的,但可以为空。我想对每一列都设置一个唯一的约束,但不能这样做,因为它可以为NULL,并且可以有两行,其中的NULL值将使该唯一约束失效。关于如何在模式级别解决它,您有什么想法吗?

您可以使用筛选索引作为唯一约束

create unique index ix_FirstIdentifier on MyTable(FirstIdentifier) 
  where FirstIdentifier is not null

你的问题有点让人困惑。首先,在模式定义中,您说不允许列包含null值,但在描述中,您说它们可以为null

无论如何,假设您的模式错误,并且您确实希望列允许空值,SQL Server允许您通过将WHERE IS NOT null添加到约束中来实现这一点

create unique index ix_FirstIdentifier on MyTable(FirstIdentifier) 
  where FirstIdentifier is not null
大致如下:

CREATE UNIQUE NONCLUSTERED INDEX IDX_my_index
ON MyTable (firstIdentifier)
WHERE firstIdentifier IS NOT NULL

对字段执行筛选后的唯一索引:

CREATE UNIQUE INDEX ix_IndexName ON MyTable (FirstIdentifier, SecondIdentifier)
   WHERE FirstIdentifier IS NOT NULL
   AND SecondIdentifier IS NOT NULL

它将允许
NULL
,但仍然强制唯一性。

您可以在创建索引上使用筛选器谓词

创建[唯一][聚集的|非聚集的]索引_名称
在(列[ASC | DESC][,…n])上
[包括(列名称[,…n])]
[其中
]

[WITH([,…n])]
[关于{分区\方案\名称(列\名称)
|文件组名称
|默认值
}
]
{FILESTREAM\u文件组\u名称上的[FILESTREAM\u| 分区_方案_名称|“NULL”}]

[;]

其中
通过指定 要包含在索引中的行。筛选的索引必须是 表上的非聚集索引。为数据创建筛选的统计信息 已筛选索引中的数据行

筛选器谓词使用简单的比较逻辑,无法引用 计算列、UDT列、空间数据类型列或 hierarchyID数据类型列。不允许使用空文本进行比较 允许使用比较运算符。使用的值为NULL且不为NULL 而不是操作员

下面是 生产物料清单表:


其中StartDate>20040101'和EndDate正如一些人所建议的那样,使用过滤索引可能是获得所需内容的方法


但是书中对你直接问题的回答是,如果一个列有一个唯一的索引,那么它可以为null,但是它只能有一行在该字段中有null值。任何多于一个null都会违反索引。

添加一些触发器以捕获插入/更新,并在该级别执行唯一性检查?制作FirstIdentifier和Secondidentifier复合键如何?是否尝试创建
候选键{FirstIdentifier,Secondidentifier}
候选键1{FirstIdentifier}
Candidate Key2{SecondIdentifier}
您能否更具体地描述一下目前的情况,以及您想要实现的目标。我看到模式不是空的(所以,它不是空的),所以唯一约束应该在模式上找到,因为它现在是这样的。@康拉德:我在考虑候选键1{FirstIdentifier},候选键2{SecondIdentifier}