El estandar ANSI desde el SQL:92 y sucesivos dice que una restricción UNIQUE debe evitar valores no nulos duplicados pero permitir a su vez múltiples valores nulos. Este es el comportamiento de la mayoría de motores de base de datos aunque SQL Server siempre ha implementado una versión particular no estándar de la restricción UNIQUE donde no son permitidos múltiples valores nulos.

Aunque seguimos teniendo este mismo problema en SQL Server 2008 (suponemos que por motivos de compatibilidad) los nuevos índices filtrados nos permiten implementar una restricción UNIQUE con un comportamiento acorde al estándar aunque sea con una sintaxis propia de creación de índices. El siguiente código de ejemplo muestra como creando una restricción UNIQUE no se nos permite tener valores nulos duplicados (columna A) mientras que la columna B nos permite nulos duplicados pero no valores no nulos duplicados:

USE tempdb

 

CREATE table test(

a int NULL UNIQUE NONCLUSTERED,

b int NULL

)

 

INSERT INTO test

VALUES

(NULL,NULL),

(1,NULL),

(2,1)

(3 row(s) affected)

 

INSERT INTO test

VALUES

(NULL,2)

 

Msg 2627, Level 14, State 1, Line 1

Violation of UNIQUE KEY constraint ‘UQ__test__3BD0198F0425A276’. Cannot insert duplicate key in object ‘dbo.test’.

 

CREATE UNIQUE NONCLUSTERED INDEX ix_unique ON test (b)

WHERE b is not null

 

INSERT INTO test

VALUES

(3,1)

 

Msg 2601, Level 14, State 1, Line 1

Cannot insert duplicate key row in object ‘dbo.test’ with unique index ‘ix_unique’.

 

INSERT INTO test

VALUES

(3,NULL)

(1 row(s) affected)

En versiones anteriores de SQL Server es posible simular este comportamiento creando una vista indexada que filtre los valores no nulos. Esta solución implica lidiar con las limitaciones impuestas por las vistas indexadas siendo la alternativa de un índice filtrado menos intrusivo en SQL Server 2008.

 

0 Shares:
Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

You May Also Like