SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 23.03.2013 17:11:41

khusamov
Участник
Откуда: Москва
Зарегистрирован: 23.03.2013
Сообщений: 7

Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Здравствуйте!

Я внутри триггера делаю UPDATE записи из таблицы section, на которую этот триггер повешен:

CREATE TRIGGER plastcom_site.trigger1
AFTER UPDATE ON plastcom_site.section FOR EACH ROW
BEGIN
    UPDATE section SET path = "newpath" WHERE section_id = 20;
END


MySQL сообщает об ошибке. Что, мол, нельзя делать UPDATE в таблице, текущая запись которой уже находится в режиме обновления.

Как это ограничение можно обойти?

Пояснение: тут сам триггер примерный и число 20 взято для примера и оно всегда не равно номеру текущей записи.

Неактивен

 

#2 23.03.2013 17:21:14

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

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

Неактивен

 

#3 23.03.2013 17:29:02

khusamov
Участник
Откуда: Москва
Зарегистрирован: 23.03.2013
Сообщений: 7

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Е-мое! Спасибо! Теперь понятно почему нельзя этого делать!

Неактивен

 

#4 23.03.2013 18:01:39

khusamov
Участник
Откуда: Москва
Зарегистрирован: 23.03.2013
Сообщений: 7

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Переделал пример триггера. Теперь видно, что рекурсия не бесконечная.

CREATE TRIGGER plastcom_site.trigger1
AFTER UPDATE ON plastcom_site.section FOR EACH ROW
BEGIN

  DECLARE done INT DEFAULT FALSE;
  DECLARE s_id INT DEFAULT 0;

  DECLARE Cur1 Cursor for SELECT section_id FROM section WHERE parent_id = new.section_id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
 
  OPEN Cur1;
 
    loop1: LOOP
      FETCH cur1 INTO s_id;  
      IF done THEN LEAVE loop1; END IF;
      UPDATE section SET path = section_path_of_parent(parent_id) WHERE section_id = s_id;
    END LOOP;
 
  CLOSE Cur1;
 
END


Здесь функция section_path_of_parent является обычным SELECT который выдает путь родителя в виде строки.

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

Неактивен

 

#5 23.03.2013 18:08:07

khusamov
Участник
Откуда: Москва
Зарегистрирован: 23.03.2013
Сообщений: 7

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Можно ли в этом случае обойти ограничение?
Условие выхода из рекурсии есть:

IF done THEN LEAVE loop1; END IF;

Неактивен

 

#6 23.03.2013 21:17:24

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Да, рекурсия не обязана быть бесконечной, поэтому такое ограничение есть не во всех базах данных. Но в MySQL ограничение есть, способа обойти не знаю.

Неактивен

 

#7 25.03.2013 02:54:46

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

А правда же Вы обновляете одну текущую строку? Нельзя обработать в NEW.xxx?

Неактивен

 

#8 26.03.2013 05:38:00

khusamov
Участник
Откуда: Москва
Зарегистрирован: 23.03.2013
Сообщений: 7

Re: Обход ограничения на UPDATE в триггере, повешенному на событие AFTER UPDATE

Нет, я там обновляю много строк (UPDATE вызывает каскадный вызов этого же триггера, по сути рекурсия).

Нашел способ обойти ограничение:

1) Структуру дерева вынес в отдельную таблицу.
2) Также создал таблицу с предками разделов (от родителя до корня).

Этого достаточно.

Спасибо rgbeast за подсказки!

Отредактированно khusamov (26.03.2013 05:41:01)

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson