Триггер выполняется после DDL операции и сохраняет: тип объекта (ora_dict_obj_type), схему (ora_dict_obj_owner), имя объекта (ora_dict_obj_name), имя пользователя , дата операции, тип DDL операции (ora_sysevent), имя компьютера и CLOB с текстом DDL операции (ora_sql_txt).
create or replace TRIGGER bi_sa_psk.trg_ddl_trig_hist
AFTER DDL
ON DATABASE
declare
PRAGMA AUTONOMOUS_TRANSACTION;
v_ddl CLOB := EMPTY_CLOB;
li ora_name_list_t;
l_n number;
BEGIN
/* sys создает системные временные таблицы для sql запросов */
IF ora_dict_obj_owner = 'SYS' THEN
return;
END IF;
/* Получим текст DDL */
l_n := ora_sql_txt(li);
for i in 1 .. l_n loop
v_ddl := v_ddl || TO_CLOB(TO_CHAR(li(i)));
end loop;
/* запишем историю */
INSERT INTO bi_sa_psk.ddl_hist(object_type, owner, object_name, USER_NAME, DDL_DATE, DDL_TYPE, COMP_NAME, DDL_TXT, stack)
VALUES(UPPER(ora_dict_obj_type), UPPER(ora_dict_obj_owner), UPPER(ora_dict_obj_name), ora_login_user, SYSDATE, ora_sysevent, SYS_CONTEXT ('USERENV', 'OS_USER'), v_ddl, dbms_utility.format_call_stack);
commit;
/* любые ошибки игнорируем, что бы не завалить БД целиком */
EXCEPTION WHEN OTHERS THEN NULL;
END trg_ddl_trig_hist;
/
Такая штука будет очень полезна, чтобы вернуть утерянные изменения или отыскать виновного в баге :) .