sql >> Databáze >  >> RDS >> Mysql

Java PreparedStatement a ON DUPLICATE KEY UPDATE:jak zjistím, zda byl řádek vložen nebo aktualizován?

Zvažte následující testovací tabulku MySQL:

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 ;

s existujícími ukázkovými daty takto:

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

S výchozím nastavením připojení compensateOnDuplicateKeyUpdateCounts=false (popsáno zde ) následující kód Java

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

vytvoří následující výstup konzoly

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

Nyní spusťte znovu stejný kód s hodnotami parametrů

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

a výstup konzole je

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

To ukazuje, že .executeUpdate skutečně může vrátit 2, pokud jedinečný index způsobí aktualizaci existujícího řádku. Pokud potřebujete další pomoc s skutečným testovací kód, pak byste měli upravit svou otázku tak, aby ji zahrnovala.

Upravit

Další testování ukazuje, že .executeUpdate vrátí 1 if

  1. pokus INSERT byl přerušen, protože by vedl k duplicitní hodnotě klíče UNIQUE, a
  2. zadané změny ON DUPLICATE KEY UPDATE ve skutečnosti nemění žádné hodnoty ve stávajícím řádku .

To lze potvrdit spuštěním výše uvedeného testovacího kódu dvakrát za sebou s přesně stejnými hodnotami parametrů. Všimněte si, že UPDATE ... id = LAST_INSERT_ID(id) "trick" zajišťuje správné id je vrácena hodnota.

To pravděpodobně vysvětluje výsledky testu OP, pokud jedinou vloženou hodnotou byla hodnota UNIQUE klíče.



  1. Základy tabulkových výrazů, část 13 – Inline tabulkové funkce, pokračování

  2. Jak přiměju SQLAlchemy, aby správně vložila unicode elipsu do tabulky mySQL?

  3. může couchdb dělat smyčky

  4. Zkopírujte tabulku MySQL včetně indexů