sql >> Database teknologi >  >> RDS >> Mysql

Java PreparedStatement og ON DUPLICATE KEY UPDATE:hvordan ved jeg, om rækken blev indsat eller opdateret?

Overvej følgende MySQL-testtabel:

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 eksisterende eksempeldata som følger:

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

Med standardforbindelsesindstillingen compensateOnDuplicateKeyUpdateCounts=false (beskrevet her ) følgende Java-kode

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

producerer følgende konsoludgang

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

Kør nu den samme kode igen med parameterværdierne

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

og konsoludgangen er

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

Dette viser, at .executeUpdate virkelig kan returnere 2, hvis det unikke indeks får en eksisterende række til at blive opdateret. Hvis du har brug for yderligere hjælp til din faktiske testkode, så skal du redigere dit spørgsmål for at inkludere det.

Rediger

Yderligere test afslører, at .executeUpdate returnerer 1 hvis

  1. Indsættelsesforsøget er afbrudt, fordi det ville resultere i en dublet UNIK nøgleværdi, og
  2. de angivne ON DUPLICATE KEY UPDATE ændringer ændrer faktisk ikke nogen værdier i den eksisterende række .

Dette kan bekræftes ved at køre ovenstående testkode to gange i træk med nøjagtig samme parameterværdier. Bemærk, at UPDATE ... id = LAST_INSERT_ID(id) "trick" sikrer, at det korrekte id værdi returneres.

Det forklarer sandsynligvis OP's testresultater, hvis den eneste værdi, der blev indsat, var den UNIKKE nøgleværdi.



  1. MySQL:Valg af flere felter til flere variabler i en lagret procedure

  2. Sådan konverteres en krydstabuleringsforespørgsel tilbage til en normal forespørgsel i Access

  3. Opdater flere kolonner i en triggerfunktion i plpgsql

  4. Hvordan opretter man et unikt tilfældigt heltals-id for primærnøgle til tabel?