Sobald Sie Ihre Duplikate 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 kann es oft besser sein, zuerst nach dieser Verletzung zu suchen, bevor SQL Server versucht, die Zeile einzufügen und eine Ausnahme zurückzugeben (Ausnahmen sind teuer).
http://www.sqlperformance.com/2012/08/t-sql-queries/error-handling
http://www.mssqltips.com/sqlservertip/2632/checking-for-potential-constraint-violations-before-entering-sql-server-try-and-catch-logic/
Wenn Sie verhindern möchten, dass Ausnahmen in die Anwendung gelangen, ohne Änderungen an der Anwendung vorzunehmen, können Sie einen INSTEAD OF
Auslöser 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 'Did nothing.';
END
END
GO
Wenn Sie dem Benutzer jedoch nicht mitteilen, dass er die Einfügung nicht durchgeführt hat, werden Sie sich fragen, warum die Daten nicht vorhanden sind und keine Ausnahme gemeldet wurde.
BEARBEITEN hier ist ein Beispiel, das genau das tut, wonach Sie fragen, auch wenn Sie dieselben Namen wie Ihre Frage verwenden, und dies beweist. Sie sollten es ausprobieren, bevor Sie davon ausgehen, dass die obigen Ideen nur die eine oder andere Spalte im Gegensatz zur Kombination behandeln ...
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
Daten in der Tabelle nach all dem:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Fehlermeldung beim letzten Einfügen:
Meldung 2627, Ebene 14, Status 1, Zeile 3 Verletzung der EINZIGARTIGEN SCHLÜSSEL-Einschränkung 'uq_Person'. Doppelter Schlüssel kann nicht in Objekt 'dbo.Person' eingefügt werden. Die Anweisung wurde beendet.