Второй триггер, инициированный первым, вызывает ошибку? - PullRequest
0 голосов
/ 12 апреля 2019

Я использую таблицу с именем inbox, в которой хранятся запросы от skills_matrix для изменения skills_matrix. area_id. Триггер на skills_matrix выполняется нормально, однако триггер на inbox прерывается при обновлении skills_matrix со следующей ошибкой:

ERROR 1442 (HY000): Can't update table 'inbox' in stored function/trigger because it 
is already used by statement which invoked this stored function/trigger

Я попытался добавить дополнительный столбец skills_matrix. area_change_pending для использования в условии триггеров skills_matrix, чтобы предотвратить выполнение оператора.

CREATE DEFINER=`root`@`localhost` TRIGGER `skills_matrix_BEFORE_UPDATE` BEFORE UPDATE ON `skills_matrix` FOR EACH ROW BEGIN
    IF (OLD.area_change_pending = 0 AND OLD.area_id != NEW.area_id) THEN
        INSERT INTO `inbox` (`id`, `prev_area`, `prop_area`, `status`) VALUES ("0",OLD.area_id,NEW.area_id,"0");
        SET NEW.area_id = OLD.area_id;
        SET NEW.area_change_pending = 1;
    END IF;
END

Также искали в Интернете:

Триггеры SQL вызывают ошибки

Логика триггера вызывает ошибку

Остальная часть SQL:

| skill_matrix |

CREATE TABLE `skills_matrix` (
`id` int(11) NOT NULL,
`area_id` int(11) NOT NULL,
`area_change_pending` tinyint(1) NOT NULL DEFAULT 0 COMMENT '0 = Not pending request, 1 = pending request to change area',
PRIMARY KEY (`id`),
KEY `fk_skills_matrix_area1_idx` (`area_id`)
) 

ENGINE=InnoDB DEFAULT CHARSET=utf8 |

CREATE DEFINER=`root`@`localhost` TRIGGER `skills_matrix_BEFORE_UPDATE` BEFORE UPDATE ON `skills_matrix` FOR EACH ROW BEGIN
    IF (OLD.area_change_pending = 0 AND OLD.area_id != NEW.area_id) THEN
        INSERT INTO `inbox` (`id`, `prev_area`, `prop_area`, `status`) VALUES ("0",OLD.area_id,NEW.area_id,"0");
        SET NEW.area_id = OLD.area_id;
        SET NEW.area_change_pending = 1;
    END IF;
END

| Входящие

CREATE TABLE `inbox` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`prev_area` int(11) DEFAULT NULL,
`prop_area` int(11) DEFAULT NULL,
`status` tinyint(1) DEFAULT 0 COMMENT '0 = pending acceptance, 1 = accepted',
PRIMARY KEY (`id`,`clock_number`)
) 

ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 |

CREATE DEFINER=`root`@`localhost` TRIGGER `inbox_BEFORE_UPDATE` BEFORE UPDATE ON `inbox` FOR EACH ROW BEGIN
    IF (NEW.status = 1) THEN
    UPDATE `skills_matrix`  SET `skills_matrix`.`area_change_pending` = 0, `skills_matrix`.`area_id` = NEW.prop_area;
    DELETE FROM `loadall_portal`.`skills_matrix` WHERE `loadall_portal`.`skills_matrix`.`status` = 1;
    END IF;
END

Ожидается, что при изменении inbox. status на 1 он обновит skills_matrix. area_id с помощью NEW. prop_area и удалит строку из inbox и установите skills_matrix. area_change_pending = 0, поскольку изменение области теперь принято.

Почему эта ошибка отображается, даже если OLD. area_change_pending в условии skills_matrix_BEFORE_UPDATE, предотвращающем выполнение любых операторов при срабатывании inbox_BEFORE_UPDATE? Есть лучший способ сделать это? Правильно ли я использую триггеры, или это может быть достигнуто с помощью более простого подхода? (впервые используя триггеры - любая помощь очень ценится!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...