如果您希望值是唯一的,除非两者都为空,这意味着您希望它们是唯一的,只要至少一个值不为空。您对索引的过滤器有一个AND
,但您需要一个OR
.
CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON dbo.MyTable(col1, col2)
WHERE col1 IS NOT NULL OR col2 IS NOT NULL -- (note: doesn't work)
但是……你不能这样做。SQL Server只允许您创建带有 AND 条件的 where 子句。您也不能使用持久计算列来执行此操作。
相反,您可以做的是在原始表上创建一个索引视图,然后将唯一索引放在该表上。它有点重量级,但它应该可以工作。
所以......借用@Meff的脚本,你正在看类似的东西:
CREATE TABLE dbo.MyTable
(
Col1 INT NULL,
Col2 INT NULL
)
GO
CREATE VIEW dbo.MyTableUniqueView WITH SCHEMABINDING AS
SELECT Col1, Col2 FROM dbo.MyTable
WHERE Col1 IS NOT NULL OR Col2 IS NOT NULL
GO
CREATE UNIQUE CLUSTERED INDEX MyTableUniqueIndex
ON dbo.MyTableUniqueView(Col1, Col2)
GO
INSERT INTO MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works
INSERT INTO MyTable(Col1, Col2)
VALUES(NULL, NULL) --Works
SELECT * FROM MyTable
INSERT INTO MyTable(Col1, Col2)
VALUES(1, 1) --Works
INSERT INTO MyTable(Col1, Col2)
VALUES(1, 1) --Fails
INSERT INTO MyTable(Col1, Col2)
VALUES(1, null) --Works
INSERT INTO MyTable(Col1, Col2)
VALUES(1, null) --Fails
SELECT * FROM MyTable
GO
DROP VIEW MyTableUniqueView
DROP TABLE MyTable