MySQL - триггер для обновления той же таблицы после вставки

Вот что я пытаюсь сделать:

Когда в таблицу ACCOUNTS добавлен новый INSERT, мне нужно обновить строку в ACCOUNTS, где 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 ;

Требование НЕ, что я манипулирую недавно вставленным столбцом, но уже существующий столбец с pk = NEW.edit_on

Однако я не могу обновить ту же таблицу: Can't update table ACCOUNTS ... already used by the statement that invoked this trigger

Пожалуйста, предложите обходное решение

PS: Я уже прошел Обновление таблицы в триггере после обновления в той же таблице, Вставить в ту же таблицу триггер mysql, Обновить с помощью триггера вставки в той же таблице и триггер mysql с вставкой и обновлением после вставки в таблицу, но они, похоже, не отвечают на мой вопрос.

Edit

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

Ответы

Ответ 1

Кажется, что вы не можете сделать все это в триггере. Согласно документации:

Внутри хранимой функции или триггера запрещено изменять таблицу, которая уже используется (для чтения или записи) оператором, который вызвал функцию или триггер.

Согласно этому ответу кажется, что вы должны:

создайте хранимую процедуру, которая вставляет в /Updates целевую таблицу, затем обновляет другую строку (и), все в транзакции.

С сохраненным процессом вы будете фиксировать изменения вручную (вставлять и обновлять). Я не делал этого в MySQL, но этот пост выглядит хорошим примером.

Ответ 2

Вот как я обновляю строку в той же таблице при вставке

activationCode и email - это строки в таблице USER. На вставке я не укажу значение для кода активации, оно будет создано на лету mysql.

Измените "имя пользователя" на свое имя пользователя mysql и "db_name" с вашим именем db.

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

Ответ 3

Имела ту же проблему, но ей пришлось обновить столбец с идентификатором, который должен был войти, поэтому вы можете сделать обновление, которое должно быть выполнено ПЕРЕД И ПОСЛЕ НЕ ПРЕЖДЕ ЧЕМ не было идентификатора, поэтому я сделал этот трюк

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 ;

Ответ 4

В последней записи; это еще один трюк:

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

Ответ 5

Вместо этого вы можете использовать перед вставкой и получить max pkid для конкретной таблицы, а затем обновить запись таблицы maximium pkid.

Ответ 6

DELIMITER $$

DROP TRIGGER IF EXISTS 'setEditStatus'$$
CREATE TRIGGER 'setEditStatus' **BEFORE** INSERT on ACCOUNTS
FOR EACH ROW BEGIN

    SET NEW.STATUS = 'E';

END$$

DELIMITER ;