Nadat u uw duplicaat(en) heeft verwijderd:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
of
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Natuurlijk kan het vaak beter zijn om eerst op deze overtreding te controleren, voordat u SQL Server laat proberen de rij in te voegen en een uitzondering te retourneren (uitzonderingen zijn duur).
-
Invloed op de prestaties van verschillende technieken voor foutafhandeling
-
Controleren op mogelijke schendingen van beperkingen voordat TRY/CATCH wordt ingevoerd
Als u wilt voorkomen dat uitzonderingen naar de applicatie borrelen, zonder wijzigingen in de applicatie aan te brengen, kunt u een INSTEAD OF
gebruiken trigger:
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
Maar als je de gebruiker niet vertelt dat ze de invoeging niet hebben uitgevoerd, zullen ze zich afvragen waarom de gegevens er niet zijn en er is geen uitzondering gemeld.
BEWERKEN hier is een voorbeeld dat precies doet wat je vraagt, zelfs met dezelfde namen als je vraag, en het bewijst. Je moet het eerst uitproberen voordat je aanneemt dat de bovenstaande ideeën alleen de ene of de andere kolom behandelen in plaats van de combinatie...
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
Gegevens in de tabel na dit alles:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Foutmelding op de laatste invoeging:
Msg 2627, niveau 14, staat 1, regel 3 Schending van UNIQUE KEY-beperking 'uq_Person'. Kan geen dubbele sleutel invoegen in object 'dbo.Person'. De instructie is beëindigd.
Ook heb ik recentelijk geblogd over een oplossing voor het toepassen van een unieke beperking op twee kolommen in willekeurige volgorde :
- Een unieke beperking afdwingen waar volgorde er niet toe doet