views:

2346

answers:

3

I am using SQL Server 2005. I want to constrain the values in a column to be unique, while allowing NULLS.

My current solution involves a unique index on a view like so:

CREATE VIEW vw_unq WITH SCHEMABINDING AS
    SELECT Column1
      FROM MyTable
     WHERE Column1 IS NOT NULL

CREATE UNIQUE CLUSTERED INDEX unq_idx ON vw_unq (Column1)

Any better ideas?

+7  A: 

Pretty sure you can't do that, as it violates the purpose of uniques.

However, this person seems to have a decent work around: http://sqlservercodebook.blogspot.com/2008/04/multiple-null-values-in-unique-index-in.html

Abyss Knight
It seems that you actually can do that. And the provided link is another way to do it as well.
Scott W
I know you can do it in Oracle, but I had no idea you could do it in SQL Server. Would love to see it done, though! :)
Abyss Knight
The workaround is actually decent, as you say.
Nuno G
It seems the content of the link you provided was actually (partially) copied without attribution from here: http://decipherinfosys.wordpress.com/2007/11/30/multiple-null-values-in-a-unique-index-in-sql-serverdb2-luw/
Tom Juergens
I disagree that it "violates the purpose of uniques" -- NULL is a special value in SQL (similar in many ways to NaN) and needs to be treated accordingly. It's actually a failure in in SQL Server to honor various SQL specifications: here is a link for a request for the "correct implementation" for what it is worth: http://connect.microsoft.com/SQLServer/feedback/details/299229/change-unique-constraint-to-allow-multiple-null-values.
pst
+15  A: 

The calculated column trick is widely known as a "nullbuster"; my notes credit Steve Kass:

CREATE TABLE dupNulls (
pk int identity(1,1) primary key,
X  int NULL,
nullbuster as (case when X is null then pk else 0 end),
CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
)
onedaywhen
+1  A: 

Using SQL Server 2008, you can create a filtered index: http://msdn.microsoft.com/en-us/library/cc280372.aspx. (I see Simon added this as a comment, but thought it deserved it's own answer as the comment is easily missed)

Another option is a trigger to check uniqueness, but this could affect performance.

Phil Haselden