#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 строки, когда вы запускаете его автономно?