Все, что вы делаете в триггере, будет следовать судьбе всей транзакции.
Если вы вставите данные, а затем создадите исключение, вся операция будет отменена.
Вам необходимо выполнить вставку в ДРУГОЙ СДЕЛКЕ. oracle позволяет определять функции и процедуры, которые выполняются в отдельной транзакции от транзакции вызывающей программы. Вы даже можете определить эти процедуры как локальные процедуры.
Это то, что вам нужно:
Create or replace trigger trg_audit
AFTER UPDATE ON lds_placement
for each row
declare
procedure WriteAuditLog is
pragma autonomous_transaction;
begin
insert into pradip_audit_table(
audit_date, table_name, operation_type, primary_key_column, primary_key_value,
column_affected, max_salary, actual_salary, host, ip_adddress, terminal
)
values
(
sysdate,
'lds_placement',
'update',
'plt_id',
:OLD.placement_id,
'actual_salary',
:new.max_salary,
:NEW.actual_salary,
sys_context('USERENV', 'HOST'),
sys_context('USERENV', 'IP_ADDRESS', 15),
sys_context('USERENV', 'TERMINAL')
);
-- you can't leave a autonomous_transaction function without committing or rolling back:
-- if you leave the transaction open you get an error!
commit;
exception when others then
rollback;
raise;
end WriteAuditLog;
BEGIN
if :NEW.actual_salary>:new.max_salary then
WriteAuditLog;
raise_application_error(-20111, 'Salary cannot be more than maximum salary');
end if;
end;
Обратите внимание, что я изменил триггер для запуска ПОСЛЕ оператора, а не ДО.
- Перед триггерами на вашем столе может быть НЕСКОЛЬКО
- Каждый ПЕРЕД триггером имеет возможность изменять фактические данные, которые будут записаны
- У вас нет гарантии, что ваш триггер будет последним из выполненных.
Вполне возможно, что есть другой триггер, который ограничил бы зарплату до максимального предела и вставил бы запись, которая не нарушает правило: ваш триггер, если он запускается до этого, сделает этот второй триггер бесполезным .
Еще одна вещь, которая может произойти, это то, что другой триггер запускается после того, как данные «до» прошли вашу проверку, и этот второй триггер может изменить данные, например, удвоив зарплату и записав данные, которые нарушают вашу проверку, независимо от того, о том, что должен делать ваш триггер.
Триггеры ПОСЛЕ не могут изменить данные, поскольку они уже записаны, поэтому правильное место для такого рода проверок и регистрации - триггер ПОСЛЕ.
Обратите внимание, что при возникновении исключения команда обновления будет отменена, даже если вы находитесь в триггере AFTER: не позволяйте слову "AFTER" вводить вас в заблуждение.