Kiedy potrzebujesz zagwarantować niepowtarzalność rekordów pod warunkiem, że nie może być wyrażony przez ograniczenie UNIQUE lub PRIMARY KEY, rzeczywiście musisz upewnić się, że sprawdzanie istnienia i wstawianie są wykonywane w jednej transakcji. Możesz to osiągnąć poprzez:
- Za pomocą jednej instrukcji SQL wykonującej sprawdzenie i wstawienie (trzecia opcja)
- Korzystanie z transakcji z odpowiednim poziomem izolacji
Istnieje jednak czwarty sposób, który pomoże ci lepiej ustrukturyzować kod, a także sprawi, że będzie działał w sytuacjach, w których musisz przetworzyć partię rekordów naraz. Możesz utworzyć zmienną TABLE lub tabelę tymczasową, wstawić wszystkie rekordy, które należy tam wstawić, a następnie na podstawie tej zmiennej napisać instrukcje INSERT, UPDATE i DELETE.
Poniżej znajduje się (pseudo)kod demonstrujący to podejście:
-- 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)
W wielu sytuacjach używam tego podejścia, ponieważ ułatwia ono odczytywanie kodu TSQL, umożliwia refaktoryzację i stosowanie testów jednostkowych.