800 столбцов немного сумасшедшие, но я не знаю ... я полагаю, такая таблица может существовать.
Вы можете начать с триггера. В триггере вы можете сравнить ": new.col_name" против ": old.col_name", но написание 800 из них громоздко. "IF UPDATING (" COL_NAME ")" можно использовать; ОДНАКО, это вернет true, даже если значение не меняется. Функция UPDATING является тестом, чтобы увидеть, был ли столбец частью оператора обновления (он может содержать или не содержать значение, отличное от старого значения).
Итак, чтобы проверить, действительно ли изменились, вы должны использовать объекты: new и: old и сделать сравнение. Oracle не предоставляет гладкого рефлексивного способа сравнения их как коллекции, поэтому необходимо использовать хорошую грубую силу.
Что вы можете сделать, это сгенерировать код с кодом. Напишите скрипт с оператором select для all_tab_columns, который сгенерирует операторы сравнения и другие строки кода, необходимые для каждого столбца, а затем выгрузит выходные данные в триггер. Используйте dbms_output.put_line, чтобы выплевывать код, который вы хотите.
Напишите курсор, подобный так (это без манжеты, вам придется работать кодирование):
SELECT
'IF (:new.'||column_name||' <> :old.'||atc.column_name||') THEN' as my_ifstmt
FROM
all_tab_columns atc
WHERE
atc.owner = 'MYSCHEMA'
AND atc.table_name = 'MY_TABLE'
Получите результаты с dbms_output.put_line вместе с оператором для вставки результата в таблицу аудита или что вы хотите сделать:
dbms_output.put_line(my_cursor.my_ifstmt);
dbms_output.put_line('INSERT INTO my_audit_table... bla bla bla');
dbms_output.put_line("END IF;")
Поместите все это в свой курсор l oop. Нет, этот код еще не закончен и не функционален, но я могу использовать этот подход, учитывая описание ваших ограниченных требований. Попробуйте соединить это вместе, и я могу добавить еще.