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

th3*_*aly 24 mysql database-trigger

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

INSERT表格中有新内容时ACCOUNTS,我需要更新ACCOUNTSwhere pk=中的行,NEW.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 ;
Run Code Online (Sandbox Code Playgroud)

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

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

请建议一个解决方法

PS:我已经通过已经走在触发更新表上相同的表更新后,插入到相同的表触发的MySQL,在同一个表插入触发器后更新对表后插入MySQL的触发器与插入和更新,但他们不似乎回答我的问题.

编辑

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
Run Code Online (Sandbox Code Playgroud)

pja*_*ama 25

看来你不能在触发器中做到这一切.根据文件:

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

根据这个答案,你似乎应该:

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

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


小智 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
Run Code Online (Sandbox Code Playgroud)

  • 这得到了我的反对,因为它完全忽略了明确声明的请求,即更新应该作用于不同的记录,而不是新插入的记录。 (2认同)

小智 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 ;
Run Code Online (Sandbox Code Playgroud)

  • 这引起了我的反对,因为它完全忽略了明确规定的请求,即更新应该作用于不同的记录,而不是新插入的记录。 (2认同)