ошибка pl sql при работе с триггером

Я получаю сообщение об ошибке при работе со следующим триггером:

create or replace trigger t1
  after insert or update  
     on student_tbl 
  declare
   pragma autonomous_transaction;
    begin
   if inserting then

 insert into stud_fees_details(stud_id,fees_balance,total_fees) 
       select stud_id,course_fees,course_fees from student_tbl s,courses_tbl c where s.stud_standard_id=c.course_id;

 elsif updating('stud_standard_id') then

insert into stud_fees_details(stud_id,fees_balance,total_fees) 
select stud_id,course_fees,course_fees from student_tbl s,courses_tbl c where s.stud_standard_id=c.course_id;

 end if;
end;

введите здесь описание изображения

ошибка

ORA-06519: обнаружена активная автономная транзакция и выполнен откат ORA-06512: в "SYSTEM.T1", строка 15 ORA-04088: ошибка во время выполнения триггера "SYSTEM.T1"


person Rishabh Mishra    schedule 17.01.2016    source источник
comment
Удалены теги Sql server и Mysql, поскольку в сообщении об ошибке четко указано, что это ORACLE.   -  person Pரதீப்    schedule 17.01.2016
comment
Пробовали ли вы искать в поисковой системе сообщение об ошибке, обнаружена активная автономная транзакция и откатываться? Мой первый хит, кажется, объясняет это очень подробно.   -  person DIDoS    schedule 17.01.2016
comment
Существует руководство Oracle по сообщениям об ошибках базы данных, в котором объясняется, почему возникает эта ошибка. и как этого избежать.   -  person miracle173    schedule 17.01.2016
comment
Во-первых, использование автономной транзакции в триггере кажется плохой идеей. Какую настоящую проблему вы пытаетесь решить с помощью этого?   -  person a_horse_with_no_name    schedule 17.01.2016
comment
Похоже, это так называемая XY-проблема: вы ввели автономные транзакции, потому что была другая проблема. Теперь вы спрашиваете об ошибке автономной транзакции вместо исходной проблемы. Кроме того, создавать объекты в схеме SYSTEM — плохая идея. Для этой цели вы должны создать пользователя/схему.   -  person miracle173    schedule 18.01.2016
comment
Почему вы используете здесь автономные транзакции?   -  person miracle173    schedule 18.01.2016


Ответы (2)


Сообщения об ошибках базы данных

ORA-06519: обнаружена и отменена активная автономная транзакция
Причина: перед возвратом из автономного блока PL/SQL все автономные транзакции, запущенные в блоке, должны быть завершены (либо зафиксированы, либо откатывались). Если нет, активная автономная транзакция неявно откатывается и возникает эта ошибка.
Действие: убедитесь, что перед возвратом из автономного блока PL/SQL все активные автономные транзакции явно фиксируются или откатываются. назад.

Пример из Справочник по языку базы данных PL/SQL

-- Autonomous trigger on emp table:

CREATE OR REPLACE TRIGGER log_sal
  BEFORE UPDATE OF salary ON emp FOR EACH ROW
DECLARE
  PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
  INSERT INTO log (
    log_id,
    up_date,
    new_sal,
    old_sal
  )
  VALUES (
    :old.employee_id,
    SYSDATE,
    :new.salary,
    :old.salary
  );
  COMMIT;
END;
/

Но @a_horse_with_no_name уже заявил, что автономная транзакция, возможно, здесь неуместна.

После удаления прагмы автономной транзакции вы, возможно, столкнетесь с проблемой, которую @GordonLinoff решает в своем сообщении.

person miracle173    schedule 17.01.2016

Если триггер не использует :new или :old, то это подозрительно. Ваш триггер использует ту же таблицу, которая изменяется в запросах.

Вероятно, вы намереваетесь:

create or replace trigger t1 after insert or update on student_tbl 
declare
   pragma autonomous_transaction;
begin
    if inserting then
        insert into stud_fees_details(stud_id, fees_balance, total_fees) 
            select stud_id, course_fees, course_fees
            from courses_tbl c
            where c.course_id = :new.stud_standard_id;

    elsif updating('stud_standard_id') then
        insert into stud_fees_details(stud_id, fees_balance, total_fees) 
            select stud_id, course_fees, course_fees
            from courses_tbl c
            where c.course_id = :new.stud_standard_id;
    end if;
    commit;
end;

Примечания:

  • Операторы select должны иметь псевдонимы таблиц, чтобы различать столбцы, происходящие из :new и из courses_tbl.
  • Два пункта к if кажутся мне одинаковыми, поэтому я не понимаю логики.
  • Условия join между чем-то под названием course_id и чем-то под названием stud_standard_id выглядят подозрительно. Я бы посоветовал вам называть внешние ключи после первичного ключа, на который они ссылаются.
person Gordon Linoff    schedule 17.01.2016
comment
ничто в этом ответе не решит проблему. Ваш триггер также вызовет ту же ошибку. - person miracle173; 17.01.2016
comment
@чудо173 . . . Этот код должен предотвратить ошибку изменяемой таблицы, которая является вероятной причиной сбоя. Этот код больше не ссылается на изменяемую таблицу. Почему вы думаете, что это не решит проблему? - person Gordon Linoff; 17.01.2016
comment
потому что проблема заключается в автономной транзакции, которая не фиксируется и не откатывается - person miracle173; 17.01.2016
comment
@ miracle173 - Могу поспорить, что прагма была помещена туда только для того, чтобы попытаться избежать ошибки мутирующей таблицы, которая происходила только из-за ненужного запроса к таблице. Я не верю, что этой версии больше не нужна эта прагма или, следовательно, фиксация; но это должен быть триггер for each row для ссылки на :new. (Ему также не нужна ветвь, поскольку оба делают одно и то же, но это совсем другая проблема). - person Alex Poole; 17.01.2016
comment
@AlexPoole В своем ответе я предположил, что автономная транзакция тоже не нужна. Тем не менее, причиной этого сообщения об ошибке является неправильная автономная транзакция. - person miracle173; 17.01.2016
comment
В качестве примечания для тех, кто читает это, добавлено commit. - person Gordon Linoff; 18.01.2016