Я применяю серию триггеров к нескольким таблицам в нашей базе данных - они служат для создания записей мягкого удаления / тени при обновлении определенных релевантных данных.
В качестве примера рассмотрим следующую таблицу:
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