内容简介:通常我们会在执行一次INSERT后,调用LAST_INSERT_ID()获取最新的自增ID,但这么做其实并不太可靠。函数 LAST_INSERT_ID() 没有额外参数或表达式时,则返回一个无符号BIGINT,默认地,它返回最后一次对自增ID列INSERT后的值。注意,对非自增ID列INSERT结束后,调用 LAST_INSERT_ID() 是没有作用的,例如:
导读
通常我们会在执行一次INSERT后,调用LAST_INSERT_ID()获取最新的自增ID,但这么做其实并不太可靠。
函数 LAST_INSERT_ID() 没有额外参数或表达式时,则返回一个无符号BIGINT,默认地,它返回最后一次对自增ID列INSERT后的值。
注意,对非自增ID列INSERT结束后,调用 LAST_INSERT_ID() 是没有作用的,例如:
[root@yejr.me]> create table tt ( `id` int(11) NOT NULL primary key, `c1` int(10) unsigned NOT NULL )engine=innodb; [root@yejr.me]> insert into tt values(0,0); Query OK, 1 row affected (0.01 sec) [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 0 | +------------------+
在应用程序中,不少开发者会习惯调用 LAST_INSERT_ID() 函数获取最后插入的自增值,但实际上这么做并不可靠,我们来看几个例子:
例1,插入失败时
[root@yejr.me]> CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `c1` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB; # 第一次插入,没问题 [root@yejr.me]> insert into t select 0,rand()*1024; [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 1 | +------------------+ # 第二次插入,也没问题 [root@yejr.me]> insert into t select 0,rand()*1024; [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 2 | +------------------+ # 第三次插入,故意制造一个重复主键,这次就不对了 [root@yejr.me]> insert into t values(0,rand()*1024), (3, rand()*1024); ERROR 1062 (23000): Duplicate entry '3' for key 'PRIMARY' [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 3 | +------------------+ # 表中实际只有两条记录 [root@yejr.me]> select * from t; +----+-----+ | id | c1 | +----+-----+ | 1 | 784 | | 2 | 574 | +----+-----+ 2 rows in set (0.00 sec)
例子2,同时多次插入时
多个insert时,返回第二个insert值,例如:
# 现在表里有3条记录 [root@yejr.me]> select * from t; +----+-----+ | id | c1 | +----+-----+ | 1 | 784 | | 2 | 574 | | 5 | 681 | +----+-----+ 3 rows in set (0.00 sec) # 一次性再插入3条记录 [root@yejr.me]> insert into t values (0,rand()*1024), (0, rand()*1024), (0,rand()*1024); # 获取到的 last_insert_id() 值却是6,显然“不太符合预期” [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 6 | +------------------+ [root@yejr.me]> select * from t; +----+-----+ | id | c1 | +----+-----+ | 1 | 784 | | 2 | 574 | | 5 | 681 | | 6 | 841 | | 7 | 112 | | 8 | 87 | +----+-----+ 6 rows in set (0.00 sec)
例3,当 LAST_INSERT_ID() 带有参数时
# 清空重来 [root@yejr.me]> truncate table t; # 插入1条新记录 [root@yejr.me]> insert into t select 0,rand()*1024; # 查看 last_insert_id(), 符合预期 [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 1 | +------------------+ [root@yejr.me]> select * from t; +----+-----+ | id | c1 | +----+-----+ | 1 | 730 | +----+-----+ # 调用 last_insert_id() 时增加表达式 [root@yejr.me]> select last_insert_id(id+2) from t; +----------------------+ | last_insert_id(id+2) | +----------------------+ | 3 | +----------------------+ # 再看 last_insert_id() 的值,好像“又不符合预期”了 [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 3 | +------------------+ # 插入1条新纪录 [root@yejr.me]> insert into t select 0,rand()*1024; # 再看 last_insert_id() 的值,好像“又回到正轨”了 [root@yejr.me]> select last_insert_id(); +------------------+ | last_insert_id() | +------------------+ | 2 | +------------------+ [root@yejr.me]> select * from t; +----+-----+ | id | c1 | +----+-----+ | 1 | 730 | | 2 | 600 | +----+-----+ 2 rows in set (0.00 sec)
通过几个例子,我们能看到调用 last_insert_id() 函数想获取表中自增列最大值其实并不可靠,如果需要构建一个sequence表,最好还是每次都调用 max() 函数获取最大值才行。
附带 MySQL 版本信息:
[root@yejr.me]> \s ... Server version: 8.0.15 MySQL Community Server - GPL ...
参考资料
MySQL手册 https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_last-insert-id
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 观点 | 信任:可信第三方、人性与利益冲突
- 安全可信的全球智能云,助中国企业赢得世界
- 西电捷通:可信网络连接架构TCA的实现及其应用分析
- 【交易技术前沿】区块链驱动金融信息系统的可信安全
- [译] 揭秘电商评分系统的核心原理:如何让评分更可信?
- 美国家标准和技术研究所提出可信云架构概念
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
平台革命:改变世界的商业模式
[美]杰奥夫雷G.帕克(Geoffrey G. Parker)、马歇尔W.范·埃尔斯泰恩(Marshall W. Van Alstyne)、桑基特·保罗·邱达利(Sangeet Paul Choudary) / 志鹏 / 机械工业出版社 / 2017-10 / 65.00
《平台革命》一书从网络效应、平台的体系结构、颠覆市场、平台上线、盈利模式、平台开放的标准、平台治理、平台的衡量指标、平台战略、平台监管的10个视角,清晰地为读者提供了平台模式最权威的指导。 硅谷著名投资人马克·安德森曾经说过:“软件正在吞食整个世界。”而《平台革命》进一步指出:“平台正在吞食整个世界”。以平台为导向的经济变革为社会和商业机构创造了巨大的价值,包括创造财富、增长、满足人类的需求......一起来看看 《平台革命:改变世界的商业模式》 这本书的介绍吧!
HTML 编码/解码
HTML 编码/解码
RGB CMYK 转换工具
RGB CMYK 互转工具