В таблицу с триггером не вставлятся новые данные Oracle
Подскажите, пожалуйста, почему может получаться так, что из-за триггера данные в таблице не вставляются.
Например, у меня есть такой триггер:
create or replace trigger tr_example
after insert
on TAB1
for each row
begin
UDL.PR_CALC(:new.DOC_ID);
end;
Здесь я использую процедуру, которая вставляет данные в конечную таблицу TAB2. Данные в таблицу TAB1 вставляются посредством распарсивания файла xml через механизм на портале. Однако, если триггер включен, новые данные просто не попадают в таблицу. Думаю, также важно отметить, что данные попадают не только в таблицу TAB1. С помощью механизма, они разбегаются по множеству таблиц.
К сожалению, из-за отсутствия опыта я никак не могу разобраться, почему триггер не позволяет вставлять новые данные в таблицу TAB2.
Если в триггер прописываю сам инсерт, проблема остаётся:
create or replace trigger wdl.tr_example
after insert
on TAB1
REFERENCING NEW AS NEW
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into TAB2
(
doc_id,
sheet_code,
name,
code,
value,
line
)
select doc_id,
sheet_code,
name,
code,
value,
line
from TAB3
left join TAB4
on 1=1
where tab3.ref_name = 'A1';
commit;
end;
Если же делать INSERT не черех SELECT, всё работает отлично:
create or replace trigger wdl.tr_example
after insert
on TAB1
REFERENCING NEW AS NEW
for each row
declare
PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into TAB2
(
doc_id,
sheet_code,
name,
code,
value,
line
)
value (1, 2, 3, 4, 5, 6);
commit;
end;
Сам скрипт на вставку через SELECT я проверял. Все данные вставляются. Но именно с триггером не работает. Плюс добавил PRAGMA AUTONOMOUS_TRANSACTION, чтобы не ругался на мутирующую таблицу.
Ответы (1 шт):
В приведённом коде особых проблем нет, но одно подозрение есть:
использую процедуру, которая вставляет данные в конечную таблицу TAB2
Но в процедуру передатся только идентификатор, то есть данные надо откуда-то взять. Данные берутся из таблицы, в которую они вроде бы только что были вставлены, логично же.
Посмотрите в этом воспроизводимом примере, что тогда произойдёт:
create table tab1 (id int, doc clob)
/
create table tab2 (id int, doc clob)
/
create or replace procedure proc (id int) is
begin
insert into tab2 values (id, (select doc from tab1 where id = proc.id));
dbms_output.put_line (sql%rowcount||' row into tab2 inserted.');
end;
/
create or replace trigger tr_example
after insert on TAB1 for each row
begin
proc (:new.id);
end;
/
insert into tab1 values (1, 'document');
ORA-04091: table SH.TAB1 is mutating, trigger/function may not see it
В построчном триггере нельзя обратится запросом к таблице, на которой он определён.
Если подозрение окажется неверно, то на основе примера выше составте свой минимальный пример с данными для локализации ошибки без догадок и шаманства.