MySQL ON DUPLICATE KEY – última identificación de inserción?

Tengo la siguiente consulta:

INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE a=1 

Quiero la ID 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 el ID “insertado” y no el ID actualizado.

¿Hay alguna forma de INSERTAR / ACTUALIZAR y recuperar el ID de la fila sin ejecutar dos consultas?

Consulte esta página: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
En la parte inferior de la página, explican cómo hacer que LAST_INSERT_ID sea significativo para las actualizaciones al pasar una expresión a esa función de MySQL.

Del ejemplo de la documentación de MySQL:

Si una tabla contiene una columna AUTO_INCREMENT e INSERT … UPDATE inserta una fila, la función LAST_INSERT_ID () devuelve el valor AUTO_INCREMENT. Si la instrucción actualiza una fila en su lugar, LAST_INSERT_ID () no tiene sentido. Sin embargo, puede solucionar esto utilizando LAST_INSERT_ID (expr). Supongamos que id es la columna AUTO_INCREMENT. Para hacer que LAST_INSERT_ID () tenga sentido para las actualizaciones, inserte las filas de la siguiente manera:

 INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3; 

Para ser exactos, si esta es la consulta original:

 INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE a=1 

y ‘id’ es la clave primaria de incremento automático que esta sería la solución de trabajo:

 INSERT INTO table (a) VALUES (0) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), a=1 

Está todo aquí: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

Si una tabla contiene una columna AUTO_INCREMENT e INSERT … UPDATE inserta una fila, la función LAST_INSERT_ID () devuelve el valor AUTO_INCREMENT. Si la instrucción actualiza una fila en su lugar, LAST_INSERT_ID () no tiene sentido. Sin embargo, puede solucionar esto utilizando LAST_INSERT_ID (expr). Supongamos que id es la columna AUTO_INCREMENT.

Puede ver REEMPLAZAR, que es esencialmente una eliminación / inserción si el registro existe. Pero esto cambiaría el campo de incremento automático, si está presente, lo que podría romper las relaciones con otros datos.

No sé cuál es tu versión de MySQL, pero con InnoDB, hubo 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

Vale la pena señalar, y esto podría ser obvio (pero lo diré de todos modos para mayor claridad aquí), que REPLACE socavará la fila de coincidencia existente antes de insertar sus nuevos datos. ON DUPLICATE KEY UPDATE solo actualizará las columnas que especifique y conservará la fila.

Del manual :

REPLACE funciona exactamente como INSERT, excepto que si una fila anterior en la tabla tiene el mismo valor que una nueva fila para una PRIMARY KEY o un índice UNIQUE, la fila anterior se elimina antes de que se inserte la nueva fila.

Las soluciones existentes funcionan si usa autoincrement. Tengo una situación en la que el usuario puede definir un prefijo y debe 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:

 INSERT INTO seq_table (prefix, id) VALUES ('$user_prefix', LAST_INSERT_ID(3000)) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id + 1); SELECT LAST_INSERT_ID(); 

Si el prefijo existe, lo incrementará y poblar last_insert_id. Si el prefijo no existe, insertará el prefijo con el valor 3000 y poblar last_insert_id con 3000.