Если в вашей таблице есть столбец, позволяющий идентифицировать записи, которые вы не хотите изменять, например столбец identity
или дату создания, вы можете создать уникальный отфильтрованный индекс для таблицы, указав в предложении where
, что он должен включать только другие записи в таблице.
Предположим, у вас есть столбец identity
с именем id
:
id | name |age
-----------------------
1 | kaushikC |21
2 | mohan |27
3 | kumar |29
4 | mohan |31
5 | karthik |55
6 | karthik |76
Вы можете создать уникальный отфильтрованный индекс для этой таблицы, который будет действителен только для строк, где id
больше 6:
CREATE UNIQUE INDEX UX_YourTable_Name_WhereIdGraterThanSix
ON YourTable (Name)
WHERE id > 6;
Это позволит вам сохранить уникальность других имен в таблице - однако это не помешает вам вставить еще один дубликат для любого существующего имени - поэтому вы можете вставить в таблицу еще один mohan
или другой kumar
(но только один).
Если вы хотите исключить все дубликаты, включая дубликаты существующих строк, лучше всего использовать триггер instead of
для вставки и обновления:
CREATE TRIGGER tr_YourTable ON YourTable
INSTEAD OF INSERT, UPDATE
AS
BEGIN
-- the statement that fired the trigger is an update statement
IF EXISTS(select 1 FROM deleted)
BEGIN
UPDATE T
SET name = I.Name
FROM YourTable AS T
JOIN Inserted AS I
ON T.Id = I.Id
WHERE NOT EXISTS
( -- make sure the name is unique
SELECT 1
FROM YourTable AS T1
WHERE T1.Name = I.Name
AND NOT EXISTS
( -- unless it is going to be updated
SELECT 1
FROM Deleted AS D
JOIN Inserted AS I
ON D.Id = I.Id
WHERE D.Id = T1.Id
AND T1.Name = D.Name
AND D.Name <> I.Name
)
)
END
ELSE -- the statement that fired the trigger is an insert statement
BEGIN
INSERT INTO YourTable(Name)
SELECT I.Name
FROM Inserted I
WHERE NOT EXISTS
( -- make sure the name is unique
SELECT 1
FROM YourTable AS T1
WHERE T1.Name = I.Name
)
END
END