谁知道如何在两列中都允许使用NULLS创建2列的唯一约束?我的意思是忽略col1 = NULL和col2 = NULL的唯一性,但是如果只有其中一个是NULL,那么让约束工作吗?我找到了如何为单列(How do I create a unique constraint that also allows nulls?)执行此操作,但无法将其用于2列。这是我的脚本,它适用于现有记录(多个NULL,允许NULL),但不允许添加任何新的NULL,NULL记录:
CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON dbo.MyTable(col1, col2)
WHERE col1 IS NOT NULL AND col2 IS NOT NULL
更新:嗯,它允许你添加新的(NULL,NULL)值,所以我错了,但它也允许你添加像(1,NULL),(1,NULL)这样我不喜欢的东西,所以唯一性适用于这种情况,只允许多个(NULL,NULL)。怎么做?
答案 0 :(得分:2)
其他一些肯定不起作用。您的代码/脚本按预期工作:
CREATE TABLE #MyTable
(
Col1 INT NULL,
Col2 INT NULL
)
CREATE UNIQUE NONCLUSTERED INDEX MyIndex ON #MyTable(col1, col2)
WHERE col1 IS NOT NULL AND col2 IS NOT NULL
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
SELECT * FROM #MyTable
DROP TABLE #MyTable
答案 1 :(得分:1)
如果希望值是唯一的,除非两者都为null,这意味着只要至少有一个值不为null,就希望它们是唯一的。您对索引的过滤器有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将only let you create a where clause with AND conditions。你也can't use a persisted computed column来做。
相反,您可以做的是在原始表上创建索引视图,然后将唯一索引放在 上。它有点重量级,但它应该有效。
所以...借用@ 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