LAST_INSERT_ID(), LAST_INSERT_ID(expr)
2017-02-06 16:04
411 查看
原文:https://dev.mysql.com/doc/refman/5.5/en/query-cache-configuration.html
使用不带参数的LAST_INSERT_ID将返回第一个insert对应AUTO_INCREMENT字段的值,从MySQL 5.5.29开始该值返回为BIGINT UNSIGNED,以前的版本返回BIGINT (signed) 。如果insert执行成功但没有数据插入,则LAST_INSERT_ID返回值不变。
在MySQL 5.5.29中带参数的LAST_INSERT_ID()返回值类型为无符号整型,以前的版本返回整型。
例如:在插入一条数据后AUTO_INCREMENT字段会生成一个值,你可以使用下面的SQL拿到这个值:
-> 195
[/code]
当前正在执行的语句并不能影响LAST_INSERT_ID()的返回值。假如你通过一个语句生成了AUTO_INCREMENT的值,此时执行LAST_INSERT_ID()获取到一个值,然后执行一条插入多行数据的INSERT语句,该语句设置了AUTO_INCREMENT列的值,再次通过LAST_INSERT_ID()获取的值与前一次相同。(无论使用LAST_INSERT_ID()还是LAST_INSERT_ID(expr),都不会起效)
如果前一个语句产生了错误,通过LAST_INSERT_ID()获取的值是undefined.在事务中,如果一个语句执行错误并回滚,LAST_INSERT_ID()值将是undefined.未产生异常的回滚中(手工回滚),LAST_INSERT_ID()的值将是事务中最后一个AUTO_INCREMENT的值,而不会重置为事务开始前的初始值。
在MySQL 5.5.35前,使用MySQL 5.5.35过滤规则的函数不能获取正确的值。(Bug #17234370, Bug #69861)
在stored routine (存储过程或函数)或触发器(trigger)的方法体中,LAST_INSERT_ID()值的变化规则与在方法体外执行的规则一致。在routine执行完毕后,routine类型不同对LAST_INSERT_ID()值也会不同:
如果一个存储过程执行完后改变了LAST_INSERT_ID()的值,接下来执行的存储过程能够获取到这个值.
在存储函数和触发器中改了LAST_INSERT_ID值的话,在方法体执行完毕后LAST_INSERT_ID()的值会被重置,所以后续的语句将不能获取到这个值。
在服务器端基于每一个连接维护了一个对应的ID(LAST_INSERT_ID的结果)值。这意味着调用LAST_INSERT_ID()将返回这个连接产生的最后一个AUTO_INCREMENT值,并不会影响其它连接使用该函数的返回值,即使其它连接也生成了AUTO_INCREMENT的值。这个行为确保了每个客户端能够获取自己生成AUTO_INCREMENT的值,而不用关心其它客户端对AUTO_INCREMENT的值的影响,也不用使用锁或者是事务。
如果你将AUTO_INCREMENT列的值设为非“magic”(非NULL和0)的值,LAST_INSERT_ID()的值将不会变。
重要
如果你在一个INSERT语句中插入多条数据,LAST_INSERT_ID()只会获取一个插入行的值。原因是为了将INSERT语句尽量简单。
For example:
Database changed
mysql>
->
->
->
Query OK, 0 rows affected (0.09 sec)
mysql>
Query OK, 1 row affected (0.01 sec)
mysql>
+----+------+
| id | name |
+----+------+
| 1 | Bob |
+----+------+
1 row in set (0.01 sec)
mysql>
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql>
->
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Mary |
| 3 | Jane |
| 4 | Lisa |
+----+------+
4 rows in set (0.01 sec)
mysql>
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
[/code]
尽管第二条INSERT语句成功插入了三条数据,但是ID却是指向本次插入的第一行数据2.
如果你使用了INSERT IGNORE并且插入行被忽略,LAST_INSERT_ID()的值将不变(如果这个连接尚未成功插入数据返回值将为0),在非事务操作中,AUTO_INCREMENT计数器将不增长。在InnoDB表中,innodb_autoinc_lock_mode的值如果是1或2,AUTO_INCREMENT计数器将增长,下面举一个例子:
更多信息查看14.11.6, “AUTO_INCREMENT Handling in InnoDB”
如果LAST_INSERT_ID()的参数是一个表达式,返回值就是表达式的结果,也是LAST_INSERT_ID()的值。我们使用下面的步骤模拟这一过程:
Create a table to hold the sequence counter and initialize it:
mysql>
[/code]
Use the table to generate sequence numbers like this:
mysql>
mysql>
The
increments the sequence counter and causes the next call to
return the updated value. The
retrieves that value. The
API function can also be used to get the value. See Section 23.8.7.37,
“mysql_insert_id()”.
You can generate sequences without calling
but the utility of using the function this way is that the ID value is maintained in the server as the last automatically generated value. It is multi-user safe because multiple clients can issue the
and get their own sequence value with the
(or
without affecting or being affected by other clients that generate their own sequence values.
Note that
only updated after
so you cannot use the C API function to retrieve the value for
executing other SQL statements like
使用不带参数的LAST_INSERT_ID将返回第一个insert对应AUTO_INCREMENT字段的值,从MySQL 5.5.29开始该值返回为BIGINT UNSIGNED,以前的版本返回BIGINT (signed) 。如果insert执行成功但没有数据插入,则LAST_INSERT_ID返回值不变。
在MySQL 5.5.29中带参数的LAST_INSERT_ID()返回值类型为无符号整型,以前的版本返回整型。
例如:在插入一条数据后AUTO_INCREMENT字段会生成一个值,你可以使用下面的SQL拿到这个值:
mysql> [code]SELECT LAST_INSERT_ID();
-> 195
[/code]
当前正在执行的语句并不能影响LAST_INSERT_ID()的返回值。假如你通过一个语句生成了AUTO_INCREMENT的值,此时执行LAST_INSERT_ID()获取到一个值,然后执行一条插入多行数据的INSERT语句,该语句设置了AUTO_INCREMENT列的值,再次通过LAST_INSERT_ID()获取的值与前一次相同。(无论使用LAST_INSERT_ID()还是LAST_INSERT_ID(expr),都不会起效)
如果前一个语句产生了错误,通过LAST_INSERT_ID()获取的值是undefined.在事务中,如果一个语句执行错误并回滚,LAST_INSERT_ID()值将是undefined.未产生异常的回滚中(手工回滚),LAST_INSERT_ID()的值将是事务中最后一个AUTO_INCREMENT的值,而不会重置为事务开始前的初始值。
在MySQL 5.5.35前,使用MySQL 5.5.35过滤规则的函数不能获取正确的值。(Bug #17234370, Bug #69861)
在stored routine (存储过程或函数)或触发器(trigger)的方法体中,LAST_INSERT_ID()值的变化规则与在方法体外执行的规则一致。在routine执行完毕后,routine类型不同对LAST_INSERT_ID()值也会不同:
如果一个存储过程执行完后改变了LAST_INSERT_ID()的值,接下来执行的存储过程能够获取到这个值.
在存储函数和触发器中改了LAST_INSERT_ID值的话,在方法体执行完毕后LAST_INSERT_ID()的值会被重置,所以后续的语句将不能获取到这个值。
在服务器端基于每一个连接维护了一个对应的ID(LAST_INSERT_ID的结果)值。这意味着调用LAST_INSERT_ID()将返回这个连接产生的最后一个AUTO_INCREMENT值,并不会影响其它连接使用该函数的返回值,即使其它连接也生成了AUTO_INCREMENT的值。这个行为确保了每个客户端能够获取自己生成AUTO_INCREMENT的值,而不用关心其它客户端对AUTO_INCREMENT的值的影响,也不用使用锁或者是事务。
如果你将AUTO_INCREMENT列的值设为非“magic”(非NULL和0)的值,LAST_INSERT_ID()的值将不会变。
重要
如果你在一个INSERT语句中插入多条数据,LAST_INSERT_ID()只会获取一个插入行的值。原因是为了将INSERT语句尽量简单。
For example:
mysql> [code]USE test;
Database changed
mysql>
CREATE TABLE t (
->
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
->
name VARCHAR(10) NOT NULL
->
);
Query OK, 0 rows affected (0.09 sec)
mysql>
INSERT INTO t VALUES (NULL, 'Bob');
Query OK, 1 row affected (0.01 sec)
mysql>
SELECT * FROM t;
+----+------+
| id | name |
+----+------+
| 1 | Bob |
+----+------+
1 row in set (0.01 sec)
mysql>
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql>
INSERT INTO t VALUES
->
(NULL, 'Mary'), (NULL, 'Jane'), (NULL, 'Lisa');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t;
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Mary |
| 3 | Jane |
| 4 | Lisa |
+----+------+
4 rows in set (0.01 sec)
mysql>
SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
[/code]
尽管第二条INSERT语句成功插入了三条数据,但是ID却是指向本次插入的第一行数据2.
如果你使用了INSERT IGNORE并且插入行被忽略,LAST_INSERT_ID()的值将不变(如果这个连接尚未成功插入数据返回值将为0),在非事务操作中,AUTO_INCREMENT计数器将不增长。在InnoDB表中,innodb_autoinc_lock_mode的值如果是1或2,AUTO_INCREMENT计数器将增长,下面举一个例子:
mysql> USE test; Database changed mysql> SELECT @@innodb_autoinc_lock_mode; +----------------------------+ | @@innodb_autoinc_lock_mode | +----------------------------+ | 1 | +----------------------------+ 1 row in set (0.00 sec) mysql> CREATE TABLE `t` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `val` INT(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.02 sec) -- Insert two rows mysql> INSERT INTO t (val) VALUES (1),(2); Query OK, 2 rows affected (0.00 sec) Records: 2 Duplicates: 0 Warnings: 0 -- With auto_increment_offset=1, the inserted rows -- result in an AUTO_INCREMENT value of 3 mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) -- LAST_INSERT_ID() returns the first automatically generated -- value that is successfully inserted for the AUTO_INCREMENT column mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ 1 row in set (0.00 sec) -- The attempted insertion of duplicate rows fail but errors are ignored mysql> INSERT IGNORE INTO t (val) VALUES (1),(2); Query OK, 0 rows affected (0.00 sec) Records: 2 Duplicates: 2 Warnings: 0 -- With innodb_autoinc_lock_mode=1, the AUTO_INCREMENT counter -- is incremented for the ignored rows mysql> SHOW CREATE TABLE t\G *************************** 1. row *************************** Table: t Create Table: CREATE TABLE `t` ( `id` int(11) NOT NULL AUTO_INCREMENT, `val` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `i1` (`val`) ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) -- The LAST_INSERT_ID is unchanged becuase the previous insert was unsuccessful mysql> SELECT LAST_INSERT_ID(); +------------------+ | LAST_INSERT_ID() | +------------------+ | 1 | +------------------+ 1 row in set (0.00 sec)
更多信息查看14.11.6, “AUTO_INCREMENT Handling in InnoDB”
如果LAST_INSERT_ID()的参数是一个表达式,返回值就是表达式的结果,也是LAST_INSERT_ID()的值。我们使用下面的步骤模拟这一过程:
Create a table to hold the sequence counter and initialize it:
mysql> [code]CREATE TABLE sequence (id INT NOT NULL);
mysql>
INSERT INTO sequence VALUES (0);
[/code]
Use the table to generate sequence numbers like this:
mysql>
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
mysql>
SELECT LAST_INSERT_ID();
The
UPDATEstatement
increments the sequence counter and causes the next call to
LAST_INSERT_ID()to
return the updated value. The
SELECTstatement
retrieves that value. The
mysql_insert_id()C
API function can also be used to get the value. See Section 23.8.7.37,
“mysql_insert_id()”.
You can generate sequences without calling
LAST_INSERT_ID(),
but the utility of using the function this way is that the ID value is maintained in the server as the last automatically generated value. It is multi-user safe because multiple clients can issue the
UPDATEstatement
and get their own sequence value with the
SELECTstatement
(or
mysql_insert_id()),
without affecting or being affected by other clients that generate their own sequence values.
Note that
mysql_insert_id()is
only updated after
INSERTand
UPDATEstatements,
so you cannot use the C API function to retrieve the value for
LAST_INSERT_ID(expr
) afterexecuting other SQL statements like
SELECTor
SET.
相关文章推荐
- LAST_INSERT_ID() LAST_INSERT_ID(expr)
- SQLite的最后插入记录的ID SELECT last_insert_rowid()
- last_insert_id函数
- MYSQL 小技巧 -- LAST_INSERT_ID
- Mysql LAST_INSERT_ID函数
- 解决Hibernate JPA中insert插入数据后自动执行select last_insert_id()
- last_insert_id()获取mysql最后一条记录ID
- SELECT LAST_INSERT_ID() 的使用和注意事项
- Mysql中LAST_INSERT_ID()的函数使用详解
- mysql函数之六:mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey
- 轻松掌握MySQL函数中的last_insert_id()
- MySQL的LAST_INSERT_ID用法
- mysql中的LAST_INSERT_ID()分析
- sql sever和mysql数据库的存储过程转换过程 scope_identity() last_insert_id();
- mysql函数-mysql函数-LAST_INSERT_ID
- MySQL的LAST_INSERT_ID用法
- MySQL使用LAST_INSERT_ID()获取新插入记录的ID
- ios sqlite 获取自增长id last_insert_rowid
- PHP 获取自增长字段数值 (MySQL的last_insert_id())
- 关于last_insert_id