Предполагая, что для обычного стола, а не для таблицы объектов, у вас нет большого количества опций. Ваш триггер должен быть чем-то вроде формы
CREATE OR REPLACE TRIGGER trigger_name
AFTER UPDATE ON table_name
FOR EACH ROW
BEGIN
IF(UPDATING('COLUMN1'))
THEN
INSERT INTO log_table(column_name, column_value)
VALUES('COLUMN1', :new.column1);
END IF;
IF(UPDATING('COLUMN2'))
THEN
INSERT INTO log_table(column_name, column_value)
VALUES('COLUMN2', :new.column2);
END IF;
<<repeat for all columns>>
END;
Вы могли бы принести COLUMN1
, COLUMN2
... COLUMN<<n>>
строки из словаря данных (USER_TAB_COLS
), а не жесткого кодирования их, но вы все равно придется hard-code ссылки на столбцы в псевдозаписке :new
.
Вы могли бы потенциально написать кусок кода, который генерируется на курок выше, запрашивая словаря данных (USER_TAB_COLS
или ALL_TAB_COLS
скорее всего), строит строку с утверждением DDL, а затем делать в EXECUTE IMMEDIATE
выполнить оператор DDL. Затем вам нужно будет вызвать этот скрипт каждый раз, когда новый столбец будет добавлен в любую таблицу для повторного создания триггера для этого столбца. Это утомительно, но не особенно технически сложно писать и отлаживать такой код генерации DDL. Но это редко стоит того, потому что кто-то неизбежно добавляет новый столбец и забывает перезапустить сценарий, или кому-то нужно изменить триггер, чтобы выполнить некоторую дополнительную работу, и проще просто вручную обновить триггер, чем модифицировать и протестировать сценарий, который генерирует триггеры.
В целом, однако, я бы поставил под вопрос мудрость хранения данных таким образом. Сохранение одной строки в таблице истории для каждого столбца каждой модифицированной строки делает использование данных истории очень сложным. Если кто-то хочет знать, в каком состоянии находится определенная строка в определенный момент времени, вам придется присоединиться к таблице истории к себе N раз, где N - количество столбцов в таблице в этот момент времени. Это будет ужасно неэффективно, что очень быстро заставит людей избегать попыток использовать данные истории, потому что они не могут делать полезные вещи с ним в течение разумного периода времени, не разрывая их волосы.Как правило, гораздо эффективнее иметь таблицу истории с тем же набором столбцов, что и в живой таблице (с несколькими добавленными для дат отслеживания и т. П.) И вставлять одну строку в таблицу истории каждый раз, когда строка обновляется. Это будет потреблять больше места, но, как правило, гораздо проще в использовании.
И Oracle имеет ряд способов аудита изменений данных - вы можете использовать DML, вы можете использовать мелкозернистый аудит (FGA), вы можете использовать Workspace Manager, или вы можете использовать Oracle Total Recall. Если вы ищете большую гибкость, чем создание собственного кода запуска, я бы настоятельно предложил исследовать эти другие технологии, которые по своей сути гораздо более автоматизированы, чем пытаться разработать собственную архитектуру.
Право. Хочешь знать, сколько я плачу в час? SO не является бесплатной услугой кодирования. что ты уже испробовал? –
@Adrian - просто ищу здесь небольшое направление ... мой вопрос никогда не заявляет, что я ищу кого-нибудь, чтобы написать код для меня ... –
Достаточно честный. Проблема в том, что ваш вопрос звучит точно так же, как в документе Spec, который я читаю сейчас. Вы должны нам что-то дать. У вас хоть какой-то подход? Вы исследовали, возможно ли это? Вы исследовали, что RDBMS (oracle) уже предоставляет это? –