sql >> Base de Datos >  >> RDS >> Mysql

Llamada UPSERT estándar de SQL

La única solución compatible con MySQL y HSQLDB es consultar las filas que desea reemplazar y, de forma condicional, INSERTAR o ACTUALIZAR. Esto significa que debe escribir más código de aplicación para compensar las diferencias entre las implementaciones de RDBMS.

  1. INICIAR TRANSACCIÓN.
  2. SELECCIONE... PARA ACTUALIZAR.
  3. Si SELECT encuentra filas, entonces ACTUALIZAR.
  4. Si no, INSERTAR.
  5. COMPROMISO.

MySQL no es compatible con la instrucción MERGE de ANSI SQL. Admite REEMPLAZAR e INSERTAR... EN ACTUALIZACIÓN DE CLAVE DUPLICADA. Vea mi respuesta a " INSERTAR IGNORAR" frente a "INSERTAR... EN ACTUALIZACIÓN DE CLAVE DUPLICADA" para más sobre eso.

Re comentarios:Sí, otro enfoque es simplemente probar INSERTAR y ver si tiene éxito. De lo contrario, haz una ACTUALIZACIÓN. Si intenta INSERTAR y golpea una clave duplicada, generará un error, que se convierte en una excepción en algunas interfaces de clientes. La desventaja de hacer esto en MySQL es que genera una nueva ID de incremento automático incluso si falla INSERT. Entonces terminas con lagunas. Sé que las brechas en la secuencia de incremento automático normalmente no son algo de qué preocuparse, pero el año pasado ayudé a un cliente que tenía brechas de 1000-1500 entre inserciones exitosas debido a este efecto, y el resultado fue que agotaron el rango de una INT en su clave principal.

Como dice @baraky, en su lugar, uno podría intentar la ACTUALIZACIÓN primero, y si eso afecta cero filas, entonces haga INSERTAR en su lugar. Mi comentario sobre esta estrategia es que la ACTUALIZACIÓN de cero filas no es una excepción:deberá verificar el "número de filas afectadas" después de la ACTUALIZACIÓN para saber si "tuvo éxito" o no.

Pero consultar la cantidad de filas afectadas lo devuelve al problema original:debe usar diferentes consultas en MySQL versus HSQLDB.

HSQLDB:

CALL DIAGNOSTICS(ROW_COUNT);

MySQL:

SELECT ROW_COUNT();