MYSQL LAST_INSERT_ID 未按预期工作。我该如何解决?

Posted

技术标签:

【中文标题】MYSQL LAST_INSERT_ID 未按预期工作。我该如何解决?【英文标题】:MYSQL LAST_INSERT_ID not working as intended. How do I fix? 【发布时间】:2015-02-13 01:52:55 【问题描述】:

我编写了 mysql StoredProcedure 来为每个表值创建并返回新 ID,但是,它在 MySQL WorkBench 和 Java 应用程序的 last_insert_id() 上得到了错误的值。

将从多个会话中调用此过程。

CALL `GET_NEW_ID`('test', @test);
select @test;

它给了我“141215000000”,这意味着 last_insert_id() 一直返回 0。 我看到它正确地将新数据插入到 seq_data 中。

CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12))
BEGIN

    INSERT INTO seq_data ( id, `name`, `stat_date`)
    SELECT IFNULL(MAX(id), 0)+1, V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d');
    SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0'));

END

表格是这样的。

CREATE TABLE `seq_data` (
  `id` int(6) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) COLLATE utf8_bin NOT NULL,
  `stat_date` varchar(8) COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`id`,`name`,`stat_date`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

我的目标是……

CALL `GET_NEW_ID`('test', @test);
select @test;

返回 141215000001

CALL `GET_NEW_ID`('test', @test);
select @test;

返回 141215000002

CALL `GET_NEW_ID`('hello', @test);
select @test;

返回 141215000001

【问题讨论】:

【参考方案1】:

如MySQL documentation 中所述,LAST_INSERT_ID() 返回一个 BIGINT(64 位)值,表示由最近执行的 INSERT 语句为 AUTO_INCREMENT 列设置的第一个自动生成的值,以影响此类列

在您的情况下,您正在插入 id,因此不会生成 AUTO_INCREMENT 值,因此 LAST_INSERT_ID 返回 0。

你可以试试这样的:

CREATE PROCEDURE `GET_NEW_ID`(IN V_TABLE VARCHAR(10), OUT V_ID VARCHAR(12))
BEGIN

    INSERT INTO seq_data (`name`, `stat_date`)
    SELECT V_TABLE, DATE_FORMAT(NOW(),'%Y%m%d') FROM seq_data WHERE name = V_TABLE AND stat_date = DATE_FORMAT(NOW(),'%Y%m%d');
    SET V_ID = concat(DATE_FORMAT(NOW(),'%y%m%d'),LPAD(LAST_INSERT_ID(), 6, '0'));

END

【讨论】:

感谢@Dondon 的回答。但我已经尝试过了,插入 id 的原因是为不同的列“名称”获取一个新的 id。例如,如果我想为表 hello 获取一个新的 id,那么它的 id 不会从 1 开始,因为测试表名还有另一个 id 1。 再次感谢@Dodon,这解释了为什么它没有按我的预期工作,我需要找到解决方法来解决问题。 @handicop 你做错了。自己生成一个新 ID 并然后手动插入它不是正确的答案。它忽略了开始的事务性要求。您甚至不应该拥有 GET_NEW_ID() 过程。它应该作为INSERT 在带有AUTO_INCREMENT 键的表中的副作用而自动发生。 嗨@EJP,是的,我刚刚和一个非常了解 DB 的人聊天,他说的和你在这里写的完全一样。现在我更改了表结构并删除了 GET_NEW_ID 过程。非常感谢!

以上是关于MYSQL LAST_INSERT_ID 未按预期工作。我该如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 索引未按预期使用

Mysql:使用左连接选择未按预期工作

MySQL ResultSet 可滚动/可更新未按预期工作

Lumen MySQL 查询未按预期处理 UTF8 值

MySQL Multiple INNER JOIN + GROUP BY 未按预期工作

MySQL NOT IN 子查询未按预期工作