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

Wie kann ich herausfinden, ob die Methode execute () beim Einfügen folgenden Code enthält:

Connection c = DriverManager.getConnection(connectionString); PreparedStatement st = c.prepareStatement("INSERT INTO `table`(`field1`) VALUES (?) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);"); st.setString(1,"some value"); st.execute(); 

Danke im Voraus.

Solutions Collecting From Web of "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 bob@example.com 2 Thompson, Gord gord@example.com 

Mit der Standardverbindungseinstellung compensateOnDuplicateKeyUpdateCounts=false ( hier beschrieben) wird der folgende Java-Code verwendet

 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, "mike@example.com"); int euReturnValue = ps.executeUpdate(); System.out.println(String.format("executeUpdate returned %d", 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.println(String.format(" => A new row was inserted: id=%d", affectedId)); } else { System.out.println(String.format(" => An existing row was updated: id=%d", affectedId)); } 

erzeugt die folgende Konsolenausgabe

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

Führen Sie den gleichen Code nun erneut mit den Parameterwerten aus

 ps.setString(1, "Loblaw, Robert"); ps.setString(2, "bob@example.com"); 

und die Konsolenausgabe ist

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

Dies zeigt, dass .executeUpdate wirklich 2 zurückgeben kann, wenn der eindeutige Index bewirkt, dass eine vorhandene Zeile aktualisiert wird. Wenn Sie weitere Hilfe zu Ihrem tatsächlichen Testcode benötigen, sollten Sie Ihre Frage bearbeiten, um sie hinzuzufügen.

Bearbeiten

Weitere Tests zeigen, dass .executeUpdate 1 if .executeUpdate

  1. Der versuchte INSERT wird abgebrochen, da dies zu einem doppelten UNIQUE-Schlüsselwert führen würde
  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" dafür sorgt, dass der richtige id Wert zurückgegeben wird.

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

Verwenden Sie stattdessen executeUpdate, da es eine int Zeilenanzahl zurückgibt.

UPDATE 1 : Laut der MySQL INSERT … ON DUPLICATE KEY UPDATE Dokumentation :

Bei ON DUPLICATE KEY UPDATE ist der Wert für betroffene Zeilen pro Zeile 1, wenn die Zeile als neue Zeile eingefügt wird, und 2, wenn eine vorhandene Zeile aktualisiert wird.

UPDATE 2 : INSERT IGNORE kann auch eine Option sein :

 INSERT IGNORE INTO `table`(`field1`) VALUES (?) 

executeUpdate sollte 1 zurückgeben, wenn eine neue Zeile eingefügt wird, und 0, wenn ein Duplikat vorhanden ist.