MSSQL:在创建表时添加唯一约束并允许 NULL

Pow*_*ave 1 sql-server

抱歉,可能是菜鸟问题,但我找不到答案。

CREATE TABLE SomeTable
(
   Id DECIMAL NOT NULL,
   UserIdentifier NVARCHAR(100) NULL,
   PRIMARY KEY (Id),
   ????
)
Run Code Online (Sandbox Code Playgroud)

如何在 CREATE TABLE 中的 UserIdentifier 列上添加允许 Null 的唯一键约束?

我知道在 CREATE TABLE 之外你可以说 ... WHERE UserIdentifier IS NOT NULL,但是在里面呢?

谢谢!

use*_*983 8

假设您想要多行包含 value NULL,您将无法使用 a UNIQUE CONSTRAINT,因为NULL它仍然是一个值(即使是未知的值)。例如:

CREATE TABLE dbo.YourTable (UserIdentifier nvarchar(100) NULL,
                            CONSTRAINT UC_UI UNIQUE (UserIdentifier));
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL);
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL);
GO
DROP TABLE dbo.YourTable;
Run Code Online (Sandbox Code Playgroud)

请注意,第二个INSERT失败了。

但是,您可以使用条件UNIQUE INDEX

CREATE TABLE dbo.YourTable (UserIdentifier nvarchar(100) NULL);

CREATE UNIQUE NONCLUSTERED INDEX UI_UI ON dbo.YourTable(UserIdentifier) WHERE UserIdentifier IS NOT NULL;

GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL); -- Success
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL); --Success
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(N'Steve'); --Success
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(N'Jayne'); --Success
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(N'Steve'); --Fails
GO
DROP TABLE dbo.YourTable;
Run Code Online (Sandbox Code Playgroud)

正如 Jeroen Mostert 在评论中所说,您不能在创建表的过程中创建唯一索引;它必须在单独的语句中创建。没有语法可以创建UNIQUE INDEXas 语句的一部分CREATE TABLE

您可以在 SQL Server 2016+ 中使用以下任一语法创建此内联(在最初编写此答案时尚未记录):

CREATE TABLE dbo.YourTable (UserIdentifier nvarchar(100) NULL,
                            CONSTRAINT UC_UI UNIQUE (UserIdentifier));
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL);
GO
INSERT INTO dbo.YourTable (UserIdentifier)
VALUES(NULL);
GO
DROP TABLE dbo.YourTable;
Run Code Online (Sandbox Code Playgroud)

db<>小提琴 2014 , db<>小提琴 2016