Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
hi all.
Есть таблица myTable с триггером AFTER INSERT.
Есть таблица с точно такими же полями и именем myTable_Vers.
В триггере есть такой код:

CREATE OR REPLACE TRIGGER MYSCHEMA.TG_MYTABLE_AI
AFTER INSERT ON MYSCHEMA.MYTABLE
...
BEGIN
   IF INSERTING THEN
     INSERT INTO myTable_Vers SELECT * FROM myTable WHERE ID=:NEW.ID;
   END IF;
   ...
END;
/
При попытке вставки строки в myTable происходит ошибка
ORA-04091: table MYSCHEMA.MYTABLE is mutating, trigger may not see it.
В тоже время, замена строки вставки на такую, в которой все необходимые поля присутствуют ЯВНО:
INSERT INTO myTable_Vers (ID, fld1, fld2, fld3) 
                          VALUES (:new.ID, :new.fld1, :new.fld2, :new.fld1);
- отрабатывает нормально.

Объясните начинающему, плз, почему надо обязательно ЯВНО ПЕРЕЧИСЛЯТЬ все поля таблицы при копировании строки в другую таблицу ?
Я понимаю смысл этой ошибки: в теле триггера нельзя модифицировать таблицу, с которой происходит обработка. Но почему её нельзя ЗАПРАШИВАТЬ ?

Заранее спасибо за ответы.
1 июн 06, 22:49    [2732454]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18343
GrayCity
Я понимаю смысл этой ошибки: в теле триггера нельзя модифицировать таблицу, с которой происходит обработка. Но почему её нельзя ЗАПРАШИВАТЬ ?

Не, не понимаете :)
Переводите дословно: триггер не может видеть модифицируемую таблицу.
Перечислять поля придется - иного интерфейса oracle не предоставил.
1 июн 06, 22:54    [2732465]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
Хм... жаль.
1 июн 06, 23:01    [2732483]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. W  [new]
Вадиман
Member

Откуда: Владивосток
Сообщений: 1072
andrey_anonymous
GrayCity
Я понимаю смысл этой ошибки: в теле триггера нельзя модифицировать таблицу, с которой происходит обработка. Но почему её нельзя ЗАПРАШИВАТЬ ?

Не, не понимаете :)
Переводите дословно: триггер не может видеть модифицируемую таблицу.
Перечислять поля придется - иного интерфейса oracle не предоставил.


Почему не предоставил, ведь синтаксис INSERT INTO table1 SELECT * FROM table2 документирован. На самом деле, интересно, почему такая разница возникает
2 июн 06, 02:24    [2732701]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
organiz
Guest
На самом деле этот код осуществить можно, но только если изменить время срабатывания триггера с AFTER INSERT на BEFORE INSERT. Насколько это вам поджодит - уже вам решать.
4 июн 06, 13:06    [2738900]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
organiz
Guest
organiz
На самом деле этот код осуществить можно, но только если изменить время срабатывания триггера с AFTER INSERT на BEFORE INSERT. Насколько это вам поджодит - уже вам решать.


Сорри - ступил. ЭТОТ кусок кода не будет иметь смысла - ничего не выберет по ходу. Но селекты из этой же таблицы делать можно в BEFORE INSERT. :)
4 июн 06, 13:09    [2738905]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
organiz
Но селекты из этой же таблицы делать можно в BEFORE INSERT. :)
- и что толку от них, если ими (результатами селектов) НЕЛЬЗЯ по-человечески пользоваться ? Вставку-то приходится делать по-корявому, т.е. ЯВНО перечисляя все поля записи. Поменяю я структуру таблицы, добавив несколько доп. полей, и придётся опять лезть в тело триггера и дописывать там эти поля.
"Так грустно, что хочется танцевать" (С) Фраза из какого-то индийского фильма.
4 июн 06, 13:37    [2738939]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
DВА
Member

Откуда:
Сообщений: 5439
GrayCity
organiz
Но селекты из этой же таблицы делать можно в BEFORE INSERT. :)
- и что толку от них, если ими (результатами селектов) НЕЛЬЗЯ по-человечески пользоваться ? Вставку-то приходится делать по-корявому, т.е. ЯВНО перечисляя все поля записи. Поменяю я структуру таблицы, добавив несколько доп. полей, и придётся опять лезть в тело триггера и дописывать там эти поля.
"Так грустно, что хочется танцевать" (С) Фраза из какого-то индийского фильма.

интересная претензия к тригеру.
мало того, что позволь вставлять неизвестно что, так еще и отслеживай структуру )
так программеры и без работы остаться могут
4 июн 06, 14:06    [2738995]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116133
Между прочим...
А может ну его, этот триггер ?

INSERT ALL into_clause + Multitable Inserts: Examples

Добавляйте сразу в две таблицы ...
4 июн 06, 14:57    [2739056]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
dmidek
Добавляйте сразу в две таблицы ...
именно это я сейчас и делаю, только с юзанием триггера AFTER INSERT OR UPDATE, который висит на "первой" таблице.
ЗЫ. От триггеров (в моём случае) отказываться никак нельзя!
4 июн 06, 15:12    [2739062]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116133
GrayCity
ЗЫ. От триггеров (в моём случае) отказываться никак нельзя!

