Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Java PreparedStatement und ON DUPLICATE KEY UPDATE:Woher weiß ich, ob eine Zeile eingefügt oder aktualisiert wurde?

Betrachten Sie die folgende MySQL-Testtabelle:

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 ;

mit vorhandenen Beispieldaten wie folgt:

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

Mit der Standardverbindungseinstellung compensateOnDuplicateKeyUpdateCounts=false (beschrieben hier ) den folgenden Java-Code

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);
}

erzeugt die folgende Konsolenausgabe

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

Führen Sie nun den gleichen Code noch einmal mit den Parameterwerten

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

und die Konsolenausgabe ist

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

Dies zeigt, dass .executeUpdate kann wirklich 2 zurückgeben, wenn der eindeutige Index bewirkt, dass eine vorhandene Zeile aktualisiert wird. Wenn Sie weitere Unterstützung bei Ihrem aktuellen benötigen Testcode, dann sollten Sie Ihre Frage bearbeiten, um ihn einzuschließen.

Bearbeiten

Weitere Tests zeigen, dass .executeUpdate gibt 1 zurück, wenn

  1. das versuchte INSERT wird abgebrochen, weil es zu einem doppelten UNIQUE-Schlüsselwert führen würde, und
  2. die angegebenen ON DUPLICATE KEY UPDATE-Änderungen ändern tatsächlich keine Werte in der vorhandenen Zeile .

Dies kann bestätigt werden, indem der obige Testcode zweimal hintereinander mit genau denselben Parameterwerten ausgeführt wird. Beachten Sie, dass UPDATE ... id = LAST_INSERT_ID(id) "trick" stellt sicher, dass die richtige id Wert wird zurückgegeben.

Das erklärt wahrscheinlich die Testergebnisse von OP, wenn der einzige eingefügte Wert der UNIQUE-Schlüsselwert war.