|
|
|
mutating table ORA-04091
|
|||
|---|---|---|---|
|
#18+
Приветствую. Имеется Oracle 9.2 В строчном тригере BEFORE UPDATE ON TABLE1 есть необходимость написать хитрый SELECT на эту же таблицу. в зависимости от результата селекта делать или не делать raise_application_error(-20001,'Нельзя так апдейтить!!!!'). Пытаюсь сделать - таблица мутирует. Может как-то можно, по хотрому... такую мутацию обойти???? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2003, 08:24:14 |
|
||
|
mutating table ORA-04091
|
|||
|---|---|---|---|
|
#18+
Прошу прощения, неправильно поставил вопрос. Мне нужно избежать самого факта изменения записи в TABLE1 когда результат выполнения SELECT . . .. .FROM TABLE1 меня не устраивает. т.е. когда отработает строчный тригер BEFORE UPDATE ON TABLE1, что-либо проверять уже поздно. Соответственно решение стандартной задачи с мутирующими таблицами Код: plaintext 1. 2. 3. 4. 5. 6. , которую описыват Том Кайт, мне не подходит. . . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2003, 11:07:58 |
|
||
|
mutating table ORA-04091
|
|||
|---|---|---|---|
|
#18+
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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2003, 16:19:35 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=32191900&tid=1989785]: |
0ms |
get settings: |
9ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
216ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
29ms |
get tp. blocked users: |
1ms |
| others: | 225ms |
| total: | 512ms |

| 0 / 0 |
