Как мне обновить, если существует, вставить, если нет (AKA «upsert» или «объединить») в MySQL?

StackOverflow https://stackoverflow.com/questions/1218905

Вопрос

Есть ли простой способ INSERT строки, когда она не существует, или UPDATE , если она существует, с помощью одного запроса MySQL?

Это было полезно?

Решение

Да, INSERT ... ON ОБНОВЛЕНИЕ КЛЮЧЕВЫХ КЛЮЧЕЙ . Например:

INSERT INTO `usage`
(`thing_id`, `times_used`, `first_time_used`)
VALUES
(4815162342, 1, NOW())
ON DUPLICATE KEY UPDATE
`times_used` = `times_used` + 1

Другие советы

Я знаю, что это старый вопрос, но Google недавно привел меня сюда, поэтому я думаю, что другие тоже приходят сюда.

@chaos правильно: есть < code> INSERT ... ON DUPLICATE KEY UPDATE Синтаксис.

Тем не менее, оригинальный вопрос задавался именно о MySQL, а в MySQL есть REPLACE INTO ... . ИМХО, эта команда проще и проще в использовании для upserts. Из руководства:

  

REPLACE работает точно так же, как INSERT, за исключением того, что если старая строка в таблице имеет то же значение, что и новая строка для PRIMARY KEY или UNIQUE индекса, старая строка удаляется перед вставкой новой строки.

Обратите внимание, что это не стандартный SQL. Пример из руководства:

CREATE TABLE test (
  id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  data VARCHAR(64) DEFAULT NULL,
  ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.04 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.04 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.00 sec)

Редактировать . Просто предупреждаю, что REPLACE INTO не похож на UPDATE . Как сказано в руководстве, REPLACE удаляет строку, если она существует, а затем вставляет новую. (Обратите внимание на забавные «2 строки, затронутые» в приведенном выше примере.) То есть он заменит значения всех столбцов существующей записи (а не просто обновит некоторые столбцы.) Поведение REPLACE INTO в MySQL очень похоже на поведение INSERT OR REPLACE INTO в Sqlite. Посмотрите этот вопрос для некоторых обходных путей, если вы хотите обновить только несколько столбцов ( и не все столбцы), если запись уже существует.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top