¿Cuál es la forma correcta / más rápida de actualizar / insertar un registro en sql (Firebird / MySql)

StackOverflow https://stackoverflow.com/questions/343562

  •  19-08-2019
  •  | 
  •  

Pregunta

Necesito un poco de SQL para actualizar un registro en una base de datos si existe e insertarlo cuando no existe, mirar alrededor parece haber varias soluciones para esto, pero no sé cuáles son las formas correctas / aceptadas de haz esto.

Idealmente, me gustaría que funcione tanto en Firebird 2 como en MySQL 5, ya que la actualización deberá ejecutarse en ambas bases de datos, y sería más simple si el mismo SQL se ejecutara en ambas, si funcionara en más bases de datos que ser un plus.

La velocidad y la confiabilidad también tienen en cuenta la confiabilidad sobre la velocidad en este caso, pero potencialmente se usará para actualizar miles de registros en una sucesión rápida (en diferentes tablas).

alguna sujeción?

¿Fue útil?

Solución

Deberías usar algo como esto:

BEGIN TRANSACTION
IF EXISTS (SELECT * FROM the_table WHERE pk = 'whatever')
    UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'
ELSE
    INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')
COMMIT

O esto, pero envíelos por separado e ignore cualquier error del INSERT sobre la violación de las restricciones de clave principal:

INSERT INTO the_table (pk, data) VALUES ('whatever', 'stuff')

UPDATE the_table SET data = 'stuff' WHERE pk = 'whatever'

Otros consejos

En Firebird 2.1 puede usar ACTUALIZAR O INSERTAR para casos simples o MERGE para escenarios más complejos.

Para MySQL, pruebe el comando REPLACE : http://dev.mysql.com/doc/refman/5.0/en/replace.html

(Vea el comentario de Milan Babuskov sobre esta respuesta para obtener equivalentes en Firebird).

En firebird antes de 2.1 puedes usar esta forma complicada:

insert into table (id, a, b, c) values (:id, :a, :b, :c)
when SQLCODE -803 
do
begin
  update table set a = :a, b = :b, c = :c where id = :id;
end;

REPLACE funciona exactamente como INSERT, excepto que si una fila anterior de la tabla tiene el mismo valor que una fila nueva para una CLAVE PRIMARIA o un índice ÚNICO, la fila anterior se elimina antes de insertar la nueva fila.

Sintaxis:

REEMPLAZAR [LOW_PRIORITY | RETRASADO]     [INTO] tbl_name [(col_name, ...)]

{ VALUES | VALUE} 

({expr | DEFAULT},...),(...),...

Considerando que: Es mejor evitar REEMPLAZAR cuando trabaje con restricciones.

He usado INSERT en MySQL para actualizar filas con:
INSERT INTO table () VALUES () ON DUPLICATE KEY UPDATE key
Pero no puede usar una clave generada automáticamente.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top