简体   繁体   English

如何更新 Mysql 触发器中的 LAST_INSERT_ID

[英]How could I update the LAST_INSERT_ID in Mysql Trigger

In my MySQL Database, I have a table with a composite primary key where the ID is not in auto_increment mode.在我的 MySQL 数据库中,我有一个包含复合主键的表,其中 ID不是 auto_increment模式。 Something like this:像这样的东西:

CREATE TABLE table_a (
    fk_table_b INT UNSIGNED NOT NULL,
    id INT UNSIGNED,
    label VARCHAR(80) NOT NULL,
    PRIMARY KEY (fk_table_b, id),
    FOREIGN KEY fk_table_b
        REFERENCES table_b(id)
);

To increment the ID in function of the foreign key, I made a trigger like this:为了增加外键的 function 中的 ID,我做了一个这样的触发器:

DELIMITER $$
CREATE TRIGGER table_a_auto_increment
BEFORE INSERT ON table_a
FOR EACH ROW BEGIN
    SET NEW.id = (
        SELECT IFNULL(MAX(id), 0) + 1
        FROM table_a
        WHERE table_a.fk_table_b  = NEW.fk_table_b
    ); 
END $$
DELIMITER ;

But when I do SELECT LAST_INSERT_ID() I am getting 0 as the new id... Normally you could override the LAST_INSERT_ID() by giving it a number like this:但是当我做SELECT LAST_INSERT_ID()我得到 0 作为新的 id ......通常你可以通过给它一个这样的数字来覆盖LAST_INSERT_ID()

INSERT table_a ( fk_table_b, id)
VALUES (1, LAST_INSERT_ID(5));
SELECT LAST_INSERT_ID(); -- -> it gives me 5

So I have tried to combine both to do this trigger:所以我试图结合两者来做这个触发器:

DELIMITER $$
CREATE TRIGGER table_a_auto_increment
BEFORE INSERT ON table_a
FOR EACH ROW BEGIN
    SET NEW.id = (
        SELECT LAST_INSERT_ID(IFNULL(MAX(id), 0) + 1)
        FROM table_a
        WHERE table_a.fk_table_b  = NEW.fk_table_b
    ); 
END $$
DELIMITER ;

But it's still giving me 0 when I insert something in the base... Do you know if there is a way to make it work?但是当我在底座中插入一些东西时它仍然给我0......你知道是否有办法让它工作吗?

Thanks a lot.非常感谢。

-- EDIT 2020-08-14 -- 编辑 2020-08-14

Finally it seems impossible to override the LAST_INSERT_ID function inside the TRIGGER, so I changed my solution by removing the trigger and doing it inside my insert function like this:最后,似乎不可能在 TRIGGER 中覆盖 LAST_INSERT_ID function,所以我通过移除触发器并在我的插入 function 中执行它来更改我的解决方案,如下所示:

INSERT table_a ( fk_table_b, id, label)
VALUES (1, LAST_INSERT_ID((
    SELECT IFNULL(MAX(old_one.id), 0) + 1
    FROM table_a AS old_one
    WHERE old_one.fk_table_b  = table_a.fk_table_b
)), "something");

And then, this is giving me the good result I can use in my backend:)然后,这给了我可以在后端使用的好结果:)

You may use additional service table:您可以使用附加服务表:

CREATE TABLE service_table (id BIGINT AUTO_INCREMENT PRIMARY KEY);

and

DELIMITER $$
CREATE TRIGGER table_a_auto_increment
BEFORE INSERT ON table_a
FOR EACH ROW 
BEGIN
    SET NEW.id = (
        SELECT IFNULL(MAX(id), 0) + 1
        FROM table_a
        WHERE table_a.fk_table_b  = NEW.fk_table_b
    ); 
    DELETE FROM service_table WHERE id IS NOT NULL;
    INSERT INTO service_table VALUES (NEW.id - 1);
    INSERT INTO service_table VALUES (NULL);
    SET NEW.id = LAST_INSERT_ID() - 1;
END $$
DELIMITER ;

fiddle (foreign key removed).小提琴(已删除外键)。


  1. Maybe the code may be simplified a little - do it yourself.也许代码可能会简化一点 - 自己做。
  2. Service table may be defined as Engine = MEMORY (if available).服务表可以定义为 Engine = MEMORY(如果可用)。
  3. The code is not safe for concurrent inserts.该代码对于并发插入是不安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM