Sie sind auf Seite 1von 2

The answer is "yes". You can do this with a filtered index (see here for documentation).

For instance, you can do:

create unique index t_col on t(col) where id > 1000;


This creates a unique index, only on new rows, rather than on the old rows. This particular
formulation would allow duplicates with existing values.
If you have just a handful of duplicates, you could do something like:

create unique index t_col on t(col) where id not in (<list of ids for duplicate values here>);
share improve this answer follow
answered Jun 4 '13 at 18:28

Gordon Linoff
2,03411 gold badge1313 silver badges1717 bronze badges
 2
Whether or not that's good would depend upon whether "old" existing items should prevent the creation of
new items with the same value. – supercat Jun 4 '13 at 18:34
 1
@supercat . . . I gave an alternative formulation for building the index on everything except existing
duplicate values. – Gordon Linoff Jun 4 '13 at 18:35
 1
For the latter to work, one would have to ensure that one omitted from the list one id for each distinct key
value that had duplicates, and would also have to ensure that if the item which was deliberately omitted
from the list got removed from the table, an item with an equal key would get removed from the
list. – supercat Jun 4 '13 at 18:44
 @supercat . . . I agree. Keeping the index consistent for updates and deletes is all the more challenging
because you can't re-create the index in a trigger. In any case, I had the impression from the OP that the
data -- or at least the duplicates -- are not changing often, if at all. – Gordon Linoff Jun 4 '13 at 18:53
 Why not exclude a list of values instead of a list of IDs? Then you don't have to exclude o
ALTER TABLE dbo.Party ADD IgnoreThisDuplicate INT NULL ;
GO

-- The *first* instance will be left NULL.


-- *Secondary* instances will be set to their ID (a unique value).
UPDATE dbo.Party
SET IgnoreThisDuplicate = ID
FROM dbo.Party AS my
WHERE EXISTS ( SELECT *
FROM dbo.Party AS other
WHERE other.Name = my.Name
AND other.ID < my.ID ) ;
GO

-- This constraint is not strictly necessary.


-- It prevents granting further exemptions beyond the ones we made above.
ALTER TABLE dbo.Party WITH NOCHECK
ADD CONSTRAINT CHK_Party_NoNewExemptions
CHECK(IgnoreThisDuplicate IS NULL);
GO

SELECT * FROM dbo.Party;


GO

-- **THIS** is our pseudo-unique constraint.


-- It works because the grandfathered duplicates have a unique value (== their ID).
-- Non-grandfathered records just have NULL, which is not unique.
CREATE UNIQUE INDEX UNQ_Party_UniqueNewNames ON dbo.Party(Name, IgnoreThisDuplicate);

Das könnte Ihnen auch gefallen