Quando è necessario garantire l'unicità dei record a una condizione che non può essere espressa da un vincolo UNIQUE o PRIMARY KEY, è infatti necessario assicurarsi che la verifica dell'esistenza e dell'inserimento avvenga in un'unica transazione. Puoi ottenerlo in uno dei seguenti modi:
- Utilizzo di un'istruzione SQL per eseguire il controllo e l'inserimento (la terza opzione)
- Utilizzare una transazione con il livello di isolamento appropriato
C'è un quarto modo, tuttavia, che ti aiuterà a strutturare meglio il tuo codice e anche a farlo funzionare in situazioni in cui devi elaborare un batch di record contemporaneamente. Puoi creare una variabile TABLE o una tabella temporanea, inserire tutti i record che devono essere inseriti in essa e quindi scrivere le istruzioni INSERT, UPDATE e DELETE in base a questa variabile.
Di seguito è riportato (pseudo)codice che dimostra questo approccio:
-- 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)
In molte situazioni utilizzo questo approccio in quanto rende il codice TSQL più facile da leggere, refactoring e applicazione di unit test.