最后一个插入 ID? ?

我有以下疑问:

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

我想要插入或更新的 ID。通常我会运行第二个查询来得到这个结果,因为我相信 insert _ ID ()只返回“插入的”ID,而不返回更新后的 ID。

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

82633 次浏览

您可以查看 REPLACE,如果记录存在,它实际上是一个 delete/insert。但是如果存在,这将改变自动增量字段,从而可能破坏与其他数据的关系。

我不知道你们的 MySQL 版本是什么,但是在 InnoDB 中,autoinc 有一个 bug

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

错误,并在5.1.33中更正 Http://bugs.mysql.com/bug.php?id=42714

看看这一页: https://web.archive.org/web/20150329004325/https://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;

值得注意的是,在插入新数据之前,REPLACE 将消除现有的匹配行,这一点可能是显而易见的(但为了清晰起见,我还是要在此说明)。ONDUPLICATEKEYUPDATE 将只更新您指定的列并保留该行。

来自 手动操作:

REPLACE 的工作方式与 INSERT 完全相同, 除非表中的旧行 对象的新行具有相同的值 主键或 UNIQUE 索引,则旧的 在删除新行之前删除该行 插入。

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

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 ()没有意义 假设 id 是 AUTO _ INCREMENT 专栏。

如果使用自动增量,现有的解决方案就可以工作。我有一个情况,用户可以定义一个前缀,它应该重新启动序列在3000。由于前缀的不同,我不能使用自动增量,这使得 last _ insert _ id 对于 insert 为空。我用以下方法解决了这个问题:

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。

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