oracle : Триггер не вставляет записи в таблицу

#oracle #plsql #triggers

Вопрос:

У меня есть триггер, но он не вставляет записи в целевую таблицу. создайте или замените триггер ins_det_trig1 после вставки в Table_a, объявите pragma autonomous_transaction; — начните вставку в inf_det, выберите a.loc_id, a.genre_id, to_char(a.emp_date,’гггг-мм-дд’), a.san_seq из Table_b a, Table_a b, где b.emp_date=a.emp_date и b.genre_id=a.genre_id и b.san_seq=a.san_seq;

 commit;
exception
when others
Rollback;
end;

      pls help me on this
 

Комментарии:

1. Возможно, для начала удалите обработчик исключений. Тогда вы можете увидеть, что ваш триггер не вставляет записи, потому что он вызывает исключение.

2. Ты , наверное, понимаешь table is mutating trigger/function may not see it , не так ли?

3. да, я получаю то же самое

4. Несвязанный комментарий к ответам ниже: вы уверены, что вам это нужно pragma autonomous_transaction; ? Это может привести к неожиданным результатам. Если в этой таблице происходит вставка, а затем она откатывается (например, из-за ошибки на более позднем этапе транзакции), триггер выполнит вставку, и данные в inf_det будут неверными.

Ответ №1:

Во-первых, триггер недействителен, поэтому он ничего не сделает. Вы используете переменную с именем v_err , которую не объявляете.

Тогда вы проглатываете все исключения. Если что-то пойдет не так, вы заполняете эту переменную кодом ошибки, а затем молча завершаете триггер. Таким образом, вы никогда не получите информацию о сбое триггера.

Но главная проблема в том, что вы используете триггер не так, как следовало бы использовать триггеры в Oracle. Триггер является триггером после строки ( AFTER INSERT ... FOR EACH ROW ) и, следовательно, срабатывает один раз за строку при вставках строк table_a. К значениям , вставленным в новую строку, можно получить доступ :new , например :new.business_date , с помощью .

Однако вы игнорируете эти значения и вместо этого выбираете из таблицы. Но в момент вашего выбора таблица мутирует. Допустим, мы пишем инструкцию insert, которая вставляет две строки. Спусковой крючок срабатывает два раза. Остается только выбрать, какая строка будет вставлена первой. Oracle видит это, и когда вы находитесь внутри триггера и пытаетесь выбрать, это говорит нам, что содержимое таблицы не является детерминированным, так как другая строка может уже быть в таблице или нет. Мы получаем исключение мутирующей таблицы.

Сказав это: Похоже, вам нужен триггер после утверждения. Триггер, который срабатывает после завершения вставки строк. Чтобы это произошло, удалите FOR EACH ROW пункт и связанный REFERENCING с ним пункт тоже.

 create or replace trigger ins_det_trig1
after insert on Table_a
declare
  ...
begin
  ...
end;
 

Комментарии:

1. Как уже упоминалось: Похоже, вам вообще не нужен триггер строки. Если вместо этого вы используете триггер after satement, строки нет, следовательно, нет :new.

2. Как я уже сказал: просто удалите эти два пункта из своего кода. (И лучше также удалить блок исключений.) Ваше заявление о вставке остается там, где оно есть, сразу после BEGIN этого .

3. Итак, вы удалили два предложения, удалили блок исключений, скомпилировали триггер, вставили что-то в table_a, но не получили исключения? Просто ничего не вставлено в таблицу inf_det? Возвращает ли оператор select строки, когда вы запускаете его автономно?