sql >> Base de Datos >  >> RDS >> Mysql

Java PreparedStatement y ON DUPLICATE KEY UPDATE:¿cómo sé si la fila se insertó o actualizó?

Considere la siguiente tabla de prueba de MySQL:

CREATE TABLE `customers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

con datos de muestra existentes de la siguiente manera:

id  name            email
--  --------------  ----------------
 1  Loblaw, Bob     [email protected]
 2  Thompson, Gord  [email protected]

Con la configuración de conexión predeterminada compensateOnDuplicateKeyUpdateCounts=false (descrito aquí ) el siguiente código Java

PreparedStatement ps = dbConnection.prepareStatement(
        "INSERT INTO customers (name, email) " +
        "VALUES (?, ?) " +
        "ON DUPLICATE KEY UPDATE " +
            "name = VALUES(name), " +
            "id = LAST_INSERT_ID(id)");
ps.setString(1, "McMack, Mike");
ps.setString(2, "[email protected]");
int euReturnValue = ps.executeUpdate();
System.out.printf("executeUpdate returned %d%n", euReturnValue);
Statement s = dbConnection.createStatement();
ResultSet rs = s.executeQuery("SELECT LAST_INSERT_ID() AS n");
rs.next();
int affectedId = rs.getInt(1);
if (euReturnValue == 1) {
    System.out.printf("    => A new row was inserted: id=%d%n", affectedId);
}
else {
    System.out.printf("    => An existing row was updated: id=%d%n", affectedId);
}

produce la siguiente salida de consola

executeUpdate returned 1
    => A new row was inserted: id=3

Ahora ejecute el mismo código nuevamente con los valores de los parámetros

ps.setString(1, "Loblaw, Robert");
ps.setString(2, "[email protected]");

y la salida de la consola es

executeUpdate returned 2
    => An existing row was updated: id=1

Esto demuestra que .executeUpdate realmente puede devolver 2 si el índice único hace que se actualice una fila existente. Si necesita más ayuda con su actual código de prueba, entonces debe editar su pregunta para incluirlo.

Editar

Pruebas adicionales revelan que .executeUpdate devolverá 1 si

  1. el intento de INSERTAR se anula porque daría como resultado un valor de clave ÚNICO duplicado, y
  2. los cambios ON DUPLICATE KEY UPDATE especificados en realidad no modifican ningún valor en la fila existente .

Esto se puede confirmar ejecutando el código de prueba anterior dos veces seguidas con exactamente los mismos valores de parámetro. Tenga en cuenta que UPDATE ... id = LAST_INSERT_ID(id) "truco" asegura que el id correcto se devuelve el valor.

Eso probablemente explica los resultados de la prueba de OP si el único valor que se inserta fue el valor de clave ÚNICO.