我們先在SQL Server數據庫中,建立一張Students表:
CREATE TABLE [dbo].[Students]( [ID] [int] IDENTITY(1,1) NOT NULL, [StudentCode] [nvarchar](50) NULL, [Name] [nvarchar](50) NULL, [Age] [int] NULL, [Sex] [nvarchar](5) NULL, CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY], CONSTRAINT [IX_UniqueStudentCode] UNIQUE NONCLUSTERED ( [StudentCode] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO
該表的主鍵是列ID,該表的唯一鍵IX_UniqueStudentCode要求列StudentCode不能有重復值,但是列StudentCode可以為空值(NULL)。
首先我們插入四條數據到Students表中:
INSERT INTO [dbo].[Students]([StudentCode],[Name],[Age],[Sex]) VALUES (N'S001',N'Jim',15,N'M'), (N'S002',N'Tom',16,N'F'), (N'S003',N'Bill',15,N'M'), (NULL,N'Jerry',15,N'M')
可以看到我們在最后第四條數據中,給列StudentCode插入了空值(NULL)。
接着我們再插入一條列StudentCode為空值(NULL)的數據到Students表:
INSERT INTO [dbo].[Students]([StudentCode],[Name],[Age],[Sex]) VALUES (NULL,N'Clark',16,N'M')
會發現SQL Server報錯,錯誤如下:
Msg 2627, Level 14, State 1, Line 1
Violation of UNIQUE KEY constraint 'IX_UniqueStudentCode'. Cannot insert duplicate key in object 'dbo.Students'. The duplicate key value is (<NULL>).
The statement has been terminated.
從錯誤中,我們可以看到,我們插入的數據違反了唯一鍵約束IX_UniqueStudentCode,插入了重復的空值(NULL)到Students表。
所以SQL Server的唯一鍵和唯一索引會將空值(NULL)也算作重復值,我們可以將上面的唯一鍵IX_UniqueStudentCode刪掉,將其建立為唯一索引:
ALTER TABLE [dbo].[Students] DROP CONSTRAINT [IX_UniqueStudentCode] CREATE UNIQUE NONCLUSTERED INDEX [IX_UniqueStudentCode] ON [dbo].[Students] ( [StudentCode] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] GO
會得到相同的實驗結果。