Проблема с триггером в MySQL
`statusid` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`statusdate` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`shelfid` BIGINT(20) NOT NULL,
`thingstatusid` BIGINT(20) NOT NULL,
`recepientid` INT(11) NOT NULL,
`isactive` INT(11) NOT NULL DEFAULT '1',
`changeraiting` INT(11) NOT NULL DEFAULT '10',
`description` text,
`whocreated` INT(11) NOT NULL,
`statuspayment` INT(11) NOT NULL DEFAULT '0',
`regionid` BIGINT(20) NOT NULL,
PRIMARY KEY (`statusid`),
KEY `shelfid` (`shelfid`),
KEY `thingstatusid` (`thingstatusid`),
KEY `recepientid` (`recepientid`),
KEY `whocreated` (`whocreated`),
KEY `regionid` (`regionid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=33 ;
--
-- Триггеры `sm_shelfstatuses`
--
DROP TRIGGER IF EXISTS `sm_shelfstatuses_before_ins_tr`;
DELIMITER //
CREATE TRIGGER `sm_shelfstatuses_before_ins_tr` BEFORE INSERT ON `sm_shelfstatuses`
FOR EACH ROW BEGIN
UPDATE `sm_shelfstatuses` SET `isactive` = 0 WHERE `shelfid` = NEW.`shelfid`;
END
//
DELIMITER ;
--
-- Ограничения внешнего ключа сохраненных таблиц
--
--
-- Ограничения внешнего ключа таблицы `sm_shelfstatuses`
--
ALTER TABLE `sm_shelfstatuses`
ADD CONSTRAINT `sm_shelfstatuses_fk4` FOREIGN KEY (`regionid`) REFERENCES `sm_regions` (`regionId`),
ADD CONSTRAINT `sm_shelfstatuses_fk` FOREIGN KEY (`shelfid`) REFERENCES `sm_thingshelf` (`shelfid`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `sm_shelfstatuses_fk1` FOREIGN KEY (`thingstatusid`) REFERENCES `sm_sprthingshelfstatuses` (`thingstatusid`),
ADD CONSTRAINT `sm_shelfstatuses_fk2` FOREIGN KEY (`recepientid`) REFERENCES `sm_users` (`id`),
ADD CONSTRAINT `sm_shelfstatuses_fk3` FOREIGN KEY (`whocreated`) REFERENCES `sm_users` (`id`);
Есть у кого какие нибудь идеи в чем может быть причина ошибки?
Версия сервера: 5.5.16
Версия MySQL-клиента: mysqlnd 5.0.8-dev - 20102224 - $Revision: 310735
A stored function or trigger cannot modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
Реализуй логику в скрипте или вставку через stored procedure с соответствующими проверками.
Наверное, в где-то доке должно быть описано, что изменять ту же таблицу, на которую висит триггер -- нарушение логики транзакций. В некоторых СУБД можно эмулировать операции DML, полностью подменяя их триггерами instead of. Обычно это доступно только для представлений, как в Oracle. Есть даже мнение, что конечной программе не нужно давать доступ к таблицам, а только к представлениям с триггерами instead of, реализующими нужную логику.
Наверное, в где-то доке должно быть описано, что изменять ту же таблицу, на которую висит триггер -- нарушение логики транзакций.
сложно сказать. наверное гдето описано. с одной стороны да - так как триггер работает вне транзакции - то попытка модифицировать данные в данной таблице может запросто привести к неоднозначности. в общем как страшно жить.
А вот не факт. В Oracle триггер всегда внутри транзакции, потому что транзакции принудительные, и нет транзакции -- нет и сеанса пользователя.
Глядя на последние изменения MySQL, наблюдаемые по форумам и от знакомых, показалось, что после покупки Oracle хочет подтянуть его к (своему?) стандарту, -- хотя бы в тех рамках, где можно. Триггеры, работающие в транзакции, похожи на одно из таких изменений. Это если считать, что запрет на изменение таблиц -- именно из-за транзакций, а не желания разработчиков насолить пользователям.
Я доку не читал, поэтому только предполагаю. :-)
проканает наверняка.
стесняюсь спросить - а нахера? :)
мне то надо что бы в ноль были установлены как раз таки те записи, которые в таблице уже есть.
Почитал поподробнее о триггерах в мускуле - сыровато. Есть очень неприятные моменты:
Note
Currently, cascaded foreign key actions do not activate triggers.