När du behöver garantera unikheten hos poster på ett villkor som inte kan uttryckas av en UNIK eller PRIMÄR KEY-begränsning, måste du verkligen se till att kontrollen för existens och infogning görs i en transaktion. Du kan uppnå detta genom att antingen:
- Använda en SQL-sats för att utföra kontrollen och infogningen (ditt tredje alternativ)
- Använda en transaktion med lämplig isoleringsnivå
Det finns dock ett fjärde sätt som hjälper dig att bättre strukturera din kod och även få den att fungera i situationer där du behöver bearbeta en sats av poster på en gång. Du kan skapa en TABLE-variabel eller en temporär tabell, infoga alla poster som behöver infogas där och sedan skriva INSERT-, UPDATE- och DELETE-satserna baserat på denna variabel.
Nedan finns en (pseudo)kod som visar detta tillvägagångssätt:
-- Logic to create the data to be inserted if necessary
DECLARE @toInsert TABLE (idCol INT PRIMARY KEY,dataCol VARCHAR(MAX))
INSERT INTO @toInsert (idCol,dataCol) VALUES (1,'row 1'),(2,'row 2'),(3,'row 3')
-- Logic to insert the data
INSERT INTO realTable (idCol,dataCol)
SELECT TI.*
FROM @toInsert TI
WHERE NOT EXISTS (SELECT 1 FROM realTable RT WHERE RT.dataCol=TI.dataCol)
I många situationer använder jag det här tillvägagångssättet eftersom det gör TSQL-koden lättare att läsa, möjlig att omstrukturera och tillämpa enhetstester på.