MySQL - 插入后触发更新同一个表的触发器

问题描述 投票:22回答:5

这是我正在尝试做的事情:

INSERT表中有一个新的ACCOUNTS时,我需要通过设置ACCOUNTS来更新pkNEW.edit_on = status='E'的行,以表示特定(旧)帐户已被编辑。

DELIMITER $$

DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` AFTER INSERT on ACCOUNTS
FOR EACH ROW BEGIN
    update ACCOUNTS set status='E' where ACCOUNTS.pk = NEW.edit_on ;
END$$

DELIMITER ;

要求不是我操纵新插入的列,而是使用pk = NEW.edit_on操作已经存在的列

但是,我无法更新同一个表:Can't update table ACCOUNTS ... already used by the statement that invoked this trigger

请建议一个解决方法

PS:我已经通过了Updating table in trigger after update on the same tableInsert into same table trigger mysqlUpdate with after insert trigger on same tablemysql trigger with insert and update after insert on table,但他们似乎没有回答我的问题。

编辑

ACCOUNTS表:

CREATE TABLE  `ACCOUNTS` (
  `pk` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` bigint(9) unsigned NOT NULL,
  `edit_on` bigint(10) unsigned DEFAULT NULL,
  `status` varchar(1) NOT NULL DEFAULT 'A',
  PRIMARY KEY (`pk`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2147483726 DEFAULT CHARSET=latin1
mysql database-trigger
5个回答
23
投票

看来你不能在触发器中做到这一切。根据documentation

在存储的函数或触发器中,不允许通过调用函数或触发器的语句修改已经使用(用于读取或写入)的表。

根据this answer,你似乎应该:

创建一个存储过程,插入/更新目标表,然后更新事务中的所有其他行。

使用存储过程,您将手动提交更改(插入和更新)。我没有在MySQL中做过这个,但是this post看起来就是一个很好的例子。


9
投票

这是我在插入时更新同一个表中的行的方法

activationCode和email是表USER中的行。在插入时,我没有为activationCode指定值,它将由mysql动态创建。

使用您的mysql用户名更改'username',使用您的db名称更改'db_name'。

CREATE DEFINER=`username`@`localhost` 
       TRIGGER `db_name`.`user_BEFORE_INSERT` 
       BEFORE INSERT ON `user` 
       FOR EACH ROW
         BEGIN
            SET new.activationCode = MD5(new.email);
         END

5
投票

有同样的问题,但不得不更新一个即将进入的ID的列,所以你可以做一个更新应该在BEFORE之前和之后没有ID没有id所以我做了这个技巧

DELIMITER $$
DROP TRIGGER IF EXISTS `codigo_video`$$
CREATE TRIGGER `codigo_video` BEFORE INSERT ON `videos` 
FOR EACH ROW BEGIN
    DECLARE ultimo_id, proximo_id INT(11);
    SELECT id INTO ultimo_id FROM videos ORDER BY id DESC LIMIT 1;
    SET proximo_id = ultimo_id+1;
    SET NEW.cassette = CONCAT(NEW.cassette, LPAD(proximo_id, 5, '0'));
END$$
DELIMITER ;

2
投票

在最后一个条目;这是另一个伎俩:

SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_schema = ... and table_name = ...

0
投票

相反,您可以在插入之前使用并获取特定表的max pkid,然后更新maximium pkid表记录。


0
投票

DELIMITER $$

DROP TRIGGER如果存在setEditStatus $$创建触发器setEditStatus在插入每个行的帐户之前开始

SET NEW.STATUS = 'E';

END $$

DELIMITER;

© www.soinside.com 2019 - 2024. All rights reserved.