SQL can I have a "conditionally unique" constraint on a table? SQL can I have a "conditionally unique" constraint on a table? sql sql

SQL can I have a "conditionally unique" constraint on a table?


If you are using SQL Server 2008 a Index filter would maybe your solution:

http://msdn.microsoft.com/en-us/library/ms188783.aspx

This is how I enforce a Unique Index with multiple NULL values

CREATE UNIQUE INDEX [IDX_Blah] ON [tblBlah] ([MyCol]) WHERE [MyCol] IS NOT NULL


In the case of descriptions which are not yet completed, I wouldn't have those in the same table as the finalized descriptions. The final table would then have a unique index or primary key on the description.

In the case of the active/inactive, again I might have separate tables as you did with an "archive" or "history" table, but another possible way to do it in MS SQL Server at least is through the use of an indexed view:

CREATE TABLE Test_Conditionally_Unique(    my_id   INT NOT NULL,    active  BIT NOT NULL DEFAULT 0)GOCREATE VIEW dbo.Test_Conditionally_Unique_ViewWITH SCHEMABINDINGAS    SELECT        my_id    FROM        dbo.Test_Conditionally_Unique    WHERE        active = 1GOCREATE UNIQUE CLUSTERED INDEX IDX1 ON Test_Conditionally_Unique_View (my_id)GOINSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (1, 0)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (1, 0)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (1, 0)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (1, 1)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (2, 0)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (2, 1)INSERT INTO dbo.Test_Conditionally_Unique (my_id, active)VALUES (2, 1)    -- This insert will fail

You could use this same method for the NULL/Valued descriptions as well.


Thanks for the comments, the initial version of this answer was wrong.

Here's a trick using a computed column that effectively allows a nullable unique constraint in SQL Server:

create table NullAndUnique     (    id int identity,     name varchar(50),    uniqueName as case         when name is null then cast(id as varchar(51))         else name + '_' end,    unique(uniqueName)    )insert into NullAndUnique default valuesinsert into NullAndUnique default values -- Worksinsert into NullAndUnique default values -- not accidentally :)insert into NullAndUnique (name) values ('Joel')insert into NullAndUnique (name) values ('Joel') -- Boom!

It basically uses the id when the name is null. The + '_' is to avoid cases where name might be numeric, like 1, which could collide with the id.