Jakmile odstraníte duplikáty:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
nebo
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Samozřejmě může být často lepší nejprve zkontrolovat toto porušení, než necháte SQL Server, aby se pokusil vložit řádek a vrátil výjimku (výjimky jsou drahé).
-
Vliv různých technik zpracování chyb na výkon
-
Kontrola potenciálního porušení omezení před zadáním TRY/CATCH
Pokud chcete zabránit probublávání výjimek do aplikace, aniž byste v aplikaci prováděli změny, můžete použít INSTEAD OF
spoušť:
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
Ale pokud uživateli neřeknete, že vložení neprovedl, bude se divit, proč tam data nejsou a nebyla hlášena žádná výjimka.
UPRAVIT zde je příklad, který dělá přesně to, co požadujete, a to i pomocí stejných jmen jako vaše otázka, a dokazuje to. Měli byste si to vyzkoušet předtím, než předpokládáte, že výše uvedené nápady zacházejí pouze s jedním nebo druhým sloupcem, nikoli s kombinací...
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
Údaje v tabulce po tom všem:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Chybová zpráva u posledního vložení:
Zpráva 2627, úroveň 14, stav 1, řádek 3 Porušení omezení UNIQUE KEY 'uq_Person'. Do objektu 'dbo.Person' nelze vložit duplicitní klíč. Příkaz byl ukončen.
Nedávno jsem také blogoval o řešení použití jedinečného omezení na dva sloupce v libovolném pořadí :
- Uplatněte jedinečné omezení tam, kde na pořadí nezáleží