Альтернативой отфильтрованному индексу, который работает в SQL Server 2000 и более поздних версиях, является индексированное представление .
Что-то вроде:
CREATE VIEW DRI_YourTable_NonNullUnique
WITH SCHEMABINDING
AS
SELECT YourColumn FROM dbo.YourTable WHERE not YourColumn is NULL
GO
CREATE UNIQUE CLUSTERED INDEX IX_DRI_YourTable on DRI_YourTable_NonNullUnique (YourColumn)
Обратите внимание, что вы нене нужно делать ничего особенного после создания этого представления - вам больше не нужно обращаться к нему снова.Это просто вызовет нарушение ограничений, если будет попытка вставить неуникальные значения в базовую таблицу.
@ marc_s - прошу отличаться.Они, разумеется, не учитываются автоматически (при компиляции запросов) в выпусках ниже Enterprise, но они однозначно доступны для создания и работают в качестве усилителей DRI во всех выпусках:
select @@VERSION
create table dbo.T1 (
T1ID int IDENTITY(1,1) not null,
Val1 varchar(10) null,
constraint PK_T1 PRIMARY KEY (T1ID)
)
go
create view dbo.DRI_T1_Val1Unique
with schemabinding
as
select Val1 from dbo.T1 where Val1 is not null
go
create unique clustered index IX_DRI_T1_Val1Unique on dbo.DRI_T1_Val1Unique (Val1)
go
insert into dbo.T1 (Val1)
select 'abc' union all
select null union all
select null
go
insert into dbo.T1 (Val1)
select 'abc'
go
select * from dbo.T1
Результаты:
Microsoft SQL Server 2000 - 8.00.2039 (Intel X86) May 3 2005 23:18:38 Copyright (c) 1988-2003 Microsoft Corporation Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
1 abc
2 NULL
3 NULL
А:
(1 row(s) affected)
(3 row(s) affected)
Msg 2601, Level 14, State 3, Line 1
Cannot insert duplicate key row in object 'DRI_T1_Val1Unique' with unique index 'IX_DRI_T1_Val1Unique'.
The statement has been terminated.
(0 row(s) affected)
(3 row(s) affected)