Мутирующая таблица (ORA-04091) при вып. select'a в триггере и вставке в ДРУГУЮ табл. Why ?

GrayCity
Дата: 01.06.2006 22:49:02
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);
- отрабатывает нормально.

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

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

Не, не понимаете :)
Переводите дословно: триггер не может видеть модифицируемую таблицу.
Перечислять поля придется - иного интерфейса oracle не предоставил.
GrayCity
Дата: 01.06.2006 23:01:25
Хм... жаль.
Вадиман
Дата: 02.06.2006 02:24:50
andrey_anonymous
GrayCity
Я понимаю смысл этой ошибки: в теле триггера нельзя модифицировать таблицу, с которой происходит обработка. Но почему её нельзя ЗАПРАШИВАТЬ ?

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


Почему не предоставил, ведь синтаксис INSERT INTO table1 SELECT * FROM table2 документирован. На самом деле, интересно, почему такая разница возникает
organiz
Дата: 04.06.2006 13:06:41
На самом деле этот код осуществить можно, но только если изменить время срабатывания триггера с AFTER INSERT на BEFORE INSERT. Насколько это вам поджодит - уже вам решать.
organiz
Дата: 04.06.2006 13:09:00
organiz
На самом деле этот код осуществить можно, но только если изменить время срабатывания триггера с AFTER INSERT на BEFORE INSERT. Насколько это вам поджодит - уже вам решать.


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

интересная претензия к тригеру.
мало того, что позволь вставлять неизвестно что, так еще и отслеживай структуру )
так программеры и без работы остаться могут
dmidek
Дата: 04.06.2006 14:57:54
Между прочим...
А может ну его, этот триггер ?

INSERT ALL into_clause + Multitable Inserts: Examples

Добавляйте сразу в две таблицы ...
GrayCity
Дата: 04.06.2006 15:12:45
dmidek
Добавляйте сразу в две таблицы ...
именно это я сейчас и делаю, только с юзанием триггера AFTER INSERT OR UPDATE, который висит на "первой" таблице.
ЗЫ. От триггеров (в моём случае) отказываться никак нельзя!