Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在MySQL中,如果存在,如何更新,如果不存在,如何插入(又称“upsert”或“merge”)?_Sql_Mysql_Insert Update_Upsert - Fatal编程技术网

在MySQL中,如果存在,如何更新,如果不存在,如何插入(又称“upsert”或“merge”)?

在MySQL中,如果存在,如何更新,如果不存在,如何插入(又称“upsert”或“merge”)?,sql,mysql,insert-update,upsert,Sql,Mysql,Insert Update,Upsert,当一行不存在时,是否有一种简单的方法来插入该行,或者使用一个MySQL查询来更新该行(如果存在)。例如: INSERT INTO `usage` (`thing_id`, `times_used`, `first_time_used`) VALUES (4815162342, 1, NOW()) ON DUPLICATE KEY UPDATE `times_used` = `times_used` + 1 我知道这是一个老问题,但谷歌最近把我带到了这里,所以我想其他人也会来这里 @混乱是正确的

当一行不存在时,是否有一种简单的方法来插入该行,或者使用一个MySQL查询来更新该行(如果存在)。例如:

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

我知道这是一个老问题,但谷歌最近把我带到了这里,所以我想其他人也会来这里

@混乱是正确的:有语法

然而,最初的问题是关于MySQL的,MySQL中有语法。IMHO,这个命令更容易和更直接地用于upserts。从手册中:

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的工作原理与INSERT完全相同,只是如果表中的一个旧行与主键或唯一索引的新行具有相同的值,则在插入新行之前会删除旧行

注意,这不是标准的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
删除行(如果存在),然后插入一个新行。(注意上面示例中有趣的“2行受影响”)也就是说,它将替换现有记录中所有列的值(而不仅仅是更新某些列)。MySQL的
replace-INTO
的行为与Sqlite的
INSERT或replace-INTO
非常相似。如果记录已经存在,则只想更新少数列(而不是所有列),请参阅以了解一些解决方法。

是的,我相信SQL Server的等效项称为
MERGE
。一般来说,这个概念通常被称为
“UPSERT”
@blub:如果在
geb
topic
上创建一个唯一的键,它就会起作用(
ALTER TABLE TABLE ADD unique geb\u by\u topic(geb,topic)
)@Brian:Oracle的等价物也被称为
MERGE
,但我不确定它的语法是否与sqlserver的相同。@Brooks:。所以不要那样做。不要向它传递任何信息,也不要向它传递一个
NULL
,以允许
自动增量
行为工作(否则,是的,按照您的假设工作;请参见)。谢谢,如果重复,您可以使用
VALUES(col)
从insert参数获取值。例如:
在重复更新时b=值(b),c=值(c)