powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / mutating table ORA-04091
4 сообщений из 4, страница 1 из 1
mutating table ORA-04091
    #32191858
Boris A. Andreev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую.
Имеется Oracle 9.2
В строчном тригере BEFORE UPDATE ON TABLE1 есть необходимость написать хитрый SELECT на эту же таблицу. в зависимости от результата селекта делать или не делать raise_application_error(-20001,'Нельзя так апдейтить!!!!').
Пытаюсь сделать - таблица мутирует.
Может как-то можно, по хотрому... такую мутацию обойти????
...
Рейтинг: 0 / 0
mutating table ORA-04091
    #32191900
Фотография Andrew Campball
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
mutating table ORA-04091
    #32192032
Boris A. Andreev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Прошу прощения, неправильно поставил вопрос.
Мне нужно избежать самого факта изменения записи в TABLE1 когда результат выполнения SELECT . . .. .FROM TABLE1 меня не устраивает.
т.е. когда отработает строчный тригер BEFORE UPDATE ON TABLE1, что-либо проверять уже поздно. Соответственно решение стандартной задачи с мутирующими таблицами
Код: plaintext
1.
2.
3.
4.
5.
6.
before update
...
after update for each row
....
after update
....

, которую описыват Том Кайт, мне не подходит. . .
...
Рейтинг: 0 / 0
mutating table ORA-04091
    #32192797
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Well, it is a slight variation of mutating table issue. The only difference BEFORE UPDATE FOR EACH ROW trigger needs to collect rowid + all :OLD values for the rows you do not want to be updated. Then AFTER UPDATE statement level trigger issues UPDATE agaist saved rows setting the old values back (see Tom Kyte's Case 2 - you need to access the :old values). What is different in your case is RECURSION. Tom Kyte's example 2 avoids the issue since triggers are DELETE triggers and AFTER DELETE statement level trigger issues an INSERT. In your case you have UPDATE triggers and AFTER UPDATE statement level trigger issues UPDATE. As a result, if you follow Tom Kyte's example you will end up in an infinite recursion (which will error out on level 50 - that is how many Oracle sypports. I will explain in more details.

1. User issues an UPDATE.
2. BEFORE UPDATE statement level trigger clears PL/SQL table
3. BEFORE UPDATE for each row trigger populates PL/SQL table
4. ATER UPDATE statement level trigger reads PL/SQL table and issues UPDATE. As a result we are back to step 2 - an infinite loop.

To resolve the issue you need:

1. Add a global package variable RECURSION BOOLEAN;
2. In BEFORE UPDATE statement level trigger use:

IF NOT RECURSION THEN clear PL/SQL table END IF;

3. In BEFORE UPDATE for each row trigger use:

IF NOT RECURSION THEN populate PL/SQL table END IF;

4. In ATER UPDATE statement level trigger use:

IF NOT RECURSION
THEN
RECURSION := TRUE;
loop through PL/SQL table and issue UPDATEs
RECURSION := FALSE;
END IF;

5. Add

EXCEPTION
WHEN OTHERS THEN
RECURSION := FALSE;
RAISE;

to all triggers. Otherwise RECURSION might not be reset back to true if one of the triggers raises an exception.

SY.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / mutating table ORA-04091
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]