sql >> Databasteknik >  >> RDS >> Mysql

Java PreparedStatement och ON DUPLICATE KEY UPDATE:hur vet jag om raden infogades eller uppdaterades?

Tänk på följande MySQL-testtabell:

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 ;

med befintliga exempeldata enligt följande:

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

Med standardanslutningsinställningen compensateOnDuplicateKeyUpdateCounts=false (beskrivs här ) följande Java-kod

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

producerar följande konsolutgång

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

Kör nu samma kod igen med parametervärdena

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

och konsolutgången är

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

Detta visar att .executeUpdate verkligen kan returnera 2 om det unika indexet gör att en befintlig rad uppdateras. Om du behöver ytterligare hjälp med din faktiska testkod så bör du redigera din fråga så att den inkluderas.

Redigera

Ytterligare tester visar att .executeUpdate returnerar 1 om

  1. Försöket att infoga avbryts eftersom det skulle resultera i ett dubblerat UNIKT nyckelvärde, och
  2. de angivna ändringarna PÅ DUBLIKATNYCKELUPPDATERING modifierar faktiskt inga värden i den befintliga raden .

Detta kan bekräftas genom att köra ovanstående testkod två gånger i rad med exakt samma parametervärden. Observera att UPDATE ... id = LAST_INSERT_ID(id) "trick" säkerställer att korrekt id värdet returneras.

Det förklarar förmodligen OP:s testresultat om det enda värdet som infogades var det UNIKA nyckelvärdet.



  1. Hur många tabeller kan skapas i en mysql-databas?

  2. Bästa metoder för MySQL-replikering

  3. Oracle SQL-timmar Skillnad mellan datum i TT:MM:SS

  4. Kontrollera Oracle RAC Network och IP-information