Pergunta

Eu tenho coluna em uma tabela que permite nulo, mas quero fazer a restrição que o torne nulo ou único ... como posso fazer isso?
Nota: Eu o validei do frontend, mas quero ter um servidor físico no SQL que permita que este desenvolvedor até tente inserir dados

Foi útil?

Solução

An alternative to a filtered index that works on SQL Server 2000 and later is an indexed view.

Something like:

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)

Note that you don't have to do anything special once this view is created - you need never refer to it again. It will simply cause constraint violations to occur, if there is an attempt to insert non-unique values in the base table.

@marc_s - I beg to differ. They're certainly not considered automatically (in query compilation) in editions below Enterprise, but they're definitely creatable, and work as DRI enforcers in all editions:

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

Results:

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

And:

(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)

Outras dicas

Você não pode fazer isso no SQL Server 2005, infelizmente. Um índice exclusivo permite apenas uma linha de valor nulo.

Com o SQL Server 2008, você pode usar um Índice filtrado - Um índice definido apenas em partes das linhas, por exemplo, aquelas que não são nulas. Este é um recurso de 2008, para que você não possa fazer isso em 2005.

CREATE UNIQUE NONCLUSTERED INDEX IX_UNIQUE
ON dbo.YourTable(YourColumn)
WHERE YourColumn IS NOT NULL
GO

Ver:

Você não pode tornar uma coluna anulável exclusiva por meio de uma restrição única normal nessa coluna, mas pode implementar a restrição por meio de um índice baseado em função, não sabe se essa contrata existe no SQL Server, mas isso pode resolvê -lo em um oráculo base de dados

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top