Вижу 3 варианта решения данной проблемы без создания уникальных индексов на несколько полей:
Для начала объявлю таблицу для примера:
CREATE TABLE [dbo].[TestTable](
[id] [int] NOT NULL,
[value1] [nchar](10) NOT NULL,
[value2] [nchar](10) NOT NULL
) ON [PRIMARY]
1.Самый банальный и простой вариант, как по мне
DECLARE
@IdValue int,
@FirstValue nchar(10),
@SecondValue nchar(10)
SELECT @IdValue = 1,
@FirstValue = 'a',
@SecondValue = 'b'
INSERT INTO TestTable
SELECT @IdValue, @FirstValue, @SecondValue
WHERE NOT EXISTS(SELECT 1 FROM TestTable t WHERE t.value1
= @FirstValue AND t.value2 = @SecondValue AND t.id != @IdValue)
2.Костыль, если у Вас уже есть готовая система - удаление строки в случае "неудачного" варианта:
CREATE TRIGGER InsertDelete
ON TestTable
AFTER INSERT
AS
BEGIN
DECLARE
@IdValue int,
@FirstValue nchar(10),
@SecondValue nchar(10)
SELECT @IdValue = INSERTED.[id],
@FirstValue= INSERTED.[value1],
@SecondValue= INSERTED.[value2]
FROM INSERTED
IF EXISTS(SELECT 1 FROM TestTable t WHERE t.value1 = @FirstValue AND t.value2 = @SecondValue AND t.id != @IdValue)
BEGIN
DELETE FROM TestTable WHERE id = @IdValue
END;
END
Такой вариант может помочь, если у Вас уже есть система, которая давно работает и нужно, скажем, вставить костыль как новшество
С первичным ключом я не рекомендую использовать Delete, т.к. это несет последствия, но целостность при нормальном использовании нарушить не должно
- Вы можете попробовать использовать INSTEAD OF TRIGGER. Здесь более подробно написано как это сделать: ТЫК (сам никогда не использовал его, поэтому предоставляю ссылку на оригинал)