Tengo la siguiente consulta:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
Quiero la identificación de la inserción o la actualización. Por lo general, ejecuto una segunda consulta para obtener esto, ya que creo que insert_id () solo devuelve la ID 'insertada' y no la ID actualizada.
¿Hay alguna manera de INSERTAR / ACTUALIZAR y recuperar la ID de la fila sin ejecutar dos consultas?
alter table tablename AUTO_INCREMENT = 0;
después de la consulta anterior, para evitar grandes brechas en sus valores de identificación.Respuestas:
Consulte esta página: https://web.archive.org/web/20150329004325/https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Al final de la página explican cómo puede hacer que LAST_INSERT_ID sea significativo para las actualizaciones pasando una expresión a esa función MySQL.
Del ejemplo de documentación de MySQL:
fuente
Para ser exactos, si esta es la consulta original:
e 'id' es la clave primaria de incremento automático de lo que sería la solución de trabajo:
Está todo aquí: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
fuente
Puede mirar REPLACE, que es esencialmente una eliminación / inserción si existe el registro. Pero esto cambiaría el campo de incremento automático si está presente, lo que podría romper las relaciones con otros datos.
fuente
No sé cuál es su versión de MySQL pero con InnoDB, hubo un error con autoinc
error en 5.1.20 y corregido en 5.1.23 http://bugs.mysql.com/bug.php?id=27405
error en 5.1.31 y corregido en 5.1.33 http://bugs.mysql.com/bug.php?id=42714
fuente
Me he encontrado con un problema, cuando ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID (id) incrementa la clave primaria en 1. Por lo tanto, la id de la siguiente entrada dentro de la sesión se incrementará en 2
fuente
Vale la pena señalar, y esto puede ser obvio (pero lo diré de todos modos para mayor claridad aquí), que REPLACE eliminará la fila coincidente existente antes de insertar sus nuevos datos. ON DUPLICATE KEY UPDATE solo actualizará las columnas que especifique y conservará la fila.
Del manual :
fuente
Las soluciones existentes funcionan si utiliza autoincrement. Tengo una situación en la que el usuario puede definir un prefijo y debería reiniciar la secuencia en 3000. Debido a este prefijo variado, no puedo usar autoincrement, lo que hace que last_insert_id esté vacío para las inserciones. Lo resolví con lo siguiente:
Si el prefijo existe, lo incrementará y completará last_insert_id. Si el prefijo no existe, insertará el prefijo con el valor 3000 y completará last_insert_id con 3000.
fuente