sql >> Database >  >> RDS >> Mysql

Java PreparedStatement en ON DUPLICATE KEY UPDATE:hoe weet ik of een rij is ingevoegd of bijgewerkt?

Bekijk de volgende 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 ;

met bestaande voorbeeldgegevens als volgt:

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

Met de standaard verbindingsinstelling compensateOnDuplicateKeyUpdateCounts=false (beschreven hier ) de volgende 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);
}

produceert de volgende console-uitvoer

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

Voer nu dezelfde code opnieuw uit met de parameterwaarden

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

en de console-uitgang is

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

Dit toont aan dat .executeUpdate kan echt 2 retourneren als de unieke index ervoor zorgt dat een bestaande rij wordt bijgewerkt. Als u meer hulp nodig heeft bij uw werkelijke testcode, moet u uw vraag bewerken om deze op te nemen.

Bewerken

Verdere tests laten zien dat .executeUpdate geeft 1 terug als

  1. de poging tot INSERT is afgebroken omdat dit zou resulteren in een dubbele UNIEKE sleutelwaarde, en
  2. de opgegeven ON DUPLICATE KEY UPDATE-wijzigingen wijzigen feitelijk geen waarden in de bestaande rij .

Dit kan worden bevestigd door de bovenstaande testcode twee keer achter elkaar uit te voeren met exact dezelfde parameterwaarden. Merk op dat de UPDATE ... id = LAST_INSERT_ID(id) "trick" zorgt er wel voor dat de juiste id waarde wordt geretourneerd.

Dat verklaart waarschijnlijk de testresultaten van OP als de enige waarde die werd ingevoegd de UNIEKE sleutelwaarde was.



  1. GI 19c RPM Package Manager-database

  2. cx orakel ImportError

  3. Eenvoudige query om maximale waarde voor elke ID te verkrijgen

  4. Een aangepaste SQL Server Docker-afbeelding maken bovenop de officiële afbeelding