|
|
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Есть два триггера. В них работает одинаковая логика (только SELECT). Один проходит нормально - другой отвергается ораклом из-за mutating table. Прочтя руководство и, убедившись в его неправильности, попробовал написать тестовый триггер, который считает количество строк в таблице. Когда в эту таблицу я добавляю INSERT'ом - все ок. DELETE - тоже mutating table error. Вывод, иметь доступ к изменяющейся таблице можно, это же подтверждает и один из оригинальных триггеров. Как с этим бороться? Селекты триггеров отличаются только одной таблицей. Эти таблицы (отличиющиеся) не ссылаются ни на кого, и никто на них не ссылается так же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 15:35 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Припоминаю я, что в 7-ке мы как-то делали select из этой же таблице в триггере after insert for each row. Может это ложное воспоминание, но для 9i я не верю в "неправильность руководства": "A mutating table is a table that is currently being modified by an UPDATE, DELETE, or INSERT statement": Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:06 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:16 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
У тебя BEFORE UPDATE, у меня AFTER UPDATE. Имхо получается, что фразу "A mutating table is a table that is currently being modified" следует понимать так: таблица, которая _изменена_ (или изменяется) к настоящему времени. Во время выполнения триггера BEFORE UPDATE данные таблицы еще не меняются. Такой триггер дает ответ на вопрос: сколько записей было перед изменением, не после. Выполнив твой скрипт, я получил: Hello from trigger. Count = 0 Hello from trigger. Count = 1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:25 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
По этой логике, что должен выдавать триггер BEFORE DELETE? Можешь проверить - ошибку. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:41 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Хм, вот это уже интересно. И update тоже не идет. Получается следующее: прочитать данные из таблицы можно только в триггере BEFORE INSERT при вставке (insert) записей. Все остальное приводит к мутации, это если говорить про row-level триггера. Значит, я не до конца еще понял документацию, но по-крайней мере конкретизировалась ситуация. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:53 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Блин! У меня документация другая. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:58 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
А вот и ответ: http://technet.oracle.com/doc/server.815/a68003/01_13dbt.htm#786 Обрати внимание на фразу: There is an exception to this restriction: For a single row INSERT, constraining tables are mutating for AFTER row triggers, but not for BEFORE row triggers. INSERT statements that involve more than one row, such as INSERT INTO Emp_tab SELECT..., are not considered single row inserts, even if they only result in one row being inserted. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 16:58 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Последнюю ссылку я взял отсюда: http://asktom.oracle.com/~tkyte/Mutate/index.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 17:09 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
А потом пойдут вопросы... а почему ошибка мутации вылетает снова при конструкции (триггер на таблицу а): insert into a (a, b, c) select a, b, c from d; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.01.2003, 19:23 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Ты это к чему? На самом деле, для меня странно, почему бы пользователю не дать возможность читать значения :old. Да и :new тоже. К каким проблемам, например, это может привести? А если и есть такие проблемы, то надо о них сказать и развязать пользователю руки (или как-то синтаксис инструкции подправить или опцию сделать). Что скажет умудренная опытом публика? Почему нельзя, скажем, с помощью триггера проверить некоторе условие по данным в таблице и разрешить/запретить текущую операцию? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2003, 10:06 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Ответ имхо будет сродни прозвучавшему в фидо по поводу одноименных таблиц и public synonym'а, о том, как достучаться к последнему. Если стоит задача анализа и разрешения/запрета изменений таблицы, то из того, что она не решается при помощи одного триггера, совсем не следует, что она не решается вообще. Просто не надо зацикливатся именно на таком решении, других вариантов масса. Если из доки на 9i выкинули описание ситуации, когда мутация не происходит, значит, есть на то причины. Может когда-нибудь мутация проявится и в этой исключительной ситуации, а пока, начиная с 8.1.7 это - недокументированная фича, как select for update skip locked. А про :old и :new мне непонятно- почему их нельзя читать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2003, 10:32 |
|
||
|
Mutating table
|
|||
|---|---|---|---|
|
#18+
Да "вообще"-то я ее решил, конечно. Просто мне показалось странным, что с помощью триггера этого нельзя сделать. Про :old \:new - это меня склинило. Сорри. Я имел в виду доступ ко всей таблице. А дока у меня 8.1.6. А какими проблемами чреват доступ на чтение к mutating таблице? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 24.01.2003, 10:54 |
|
||
|
|

start [/forum/topic.php?fid=52&gotonew=1&tid=1992061]: |
0ms |
get settings: |
9ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
141ms |
get topic data: |
10ms |
get first new msg: |
6ms |
get forum data: |
2ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
| others: | 216ms |
| total: | 455ms |

| 0 / 0 |
