Une fois que vous avez supprimé votre (vos) duplicata (s):
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
ou
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Bien sûr, il peut souvent être préférable de vérifier d'abord cette violation, avant de simplement laisser SQL Server essayer d'insérer la ligne et de renvoyer une exception (les exceptions coûtent cher).
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/
Si vous souhaitez empêcher les exceptions de se propager dans l'application, sans apporter de modifications à l'application, vous pouvez utiliser un INSTEAD OF
déclencheur:
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
Mais si vous ne dites pas à l'utilisateur qu'il n'a pas effectué l'insertion, il se demandera pourquoi les données ne sont pas là et aucune exception n'a été signalée.
EDIT voici un exemple qui fait exactement ce que vous demandez, même en utilisant les mêmes noms que votre question, et le prouve. Vous devriez l'essayer avant de supposer que les idées ci-dessus ne traitent qu'une colonne ou l'autre par opposition à la combinaison ...
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
Données dans le tableau après tout cela:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Message d'erreur sur la dernière insertion:
Msg 2627, niveau 14, état 1, ligne 3 Violation de la contrainte UNIQUE KEY 'uq_Person'. Impossible d'insérer la clé en double dans l'objet 'dbo.Person'. La déclaration a été terminée.