Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Java PreparedStatement i ON DUPLICATE KEY UPDATE:skąd mam wiedzieć, czy wiersz został wstawiony lub zaktualizowany?

Rozważ następującą tabelę testową 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 ;

z istniejącymi przykładowymi danymi w następujący sposób:

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

Z domyślnym ustawieniem połączenia compensateOnDuplicateKeyUpdateCounts=false (opisane tutaj ) następujący kod 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);
}

generuje następujące wyjście konsoli

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

Teraz ponownie uruchom ten sam kod z wartościami parametrów

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

a wyjście konsoli to

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

To pokazuje, że .executeUpdate naprawdę może zwrócić 2, jeśli unikalny indeks powoduje aktualizację istniejącego wiersza. Jeśli potrzebujesz dalszej pomocy z rzeczywistym kod testowy, powinieneś edytować swoje pytanie, aby je uwzględnić.

Edytuj

Dalsze testy ujawniają, że .executeUpdate zwróci 1, jeśli

  1. próba INSERT została przerwana, ponieważ spowodowałoby to zduplikowaną wartość klucza UNIKALNA, i
  2. określone zmiany ON DUPLICATE KEY UPDATE w rzeczywistości nie modyfikują żadnych wartości w istniejącym wierszu .

Można to potwierdzić, uruchamiając powyższy kod testowy dwa razy z rzędu z dokładnie tymi samymi wartościami parametrów. Zwróć uwagę, że UPDATE ... id = LAST_INSERT_ID(id) "sztuczka" zapewnia, że ​​poprawny id zwracana jest wartość.

To prawdopodobnie wyjaśnia wyniki testu OP, jeśli jedyną wstawioną wartością była UNIKALNA wartość klucza.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przełączanie na gotowe zestawienia

  2. Błąd CREATE FUNCTION Ta funkcja nie ma żadnych DETERMINISTIC, NO SQL ani READS SQL DATA

  3. Proste wprowadzenie do korzystania z MySQL na terminalu Linux

  4. DOŁĄCZ do GROUP BY w znormalizowanej bazie danych o zasobach, tematach i rozdziałach

  5. Policz wiersze tabeli