Mysql
 sql >> база данни >  >> RDS >> Mysql

Java PreparedStatement и ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИКАТ КЛЮЧ:как да разбера дали редът е бил вмъкнат или актуализиран?

Помислете за следната тестова таблица на 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 ;

със съществуващи примерни данни, както следва:

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

С настройката за връзка по подразбиране compensateOnDuplicateKeyUpdateCounts=false (описано тук ) следния 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);
}

произвежда следния конзолен изход

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

Сега стартирайте отново същия код със стойностите на параметрите

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

и изходът на конзолата е

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

Това демонстрира, че .executeUpdate наистина може да върне 2, ако уникалният индекс води до актуализиране на съществуващ ред. Ако имате нужда от допълнителна помощ с действителния тестов код, тогава трябва да редактирате въпроса си, за да го включите.

Редактиране

По-нататъшното тестване разкрива, че .executeUpdate ще върне 1 if

  1. опитът INSERT е прекратен, защото би довел до дублирана стойност на УНИКАЛЕН ключ, и
  2. указаните промени ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИКАТ КЛЮЧ всъщност не променят никакви стойности в съществуващия ред .

Това може да се потвърди чрез стартиране на горния тестов код два пъти подред с точно същите стойности на параметрите. Обърнете внимание, че UPDATE ... id = LAST_INSERT_ID(id) "трик" гарантира, че правилният id стойност се връща.

Това вероятно обяснява резултатите от теста на OP, ако единствената вмъкната стойност е УНИКАЛНАТА ключова стойност.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка в Docker php_network_getaddresses

  2. База данни по подразбиране на MySQL

  3. Полето „id“ няма стойност по подразбиране?

  4. Създаване на високодостъпна база данни за Moodle с помощта на MySQL репликация

  5. Как да заменя идентификаторите на отдели, разделени със запетая, съответно с тяхното име?