Why ?
4 июн 06, 15:14    [2739063]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
Тогда надо будет все эти вставочки делать в хранилках.
Допустим, я _БУДУ_ помнить о необходимости написания таких вставок. А мой коллега, к примеру, может забыть. Или наоборот, я забуду. И что тогда ?
Не, триггеры - вещь удобная. НаписАл и забыл. Лень (и склероз :)), как известно, двигатель всего прогресса.
Перефразируя известную поговорку про небо и звёзды: "если в СУБД зажигаются (fired :)) триггеры, значит, это кому-то нужно".
4 июн 06, 15:28    [2739068]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
andrey_anonymous
Member

Откуда: Москва
Сообщений: 18343
GrayCity
Тогда надо будет все эти вставочки делать в хранилках.
Допустим, я _БУДУ_ помнить о необходимости написания таких вставок. А мой коллега, к примеру, может забыть. Или наоборот, я забуду. И что тогда ?
Не, триггеры - вещь удобная. НаписАл и забыл. Лень (и склероз :)), как известно, двигатель всего прогресса.

1) Если офрмите в пакетный метод - то не забудете.
2) Забыть про триггера никак не получится. За ними следить надо. Станет инвалидом - и не заметите. Или оформите пакетную загрузку с alter ... disable all triggers и забудете включить обратно... Пока обнаружите проблему - много времени может пройти.
Процедурка же сломается целиком и целиком же починится. Data inconsistency не будет.
Вот и думайте.
4 июн 06, 16:07    [2739100]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116133
Согласен с andrey_anonymous.
И еще.
Вы добавляете одинаковую запись в две таблицы.
Для чего еще нужеu INSERT ALL, если его не использовать здесь ?
Особенно в свете наличия отсутствия :) :new.row.
4 июн 06, 16:24    [2739118]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
andrey_anonymous
1) Если офрмите в пакетный метод - то не забудете.
- поясните поподробнее, если не трудно (я еще очень мало работаю с Ораклом)
andrey_anonymous
За ними следить надо. Станет инвалидом - и не заметите. Или оформите пакетную загрузку с alter ... disable all triggers и забудете включить обратно... Пока обнаружите проблему - много времени может пройти.
- ну дык на старте приложения надо обращаться к Словарю и искать там инвалидные триггера. Если нашёлся хоть один - пошли все в баню, пусть зовут админа/девелопера, чтобы починили. Или еще лучше: попробовать по-тихому скомпилирвать эти инвалидные триггера и, если вылезет ошибка хотя бы в одном из них - тогда "стоп, зовите санитара".

Имхо, это весьма удобно: заставить приложение САМОСТОЯТЕЛЬНО проверять готовность своих метаданных.
Единственное требование при этом: ВСЕ приложения, обращающиеся к БД, должны на старте _обязательно_ вызывать одну и ту же ХП, проверяющую эту самую "готовность метаданных". Согласен, здесь может возникнуть небольшая засада. Но для этого надо, чтобы таких приложений БЫЛО В НАТУРЕ несколько. А у меня пока и одного нет
4 июн 06, 16:28    [2739122]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
dmidek
Вы добавляете одинаковую запись в две таблицы.
Для чего еще нужеu INSERT ALL, если его не использовать здесь ?
Особенно в свете наличия отсутствия :) :new.row.
Выглядит этот INSERT ALL, конечно, изящно. Но тогда про триггера надо забывать. А у меня от этой мысли суеверный холод бежит по спине.
Не поборол я еще свои религиозные предрассудки! :)
4 июн 06, 16:32    [2739125]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
dmidek
Member

Откуда: Киев - Дортмунд
Сообщений: 116133
GrayCity
dmidek
Вы добавляете одинаковую запись в две таблицы.
Для чего еще нужеu INSERT ALL, если его не использовать здесь ?
Особенно в свете наличия отсутствия :) :new.row.
Выглядит этот INSERT ALL, конечно, изящно. Но тогда про триггера надо забывать. А у меня от этой мысли суеверный холод бежит по спине.
Не поборол я еще свои религиозные предрассудки! :)

Ну в общем я так и думал. INSERT ALL оказался внове...

Ни в коем случае нельзя забывать про триггеры. Разумеется INSERT ALL не заменяет триггеры. Он является разумной альтернативой в конкретном, а именно ИМХО в Вашем случае. Вы добавляете одинаковую строку в две таблицы. Это не предмет забот триггера, это дело множественного селекта.

Решайтесь ! Опять же и проблемы с дебаггером :old и :new в TOAD пропадают
4 июн 06, 16:46    [2739136]     Ответить | Цитировать Сообщить модератору
 Re: Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?  [new]
GrayCity
Member

Откуда: Подмосковье
Сообщений: 94
Хм... Во мне теперь сидит червь сомнений. Особенно тревожно то, что триггеров уже понаделано приличное количество (для большого числа таблиц, работающих "в паре"). И они (триггера) выполняют НЕ только вставку в одинаковые таблицы, но и еще ряд полезнейших действий. Например, всякие предварительные проверки и преобразования входных данных.

dmidek
Ни в коем случае нельзя забывать про триггеры. INSERT ALL ... является разумной альтернативой в конкретном, а именно ИМХО в Вашем случае.
- а как мне тут скрестить ежа и ужа ? Если повесить триггер, то INSERT в его тело не вставишь. Значит, запихнуть этот INSERT ALL в какую-то ХП, так ? Стрёмно всё это... Это ружьё (в смысле, что кто-то забудет вызывать эту ХП в какой-нибудь ситуации) обязательно когда-нибудь пальнёт.

Ладно, буду думать. Спасибо за просвещение! :)

ЗЫ. "Мало знаешь - крепче спишь" (С)
4 июн 06, 17:08    [2739159]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить