Есть ли способ использовать триггер MySQL для дублирования записи в таблице, но изменить данные перед вставкой? - PullRequest
1 голос
/ 22 февраля 2020

Я применяю серию триггеров к нескольким таблицам в нашей базе данных - они служат для создания записей мягкого удаления / тени при обновлении определенных релевантных данных.

В качестве примера рассмотрим следующую таблицу:

CREATE TABLE `cms_content` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(40) NOT NULL,
  `tag` varchar(20) NOT NULL,
  `data` text NOT NULL,
  `is_active` tinyint(1) unsigned NOT NULL DEFAULT '0',
  `created_by` int(10) unsigned DEFAULT NULL,
  `updated_by` int(10) unsigned DEFAULT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='                   ';

Использование этого запроса

UPDATE cms_content SET `tag` = 'user-cities-field' WHERE id = 3;

Когда этот запрос выполняется, я хочу по существу выполнить следующие манипуляции:

  • Установите для INSERT id входящей записи значение NULL, чтобы AUTO_INCREMENT соответственно установило следующее значение.
  • Вставьте копию записи, которая была обновлено , единственное изменение состоит в том, что для флага is_active необходимо установить 1
  • Я знаю, что вы не можете обновить таблицу изнутри, так как MySQL заблокирует ее, чтобы предотвратить рекурсия.
  • Если есть способ, можете ли вы по существу выбрать обновляемую запись до ее обновления, а затем INSERT измененную запись?

Было бы больше полезно использовать хранимую функцию для справиться с этим?

Что мне нужно , чтобы сделать, это выбрать СТАРОЮ запись pre-update, а затем изменить значение флага is_active на этой записи до ее вставки. Код, с которым я работал, приведен ниже.

Триггер

CREATE DEFINER=`root`@`localhost` TRIGGER `cms_content_AFTER_UPDATE` BEFORE UPDATE ON `cms_content` FOR EACH ROW BEGIN
    IF (NEW.is_active = 1) THEN

        SET NEW.id = NULL;

        INSERT INTO `tester`.`cms_content` (SELECT *, 0 as is_active  from `cms_content` WHERE `id` = OLD.`id`);
        #UPDATE      `tester`.`cms_content` SET is_active = 0 WHERE `id` = OLD.`id`;

    END IF;
END
...