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     example@sqldat.com
 2  Thompson, Gord  example@sqldat.com

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, "example@sqldat.com");
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, "example@sqldat.com");

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.