Как мне обновить, если существует, вставить, если нет (AKA "upsert" или "объединить") в MySQL?
Есть ли простой способ INSERT
строка, когда она не существует, или UPDATE
если он существует, используя один запрос MySQL?
2 ответа
Да, INSERT ... ON DUPLICATE KEY UPDATE
, Например:
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 правильно: есть 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 строки" в примере выше.) То есть он заменит значения всех столбцов существующей записи (а не просто обновит некоторые столбцы.) Поведение MySQL REPLACE INTO
очень похоже на Sqlite's INSERT OR REPLACE INTO
, Посмотрите этот вопрос для некоторых обходных путей, если вы хотите обновить только несколько столбцов (и не все столбцы), если запись уже существует.