мутирует, триггер/функция может его не видеть - ошибка при выполнении триггера

CREATE OR REPLACE TRIGGER UPDATE_TEST_280510
AFTER insert on TEST_TRNCOMPVISIT
declare
V_TRNCOMPNO NUMBER(10);

CURSOR C1 IS SELECT B.COMPNO FROM TEST_TRNCOMPVISIT A, TEST_TRNCOMPMST B, 
                                  TEST_MEMMAST C
WHERE A.COMPNO=B.COMPNO 
AND B.TRNMEMID=C.MEMID 
AND C.MEMOS>=1000;

begin
open c1;
fetch c1 into V_TRNCOMPNO;


UPDATE TEST_TRNCOMPMST SET COMPSTATUS='P',
       remark='comp is pending due to O/S>1000'
WHERE COMPNO=V_TRNCOMPNO AND COMPSTATUS='C';
CLOSE C1;

end;

Я сделал этот триггер и при вставке строки в таблицу TEST_TRNCOMPVISIT выдает следующую ошибку:

Произошла следующая ошибка:

ORA-04091: таблица TEST.TEST_TRNCOMPVISIT видоизменяется, триггер/функция может ее не видеть
ORA-06512: в "TEST.UPDATE_TEST_280510", строка 4
ORA-06512: в "TEST.UPDATE_TEST_280510", строка 10
ORA-04088: ошибка при выполнении триггера 'TEST.UPDATE_TEST_280510'


person mahesh soni    schedule 08.06.2010    source источник
comment
Эта ошибка возникает, когда вы пытаетесь получить доступ к таблице, на которой основан триггер, в триггере FOR EACH ROW. Вы уверены, что не указали FOR EACH ROW в своем определении триггера?   -  person Tony Andrews    schedule 08.06.2010
comment
Уважаемый г-н Тони! После удаления FOR EACH ROW ошибка не возникает, но записи не обновляются, как указано в теле триггера. Пожалуйста, поддержите. МахешА....   -  person mahesh soni    schedule 08.06.2010
comment
Что должен делать триггер? Казалось бы, некоторые строки обновляются, если курсор c1 возвращает строку.   -  person Tony Andrews    schedule 08.06.2010
comment
этот триггер обновит столбец COMPSTATUS & REMARK таблицы TEST_TRNCOMPMST, если курсор c1 возвращает строку. Но он не обновляется даже после того, как c1 возвращает строку. Пожалуйста, предложите. МахешА...   -  person mahesh soni    schedule 08.06.2010
comment
Также обратите внимание, что ваш триггер выполняет только одну выборку, поэтому, если курсор возвращает более одной записи, обновляется только первая.   -  person AndyDan    schedule 08.06.2010


Ответы (2)


Это единственный триггер, который у вас есть? Ваш триггер обновляет таблицу TEST_TRNCOMPMST. Если в этой таблице есть триггер, который обращается к TEST_TRNCOMPVISIT, вы получите сообщение об ошибке.

person Rene    schedule 09.06.2010
comment
ДА, сэр, это единственный триггер, который у меня есть. В таблице TEST_TRNCOMPMST нет другого триггера. Что мне делать, чтобы обновлять таблицу TEST_TRNCOMPMST всякий раз, когда запись, вставляемая в таблицу TEST_TRNCOMPVISIT, имеет compno, который есть в таблице TEST_TRNCOMPMST. Пожалуйста, помогите мне, так как я новее в ORACLE, у меня нет опыта работы в этой области, всего 2 месяца до окончания учебы. МахешА... - person mahesh soni; 10.06.2010

Исключение «таблица изменяется» возникает, когда триггер, определенный как FOR EACH ROW, пытается получить доступ к таблице, для которой он был запущен. Том Кайт написал отличное руководство по причинам и устранению этого исключения здесь .

В вашем опубликованном примере у вас нет FOR EACH ROW, поэтому я бы не ожидал, что исключение будет возбуждено. Обычно триггеры FOR EACH ROW нужно использовать только в тех случаях, когда необходимо получить доступ к значениям :OLD или :NEW каждой строки, чего нет у вас.

person Tony Andrews    schedule 08.06.2010
comment
Извини . Я забыл ввести его в данном примере. после удаления его из определения триггера ошибка не возникает, но запись также не обновляется, как указано в теле триггера. Пожалуйста, предложите. МахешА... - person mahesh soni; 08.06.2010
comment
Мое первое предложение состояло бы в том, чтобы вы поместили некоторые отладочные сообщения в триггер, например. используя DBMS_OUTPUT.PUT_LINE для проверки (а) того, что он вообще выполняется, и (б) находит ли курсор какие-либо строки. - person Tony Andrews; 08.06.2010