След като премахнете своите дубликати:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
или
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Разбира се, често може да е по-добре първо да проверите за това нарушение, преди просто да оставите SQL Server да опита да вмъкне реда и да върне изключение (изключенията са скъпи).
-
Въздействие върху производителността на различни техники за обработка на грешки
-
Проверка за потенциални нарушения на ограниченията, преди да влезете в TRY/CATCH
Ако искате да предотвратите появата на изключения в приложението, без да правите промени в приложението, можете да използвате INSTEAD OF
задействане:
CREATE TRIGGER dbo.BlockDuplicatesYourTable
ON dbo.YourTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM inserted AS i
INNER JOIN dbo.YourTable AS t
ON i.column1 = t.column1
AND i.column2 = t.column2
)
BEGIN
INSERT dbo.YourTable(column1, column2, ...)
SELECT column1, column2, ... FROM inserted;
END
ELSE
BEGIN
PRINT 'Did nothing.';
END
END
GO
Но ако не кажете на потребителя, че не е извършил вмъкването, той ще се чуди защо данните не са там и не е докладвано изключение.
РЕДАКТИРАНЕ ето пример, който прави точно това, което искате, дори използва същите имена като вашия въпрос, и го доказва. Трябва да го изпробвате, преди да приемете, че горните идеи третират само една или друга колона, за разлика от комбинацията...
USE tempdb;
GO
CREATE TABLE dbo.Person
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(32),
Active BIT,
PersonNumber INT
);
GO
ALTER TABLE dbo.Person
ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 0, 22);
GO
-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
Данни в таблицата след всичко това:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Съобщение за грешка при последното вмъкване:
Съобщение 2627, ниво 14, състояние 1, ред 3 Нарушение на ограничението UNIQUE KEY 'uq_Person'. Не може да се вмъкне дублиран ключ в обект 'dbo.Person'. Изявлението е прекратено.
Също така наскоро писах в блог за решение за прилагане на уникално ограничение към две колони в всеки ред :
- Прилагане на уникално ограничение, където редът няма значение