我有以下查询:MySQL ON DUPLICATE KEY - 最后一次插入ID?
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
我想无论是插入或更新的ID。通常我运行第二个查询来获得这个,因为我相信insert_id()只返回'已插入'的ID而不是已更新的ID。
有没有办法来插入/更新和检索行的ID而不运行两个查询?
我有以下查询:MySQL ON DUPLICATE KEY - 最后一次插入ID?
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
我想无论是插入或更新的ID。通常我运行第二个查询来获得这个,因为我相信insert_id()只返回'已插入'的ID而不是已更新的ID。
有没有办法来插入/更新和检索行的ID而不运行两个查询?
查看此网页纠正了:http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
在页面的底部,他们解释如何可以使LAST_INSERT_ID有意义的更新传递一个表达式TH在MySQL功能。
从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,如果记录存在,REPLACE本质上是一个删除/插入操作。但是,如果存在这会改变自动增量字段,这可能会破坏与其他数据的关系。
啊耶 - 我正在寻找的东西不会摆脱以前的ID – thekevinscott 2009-04-22 18:42:09
这可能是危险的,因为这也可能会导致删除其他相关数据(通过约束)。 – Serge 2017-10-12 13:49:00
我不知道什么是你的MySQL,但与InnoDB的版本,有臭虫以AUTOINC
臭虫在5.1.20和5.1.31在5.1.23 http://bugs.mysql.com/bug.php?id=27405
的bug修正在5.1.33 http://bugs.mysql.com/bug.php?id=42714
值得一提的,这可能是明显的(但无论如何,我会说这为清楚起见,在这里),即更换会吹走插入新数据之前的现有匹配行。 ON DUPLICATE KEY UPDATE只会更新您指定的列并保留该行。
从manual:
更换作品酷似INSERT, 不同之处在于,如果一个老行的表 具有相同的值作为新行的 主键或唯一索引,则在插入新行之前删除旧行 行。
确切的说,如果这是原始查询:
INSERT INTO table (a) VALUES (0)
ON DUPLICATE KEY UPDATE a=1
和“身份证”比这个自动递增的主键将是工作的解决方案:
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 ...更新 插入一行,LAST_INSERT_ID()函数返回 AUTO_INCREMENT值。如果语句更新一行, LAST_INSERT_ID()没有意义。但是,您可以通过使用LAST_INSERT_ID(expr)解决此问题 。假设id是AUTO_INCREMENT 列。
如果您使用自动增量,现有的解决方案工作。我有一种情况,用户可以定义一个前缀,并且应该在3000处重新开始序列。由于前缀不同,我不能使用autoincrement,这使得insert_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。
而不是假设,你为什么不自己测试它?上述编辑中的SQL确实有效,通过我的测试比捕获插入失败更快,使用INSERT IGNORE,或者选择先查看是否有重复。 – 2011-12-28 01:26:32
警告:解决方案建议工作,但即使没有插入,auto_increment值也会继续增加。如果重复密钥经常发生,那么在上述查询之后,您可能想要运行`alter table tablename AUTO_INCREMENT = 0;`,以避免您的id值出现大的差距。 – 2016-04-22 06:00:54