#1 楼
使用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
#2 楼
我知道这是一个老问题,但是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的行为非常相似。 INSERT OR REPLACE INTO
。如果您只想更新几列(而不是所有列)(如果记录已存在),请参见此问题的一些解决方法。
评论
是的,我相信SQL Server的等效项称为MERGE。通常,该概念通常称为“ UPSERT”。
–混乱
09年8月2日在13:40
@blub:如果您在geb和topic上创建唯一键,它将起作用(ALTER TABLE表添加唯一的geb_by_topic(geb,topic))。
–混乱
09年8月2日在13:43
@Brian:Oracle的等效名称也称为MERGE,但我不确定其语法是否与SQL Server相同。
– Ken Keenan
09年8月2日在14:20
@Brooks:如果将其传递给0,则它将实际上使用0作为值。所以不要那样做。不要传递任何东西,也不要传递NULL,以允许auto_increment行为起作用(否则,是的,按您的假设起作用;请参见dev.mysql.com/doc/refman/5.5/en/example-auto- inv.html)。
–混乱
2012年5月17日下午16:56
谢谢,如果有重复,您可以使用VALUES(col)从insert参数获取值。例如:在重复更新时b = VALUES(b),c = VALUES(c)
– gerrytan
2014年5月20日在1:51