MySQL ON DUPLICATE KEY - 最后一次插入ID?

时间:2009-04-22 18:22:31

标签: mysql insert-id

我有以下查询:

INSERT INTO table (a) VALUES (0)
  ON DUPLICATE KEY UPDATE a=1

我想要插入或更新的ID。通常我会运行第二个查询以获取此信息,因为我认为insert_id()只返回'inserted'ID而不是更新的ID。

有没有办法INSERT / UPDATE并检索行的ID而不运行两个查询?

7 个答案:

答案 0 :(得分:149)

查看此页:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
在页面的底部,他们解释了如何通过将表达式传递给MySQL函数来使LAST_INSERT_ID对更新有意义。

从MySQL文档示例:

  

如果表包含AUTO_INCREMENT列并且INSERT ... UPDATE插入行,则LAST_INSERT_ID()函数返回AUTO_INCREMENT值。如果语句更新了一行,则LAST_INSERT_ID()没有意义。但是,您可以使用LAST_INSERT_ID(expr)解决此问题。假设id是AUTO_INCREMENT列。要使LAST_INSERT_ID()对更新有意义,请按如下方式插入行:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;

答案 1 :(得分:31)

确切地说,如果这是原始查询:

INSERT INTO table (a) VALUES (0)
 ON DUPLICATE KEY UPDATE a=1

和'id'是自动增量主键,而不是工作解决方案:

INSERT INTO table (a) VALUES (0)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), a=1

全部在这里:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

  

如果表包含AUTO_INCREMENT列并且INSERT ... UPDATE   插入一行,LAST_INSERT_ID()函数返回   AUTO_INCREMENT值。如果语句更新了一行,   LAST_INSERT_ID()没有意义。但是,你可以解决这个问题   通过使用LAST_INSERT_ID(expr)。假设id是AUTO_INCREMENT   列。

答案 2 :(得分:2)

您可以查看REPLACE,如果记录存在,则基本上是删除/插入。但这会改变自动增量字段(如果存在),这可能会破坏与其他数据的关系。

答案 3 :(得分:2)

我不知道你的MySQL版本是什么,但是对于InnoDB,有autoinc的错误

5.1.20中的错误,并在5.1.23中更正 http://bugs.mysql.com/bug.php?id=27405

5.1.31中的错误,并在5.1.33中进行了更正 http://bugs.mysql.com/bug.php?id=42714

答案 4 :(得分:0)

值得注意的是,这可能是显而易见的(但为了清楚起见,我会说清楚),REPLACE会在插入新数据之前吹掉现有的匹配行。 ON DUPLICATE KEY UPDATE仅更新您指定的列并保留该行。

来自manual

  

REPLACE与INSERT完全一样,   除非表中有一个旧行   与a的新行具有相同的值   PRIMARY KEY或UNIQUE索引,旧的   在新行之前删除行   插入

答案 5 :(得分:0)

如果您使用自动增量,现有解决方案仍然有效。我有一种情况,用户可以定义一个前缀,它应该在3000重新启动序列。由于这个不同的前缀,我不能使用自动增量,这使得插入时last_insert_id为空。我解决了以下问题:

INSERT INTO seq_table (prefix, id) VALUES ('$user_prefix', LAST_INSERT_ID(3000)) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id + 1);
SELECT LAST_INSERT_ID();

如果前缀存在,它将递增它并填充last_insert_id。 如果前缀不存在,它将插入值为3000的前缀,并使用3000填充last_insert_id。

答案 6 :(得分:0)

我遇到了一个问题,当ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id)将主键增加1时,会话中下一个输入的id将增加2