Cuando necesite garantizar la unicidad de los registros en una condición que no puede expresarse mediante una restricción ÚNICA o CLAVE PRINCIPAL, debe asegurarse de que la verificación de existencia y la inserción se realicen en una sola transacción. Puede lograr esto ya sea:
- Usando una declaración SQL realizando la verificación y la inserción (su tercera opción)
- Utilizar una transacción con el nivel de aislamiento adecuado
Sin embargo, hay una cuarta forma que lo ayudará a estructurar mejor su código y también lo hará funcionar en situaciones en las que necesita procesar un lote de registros a la vez. Puede crear una variable TABLE o una tabla temporal, insertar todos los registros que deben insertarse allí y luego escribir las declaraciones INSERT, UPDATE y DELETE basadas en esta variable.
A continuación se muestra un (pseudo) código que demuestra este enfoque:
-- 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)
En muchas situaciones utilizo este enfoque, ya que hace que el código TSQL sea más fácil de leer, es posible refactorizarlo y aplicarle pruebas unitarias.