1. select max(id) from tablename
2.SELECT LAST_INSERT_ID() 函数
LAST_INSERT_ID 是与table无关的,如果向表a插入数据后,再向表b插入数据,LAST_INSERT_ID会改变。
在多用户交替插入数据的情况下max(id)显然不能用。这时就该使用LAST_INSERT_ID了,因为LAST_INSERT_ID是基于Connection的,只要每个线程都使用独立的 Connection对象,LAST_INSERT_ID函数将返回该Connection对AUTO_INCREMENT列最新的insert or update 操作生成的第一个record的ID。这个值不能被其它客户端(Connection)影响,保证了你能够找回自己的 ID 而不用担心其它客户端的活动,而且不需要加锁。使用单INSERT语句插入多条记录, LAST_INSERT_ID返回一个列表。
3. select @@IDENTITY;
@@identity 是表示的是最近一次向具有identity属性(即自增列)的表插入数据时对应的自增列的值,是系统定义的全局变量。一般系统定义的全局变量都是以@@开头,用户自定义变量以@开头。
比如有个表A,它的自增列是id,当向A表插入一行数据后,如果插入数据后自增列的值自动增加至101,则通过select @@identity得到的值就是101。使用@@identity的前提是在进行insert操作后,执行select @@identity的时候连接没有关闭,否则得到的将是NULL值。
这个语句很特别,没有关联到特定的SQL语句,会 让人感觉迷糊,他到底是怎么获取值的。在并发情况下会不会获取其他线程执行后的值。
答案是有可能的,但是不用怕、是可控的。只有不当的编码才会导致取到其他线程的值。先来说一下原理:
1
2
|
SUMMARY
The Jet OLE DB version 4.0 provider supports the
SELECT
@@Identity query that allows you
to
retrieve the value
of
the auto-increment field generated
on
your
connection
. Auto-increment
values
used
on
other connections
to
your
database
do
not
affect the results
of
this specialized query. This feature works
with
Jet 4.0 databases but
not
with
older formats.
|
大致意思是【SELECT @@IDENTITY】获取的是当前数据库连接的前一次执行的值。其他连接执行的值不会影响当前线程。时下流行的框架(如Spring-jdbc、mybatis、hibernate)的数据库连接都是存在ThreadLocal中的、是线程隔离的,所以不会获取到其他线程中的【SELECT @@IDENTITY】值。当多线程 编程 时、强制把 数据库 连接传给各个线程同时执行时才会取到其他线程的【SELECT @@IDENTITY】。
2、在MySql中模拟Sequence
第一步:创建--Sequence 管理表
1
2
3
4
5
6
7
|
DROP
TABLE
IF EXISTS
sequence
;
CREATE
TABLE
WFO_SEQ(
name
VARCHAR
(50)
NOT
NULL
,
current_value
INT
NOT
NULL
,
increment
INT
NOT
NULL
DEFAULT
1,
PRIMARY
KEY
(
name
)
) ENGINE=InnoDB;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
DROP
FUNCTION
IF EXISTS currval;
DELIMITER $
CREATE
FUNCTION
currval (seq_name
VARCHAR
(50))
RETURNS
INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS
SQL
SQL SECURITY DEFINER
COMMENT
''
BEGIN
DECLARE
value
INTEGER
;
SET
value = 0;
SELECT
current_value
INTO
value
FROM
WFO_SEQ
WHERE
name
= seq_name;
RETURN
value;
END
$
DELIMITER ;
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
DROP
FUNCTION
IF EXISTS nextval;
DELIMITER $
CREATE
FUNCTION
nextval (seq_name
VARCHAR
(50))
RETURNS
INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS
SQL
SQL SECURITY DEFINER
COMMENT
''
BEGIN
DECLARE
C_V
INTEGER
;
UPDATE
WFO_SEQ
SET
CURRENT_VALUE = CURRENT_VALUE + INCREMENT
WHERE
NAME
= SEQ_NAME;
SET
C_V = CURRVAL(SEQ_NAME);
IF C_V = -1
THEN
INSERT
INTO
WFO_SEQ(
NAME
, CURRENT_VALUE, INCREMENT)
VALUES
(SEQ_NAME, 1, 1);
RETURN
1;
END
IF;
RETURN
C_V;
END
$
DELIMITER ;
|
第四步:创建--更新当前值的函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
DROP
FUNCTION
IF EXISTS setval;
DELIMITER $
CREATE
FUNCTION
setval (seq_name
VARCHAR
(50), value
INTEGER
)
RETURNS
INTEGER
LANGUAGE SQL
DETERMINISTIC
CONTAINS
SQL
SQL SECURITY DEFINER
COMMENT
''
BEGIN
UPDATE
WFO_SEQ
SET
current_value = value
WHERE
name
= seq_name;
RETURN
currval(seq_name);
END
$
DELIMITER ;
|
第五步:测试函数功能
SELECT SETVAL('TestSeq', 10);---设置指定sequence的初始值
SELECT CURRVAL('TestSeq');--查询指定sequence的当前值
SELECT NEXTVAL('TestSeq');--查询指定sequence的下一个值
4. SHOW TABLE STATUS;
得出的结果里边对应表名记录中有个Auto_increment字段,里边有下一个自增ID的数值就是当前该表的最大自增ID.