是否有一个简单的方法来 INSERT一行时,它不存在,或者 UPDATE,如果它存在,使用一个 MySQL 查询?
INSERT
UPDATE
使用 INSERT ... ON DUPLICATE KEY UPDATE,例如:
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
我知道这是一个古老的问题,但谷歌最近引导我来到这里,所以我想其他人也来到这里。
@ 慌乱是正确的: 有 INSERT ... ON DUPLICATE KEY UPDATE语法。
然而,最初的问题是关于 MySQL 的,在 MySQL 中有 REPLACE INTO ...语法。恕我直言,这个命令对于 upserts 来说更简单、更直接。手册上说:
REPLACE INTO ...
REPLACE 的工作方式与 INSERT 完全相同,只是如果表中的旧行与 PRIMARYKEY 或 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 的 INSERT OR REPLACE INTO非常相似。如果只想在记录已经存在的情况下更新少数几个列(而不是所有列) ,请参阅 这个问题了解一些解决方案。
REPLACE INTO
REPLACE
INSERT OR REPLACE INTO