SQL estándar llamada UPSERT

Estoy buscando una statement SQL estándar " UPSERT ". Una llamada para insert y actualizar si existe.

Estoy buscando una llamada de trabajo, eficiente y multiplataforma.

He visto MERGE , UPSERT , REPLACE , INSERT .. ON DUPLICATE UPDATE pero ninguna statement cumple con las necesidades.

Por cierto, uso MYSQL y HSQLDB para unitests. Entiendo que HSQLDB es limitado y puede que no cubra lo que necesito, pero no pude encontrar una forma estándar incluso sin él. Una afirmación de que solo MYSQL y HSQLDB también serán suficientes por ahora.

Estuve mirando por un time y no pude get una respuesta.

Mi table:

 CREATE TABLE MY_TABLE ( MY_KEY varchar(50) NOT NULL , MY_VALUE varchar(50) DEFAULT NULL, TIME_STAMP bigint NOT NULL, PRIMARY KEY (MY_KEY) ); 

¿Alguna idea?

Gracias;)

La única solución admitida por MySQL y HSQLDB es consultar las filas que desea replace 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. COMIENZA LA TRANSACCIÓN.
  2. SELECCIONAR … PARA ACTUALIZAR.
  3. Si el SELECT encuentra filas, ACTUALIZA.
  4. De lo contrario, INSERTAR.
  5. COMETER.

MySQL no admite la instrucción ANSI SQL MERGE. Es compatible con REEMPLAZAR e INSERTAR … EN ACTUALIZACIÓN DUPLICADA DE LLAVE. Consulte mi respuesta a "INSERT IGNORE" frente a "INSERTAR … SOBRE ACTUALIZACIÓN DE LLAVE DUPLICADA" para get más información al respecto.


Re comentarios: Sí, otro enfoque es probar el INSERT y ver si tiene éxito. De lo contrario, haga una ACTUALIZACIÓN. Si intentas INSERTAR y pulsa una tecla duplicada, generará un error, que se convierte en una exception en algunas interfaces de cliente. La desventaja de hacer esto en MySQL es que genera un nuevo ID de incremento automático incluso si INSERT falla. Entonces terminas con lagunas. Sé que las lagunas en la secuencia de auto incremento no son algo de lo que preocuparse, pero el año pasado ayudé a un cliente que tenía una brecha de 1000-1500 entre insertos exitosos debido a este efecto, y el resultado fue que agotaron el range de una INT en su key principal.

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

Pero consultar el número de filas afectadas lo regresa al problema original: tiene que usar consultas diferentes en MySQL versus HSQLDB.

HSQLDB:

 CALL DIAGNOSTICS(ROW_COUNT); 

MySQL:

 SELECT ROW_COUNT(); 

La syntax para hacer un upsert en un solo command varía según RDBMS.

En MySQL, es INSERT...ON DUPLICATE KEY UPDATE

En HSQLDB es MERGE

Si quieres una solución multiplataforma, necesitarás usar varios commands. Primero compruebe la fila existente, luego condicionalmente inserte o actualice según corresponda.