Мне неизвестны какие-либо подобные функции в Oracle. См. Ниже.
Лучшее решение, которое я могу придумать, - это создать триггер для каждой из ваших таблиц, который обновляет таблицу из одной строки или context с текущей датой / временем. Такие триггеры могут быть на уровне таблицы (в отличие от уровня строки), поэтому они не будут нести столько накладных расходов, как большинство триггеров.
Кстати, Oracle не может хранить идентификатор транзакции для каждой схемы, поскольку одна транзакция может повлиять на несколько схем. Можно было бы использовать V $ views для отслеживания транзакции обратно на объекты, на которые она влияла, но это было бы непросто и почти наверняка работало бы хуже, чем схема триггера.
Оказывается, если у вас есть 10g, вы можете использовать функцию флэшбэка Oracle, чтобы получить эту информацию. Тем не менее, вам нужно включить флэшбэк (который несет некоторые накладные расходы), и запрос смехотворно медленен (предположительно, потому что он на самом деле не предназначен для этого использования):
select max(commit_timestamp)
from FLASHBACK_TRANSACTION_QUERY
where table_owner = 'YOUR_SCHEMA'
and operation in ('INSERT','UPDATE','DELETE','MERGE')
Чтобы избежать проблем с блокировкой в таблице «последнее обновление», вы, вероятно, захотите поместить это обновление в процедуру, которая использует автономную транзакцию, например:
create or replace procedure log_last_update as
pragma autonomous_transaction;
begin
update last_update set update_date = greatest(sysdate,update_date);
commit;
end log_last_update;
Это приведет к тому, что ваше приложение будет до некоторой степени сериализовано: каждому оператору, которому нужно вызвать эту процедуру, нужно будет дождаться завершения предыдущего. Таблица «Последнее обновление» также может быть не синхронизирована, поскольку обновление в ней будет сохраняться, даже если откат обновления, активировавшего триггер, будет выполнен. Наконец, если у вас особенно длинная транзакция, приложение может подобрать новую дату / время до завершения транзакции, что противоречит цели. Чем больше я думаю об этом, тем больше это кажется плохой идеей.
Лучшее решение, чтобы избежать этих проблем, это просто вставить строку из триггеров. Это не заблокировало бы таблицу, поэтому не было бы никакой сериализации, и вставки не должны были бы выполняться асинхронно, чтобы они могли откатываться вместе с фактическими данными (и не были бы видимы для вашего приложения, пока данные тоже видны). Приложение получит максимум, который должен быть очень быстрым, если таблица будет проиндексирована (фактически, эта таблица была бы идеальным кандидатом для таблицы, организованной по индексу). Единственным недостатком является то, что вы хотите, чтобы задание периодически запускалось для очистки старых значений, чтобы оно не стало слишком большим.