sql >> Base de Datos >  >> RDS >> Sqlserver

ACTUALIZAR si existe más INSERTAR en SQL Server 2008

Mucha gente te sugerirá que uses MERGE , pero te advierto que no lo hagas. De forma predeterminada, no lo protege de las condiciones de concurrencia y de carrera más que varias declaraciones, pero presenta otros peligros:

  • Tenga cuidado con la instrucción MERGE de SQL Server
  • Qué evitar si desea utilizar MERGE
  • Patrones UPSERT y Antipatrones de SQL Server

Incluso con esta sintaxis "más simple" disponible, sigo prefiriendo este enfoque (se omite el manejo de errores por brevedad):

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
  INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;

Más información sobre este UPSERT enfoque aquí:

  • Deje de usar este antipatrón UPSERT

Mucha gente lo sugerirá de esta manera:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
  UPDATE ...
END
ELSE
BEGIN
  INSERT ...
END
COMMIT TRANSACTION;

Pero todo lo que esto logra es garantizar que es posible que deba leer la tabla dos veces para ubicar las filas que se actualizarán. En la primera muestra, solo necesitará ubicar las filas una vez. (En ambos casos, si no se encuentran filas de la lectura inicial, se produce una inserción).

Otros sugerirán de esta manera:

BEGIN TRY
  INSERT ...
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 2627
    UPDATE ...
END CATCH

Sin embargo, esto es problemático aunque solo sea por la razón de que permitir que SQL Server detecte excepciones que podría haber evitado en primer lugar es mucho más costoso, excepto en el caso poco frecuente en el que casi todas las inserciones fallan. Lo demuestro mucho aquí:

  • Comprobación de posibles violaciones de restricciones antes de ingresar TRY/CATCH
  • Impacto en el rendimiento de diferentes técnicas de manejo de errores

No estoy seguro de lo que cree que gana al tener una sola declaración; No creo que ganes nada. MERGE es una declaración única, pero aún tiene que realizar múltiples operaciones de todos modos, aunque te hace pensar que no lo hace.