#sql #oracle #plsql #triggers #mutating-table
#sql #Oracle #plsql #триггеры #изменение-таблица
Вопрос:
Я хочу, чтобы триггер запускался после каждой вставляемой записи.
Эта проверка работает нормально, если у меня есть простая вставка, подобная этой:
insert into g_dossier values
(112334, 'BBT', 'LPO','TTS','Y') ;
Однако, когда это похоже на массовую вставку, подобную этой:
INSERT INTO g_piece(
refpiece,
typpiece,
class_piece
group_piece
flag_piere)
SELECT :new.element_num,
PROC_TYPE,
DECODE( piece_it, 'F', 'FTTR', 'N', 'FTTR', NULL ),
DECODE( piece_it, 'T', 'TTSN', 'N', 'TTSN', NULL ),
'N'
FROM t_elements
WHERE :new.db_piece_flag = 'Y';
Триггер мутирует. Я хочу, чтобы проверка также работала, когда выполнялась как массовая вставка.
Запрос, вызывающий эту проблему
SELECT COUNT(*)
INTO existing_cmcl_cnt
FROM g_piece cmcl
WHERE cmcl.class_piece= :new.class_piece
Проблема в том, что этот запрос вызывается в триггере, применяемом к той же таблице «g_piece». Когда я выполняю простую вставку (вставляю в значения g_piece (…)), у меня нет этой проблемы.
Как я могу избежать этой проблемы? Спасибо.
Ответ №1:
Здесь вы должны изменить запрос и вставить результат a SELECT ... FROM some join
, вообще не используя триггер. Вы хотите, чтобы при вставке в таблицу X
триггер также вставлялся в ту же таблицу, что невозможно (это повторилось бы).
Если вы не можете изменить запрос, вам следует переименовать свою таблицу, создать представление таблицы со старым именем и создать a TRIGGER INSTEAD OF INSERT ON that view FOR EACH ROW
, которое будет INSERT INTO into the real table
результатом a SELECT ... FROM some join
.
Ответ №2:
Если вы используете Oracle 11G, вы можете взглянуть на составные триггеры, чтобы избежать ошибки mutating-table. Взгляните: http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/triggers.htm#CIHEFGFD