"клиент определил структуру таблицы, которую он хотел бы для журнала аудита"
Ужасные слова.
Вот как бы вы реализовали такую вещь:
create or replace trigger emp_bur before insert on emp for each row
begin
if :new.ename = :old.ename then
insert_audit_record('EMP', 'ENAME', :old.ename, :new.ename);
end if;
if :new.sal = :old.sal then
insert_audit_record('EMP', 'SAL', :old.sal, :new.sal);
end if;
if :new.deptno = :old.deptno then
insert_audit_record('EMP', 'DEPTNO', :old.deptno, :new.deptno);
end if;
end;
/
Как видите, это требует много повторений, но это достаточно просто для обработки, с генератором кода, встроенным в словарь данных. Но есть и более серьезные проблемы с этим подходом.
- Имеет значительные накладные расходы:
одно обновление, которое касается десяти
поле сгенерирует десять вставок
заявления.
- BeforeValue и AfterValue
столбцы становятся проблематичными, когда мы
должны обрабатывать разные типы данных -
даже даты и метки времени становятся
интересные, не говоря уже о CLOBs.
- Трудно восстановить государство
записи в определенный момент времени. Мы
надо начинать с самого раннего
версия записи и применить
последующие изменения постепенно.
- Не сразу очевидно, как
этот подход будет обрабатывать вставку
и УДАЛИТЬ операторы.
Теперь ни одно из этих возражений не является проблемой, если основное требование клиента состоит в том, чтобы отслеживать изменения в нескольких чувствительных столбцах: EMPLOYEES.SALARY, CREDIT_CARDS.LIMIT и т. Д. Но если требуется отслеживать изменения в каждой таблице, лучше использовать подход «целая запись»: просто вставьте одну запись аудита для каждой строки, затронутой DML.