内容简介:通常我们会在执行一次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的实现及其应用分析
- 【交易技术前沿】区块链驱动金融信息系统的可信安全
- [译] 揭秘电商评分系统的核心原理:如何让评分更可信?
- 美国家标准和技术研究所提出可信云架构概念
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Numerical Recipes 3rd Edition
William H. Press、Saul A. Teukolsky、William T. Vetterling、Brian P. Flannery / Cambridge University Press / 2007-9-6 / GBP 64.99
Do you want easy access to the latest methods in scientific computing? This greatly expanded third edition of Numerical Recipes has it, with wider coverage than ever before, many new, expanded and upd......一起来看看 《Numerical Recipes 3rd Edition》 这本书的介绍吧!