¿Cómo saber si al usar "en actualización de clave duplicada" se insertó o actualizó una fila?

Tenemos una base de datos que se actualiza todos los días a la medianoche con un cronjob, obtenemos nuevos datos de un XML externo.

Lo que hacemos es que insertamos todo el contenido nuevo y en caso de que haya una clave duplicada actualizamos ese campo.

INSERT INTO table (id, col1, col2, col3)
values (id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY UPDATE 
col1 = VALUES (col1), 
col2 = VALUES (col2), 
col3 = VALUES (col3);

Lo que queremos saber es qué filas se han insertado realmente, lo que significa que queremos tener una lista de los elementos nuevos. ¿Hay alguna consulta que pueda devolver las nuevas inserciones? Básicamente, necesitaremos obtener todas las nuevas identificaciones y no la cantidad de nuevas inserciones.

Muchas Gracias

preguntado el 22 de mayo de 12 a las 21:05

3 Respuestas

Puede obtener esta información en el momento de la inserción/actualización examinando el número de filas afectadas en el conjunto de resultados.

MySQL documentación establece lo siguiente:

Con ON DUPLICATE KEY UPDATE, el valor de las filas afectadas por fila es 1 si la fila se inserta como una fila nueva y 2 si se actualiza una fila existente.

Deberá combinar ROW_COUNT con LAST_INSERT_ID para obtener su respuesta e insertar una fila a la vez.

contestado el 22 de mayo de 12 a las 21:05

Esto ayuda a determinar ¿Cuántos las filas se insertaron frente a las actualizadas, pero no cuáles fueron cuáles ... - huevo

Sí, pensamos en eso, pero necesito saber la clave principal de las filas insertadas, no el número o el recuento de filas insertadas. - multimedios

@EddyXP, deberá combinar ROW_COUNT con LAST_INSERT_ID para obtener su respuesta e insertar una fila a la vez. - marcus adams

Tenga en cuenta que si se produce una actualización pero con los mismos datos anteriores, las filas afectadas darán 0. - malayas

Añadir un update_count INT NOT NULL DEFAULT 1 columna y cambie su consulta:

INSERT
INTO    table (id, col1, col2, col3)
VALUES
(id_value, val1, val2, val3),
(id_value, val1, val2, val3,),
(id_value, val1, val2, val3),
(id_value, val1, val2, val3),
ON DUPLICATE KEY
UPDATE 
        col1 = VALUES (col1), 
        col2 = VALUES (col2), 
        col3 = VALUES (col3),
        update_count = update_count + 1;

También puede incrementarlo en un BEFORE UPDATE disparador que le permitirá mantener la consulta como está.

contestado el 22 de mayo de 12 a las 21:05

Gracias Quassnoi, gran idea, usé una nueva columna llamada actualizada y apliqué su idea con un enfoque diferente que realmente funcionó muy bien para mí, revise su respuesta para las modificaciones que hice y envíeme sus comentarios. Funcionó muy bien gracias. - multimedios

Puedo decir cómo lo hice en PHP:

1) Consulta simple SELECCIONE MAX (id) y recuérdelo en $ max_id de la tabla antes de Insertar en duplicado.

2) Luego, durante el proceso de actualización, recopile la ID de las filas afectadas (no importa si es nueva o si existió): $ids[] = mysql_insert_id();

3) Luego $inserted_rows = max($ids)-$max_id;

4) Filas actualizadas = recuento ($ids_srt)-$inserted_rows

$max_id = mysql_query("SELECT MAX(id) from table");
$max_id = mysql_result($max_id, 0);

// !!! prepare here 'insert on duplicate' query in a cycle

$result=mysql_query($query);
$ids[] = mysql_insert_id();

// finish inserting and collecting affected ids and close cycle

$inserted_rows = max($ids)- $max_id;
$updated_rows = count($ids)- $inserted_rows

respondido 15 nov., 17:22

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.