Как узнать, когда таблица Oracle была обновлена ​​в последний раз - PullRequest
23 голосов
/ 05 ноября 2008

Могу ли я узнать, когда последний оператор INSERT, UPDATE или DELETE был выполнен для таблицы в базе данных Oracle, и если да, то как?

Немного предыстории: версия Oracle 10g. У меня есть пакетное приложение, которое регулярно запускается, читает данные из одной таблицы Oracle и записывает их в файл. Я хотел бы пропустить это, если данные не изменились с момента последнего запуска задания.

Приложение написано на C ++ и связывается с Oracle через OCI. Он входит в Oracle с «обычным» пользователем, поэтому я не могу использовать какие-либо специальные админские вещи.

Редактировать: Хорошо, "Special Admin Stuff" не совсем подходящее описание. Я имею в виду: я ничего не могу сделать, кроме ВЫБОРА из таблиц и вызова хранимых процедур. Изменять что-либо в самой базе данных (например, добавлять триггеры), к сожалению, не вариант, если вы хотите сделать это до 2010 года.

Ответы [ 11 ]

44 голосов
/ 26 июля 2011

Я очень опоздал на эту вечеринку, но вот как я это сделал:

SELECT SCN_TO_TIMESTAMP(MAX(ora_rowscn)) from myTable;

Это достаточно близко для моих целей.

36 голосов
/ 05 ноября 2008

Поскольку вы используете 10g, вы можете использовать псевдостолбец ORA_ROWSCN. Это дает вам верхнюю границу последнего SCN (номер изменения системы), который вызвал изменение в строке. Поскольку это возрастающая последовательность, вы можете сохранить максимальный ORA_ROWSCN, который вы видели, а затем искать только данные с SCN больше этого.

По умолчанию ORA_ROWSCN фактически поддерживается на уровне блока, поэтому изменение любой строки в блоке изменит ORA_ROWSCN для всех строк в блоке. Этого, вероятно, вполне достаточно, если целью является минимизация количества обрабатываемых строк несколько раз без изменений, если мы говорим о «нормальных» шаблонах доступа к данным. Вы можете перестроить таблицу с помощью ROWDEPENDENCIES, что приведет к отслеживанию ORA_ROWSCN на уровне строк, что даст вам более детальную информацию, но потребует одноразовых усилий для перестройки таблицы.

Другой вариант - настроить что-то вроде Change Data Capture (CDC) и сделать приложение OCI подписчиком на изменения в таблице, но это также требует единовременных усилий для настройки CDC.

9 голосов
/ 05 ноября 2008

Спросите своего администратора базы данных об аудите. Он может начать аудит с помощью простой команды, например:

AUDIT INSERT ON user.table

Затем вы можете запросить таблицу USER_AUDIT_OBJECT, чтобы определить, была ли вставка в вашу таблицу с момента последнего экспорта.

Google для аудита Oracle для получения дополнительной информации ...

8 голосов
/ 25 августа 2014
SELECT * FROM all_tab_modifications;
7 голосов
/ 05 ноября 2008

Не могли бы вы выполнить какую-либо контрольную сумму результата и сохранить ее локально? Затем, когда ваше приложение запрашивает базу данных, вы можете сравнить ее контрольную сумму и определить, следует ли ее импортировать?

Похоже, что вы можете использовать функцию ORA_HASH для этого.

Обновление: Еще один полезный ресурс: Функция 10RA ORA_HASH для определения, равны ли данные двух таблиц Oracle

4 голосов
/ 05 ноября 2008

Oracle может наблюдать за изменениями в таблицах, а при их изменении может выполнять функцию обратного вызова в PL / SQL или OCI. Обратный вызов получает объект, который представляет собой набор таблиц, которые изменились, и который содержит коллекцию измененных строк и тип действия, Ins, upd, del.

Так что ты даже не идешь к столу, ты сидишь и ждешь вызова. Вы пойдете, только если есть изменения, чтобы написать.

Это называется Уведомление об изменении базы данных . Как упоминал Джастин, это намного проще, чем CDC, но оба требуют некоторой фантазии администратора. Хорошая часть заключается в том, что ни один из них не требует изменений в заявке.

Предостережение заключается в том, что CDC подходит для таблиц большого объема, а DCN - нет.

2 голосов
/ 13 декабря 2018

Если аудит включен на сервере, просто используйте

SELECT *
FROM ALL_TAB_MODIFICATIONS
WHERE TABLE_NAME IN ()
1 голос
/ 05 ноября 2008

Сколько времени занимает пакетный процесс для записи файла? Возможно, проще всего позволить ему пойти дальше, а затем сравнить файл с копией файла из предыдущего запуска, чтобы убедиться, что они идентичны.

1 голос
/ 05 ноября 2008

Вам потребуется добавить триггер при вставке, обновлении, удалении, который устанавливает значение в другой таблице для sysdate.

Когда вы запускаете приложение, оно считывает значение и сохраняет его где-нибудь, чтобы при следующем запуске оно имело ссылку для сравнения.

Считаете ли вы, что "Special Admin Stuff"?

Было бы лучше описать, что вы на самом деле делаете, чтобы получить более четкие ответы.

0 голосов
/ 26 июля 2016

Если кто-то все еще ищет ответ, он может использовать Функция Oracle Database Change Notification , поставляемая с Oracle 10g. Требуется CHANGE NOTIFICATION системная привилегия. Вы можете зарегистрировать слушателей, когда вызывать уведомление обратно в приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...