Sobald Sie Ihr Duplikat(en) entfernt haben:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
oder
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Natürlich ist es oft besser, diese Verletzung zuerst zu überprüfen, bevor Sie SQL Server einfach versuchen lassen, die Zeile einzufügen und eine Ausnahme zurückzugeben (Ausnahmen sind teuer).
Wenn Sie möchten, dass Ausnahmen nicht bis zur Anwendung durchsickern, ohne Änderungen an der Anwendung vorzunehmen, können Sie einen INSTEAD OF
Trigger verwenden:
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 'Habe nichts gemacht.';
END
END
GO
Aber wenn Sie dem Benutzer nicht mitteilen, dass er die Einfügung nicht vorgenommen hat, wird er sich fragen, warum die Daten nicht vorhanden sind und keine Ausnahme gemeldet wurde.
BEARBEITEN hier ist ein Beispiel, das genau das tut, was Sie verlangen, sogar mit denselben Namen wie in Ihrer Frage, und beweist es. Sie sollten es ausprobieren, bevor Sie davon ausgehen, dass die obigen Ideen nur eine Spalte behandeln oder die andere im Gegensatz zur Kombination...
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
-- hat Erfolg:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
-- hat Erfolg:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 0, 22);
GO
-- fehlschlägt:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
Daten in der Tabelle nach all dem:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Fehlermeldung bei der letzten Einfügung:
Msg 2627, Level 14, State 1, Line 3 Verletzung des eindeutigen Schlüsselconstraints 'uq_Person'. Kann doppelten Schlüssel in Objekt 'dbo.Person' nicht einfügen. Der Befehl wurde beendet.
Außerdem habe ich kürzlich mehr über eine Lösung zum Anwenden eines eindeutigen Constraints auf zwei Spalten in beliebiger Reihenfolge gebloggt: