Понимание поведения ORA_ROWSCN в Oracle - PullRequest
2 голосов
/ 01 марта 2012

Так что это, по сути, дополнительный вопрос по Поиск дубликатов записей .

Мы выполняем импорт данных из текстовых файлов каждый день, и в итоге мы импортировали 10163 записей, распределенных по 182 файлам дважды.При выполнении вышеупомянутого запроса для поиска дубликатов общее количество записей, которое мы получили, составляет 10174, что на 11 записей больше, чем содержится в файлах.Я предположил о возможности двух одинаковых записей, которые являются действительными и учитываются в запросе.Поэтому я подумал, что было бы лучше использовать поле метки времени и просто найти все записи, которые выполнялись сегодня (и, следовательно, в итоге добавили дублирующиеся строки).Я использовал ORA_ROWSCN, используя следующий запрос:

select count(*) from my_table
where TRUNC(SCN_TO_TIMESTAMP(ORA_ROWSCN)) = '01-MAR-2012'
;

Тем не менее, счетчик еще больше, т.е. 10168. Теперь я почти уверен, что общее количество строк в файле составляет 10163, выполнив следующую команду в папкекоторый содержит все файлы.wc -l *.txt.

Можно ли узнать, какие строки фактически вставлены дважды?

1 Ответ

14 голосов
/ 01 марта 2012

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

Поскольку ORA_ROWSCN гарантированно будет только верхней границей в последний раз, когда в строке был DML, было бы гораздо более распространенным определить, сколько строк было вставлено сегодня, добавив столбец CREATE_DATE в таблица со значением по умолчанию SYSDATE или положением SQL%ROWCOUNT после выполнения INSERT (при условии, конечно, что вы используете один оператор INSERT для вставки всех строк).

Как правило, использование функций ORA_ROWSCN и SCN_TO_TIMESTAMP будет проблематичным способом определения, когда была вставлена ​​строка, даже если таблица построена с ROWDEPENDENCIES. ORA_ROWSCN возвращает Oracle SCN, который является номером системного изменения. Это уникальный идентификатор для конкретного изменения (то есть транзакции). Таким образом, нет прямой связи между SCN и временем - моя база данных может генерировать SCN в миллион раз быстрее, чем ваша, а мой SCN 1 может отличаться на годы от вашего SCN 1. Фоновый процесс Oracle SMON поддерживает таблица, которая отображает значения SCN в приблизительные временные метки, но поддерживает эти данные только в течение ограниченного периода времени - в противном случае ваша база данных получит многомиллиардную таблицу строк, в которой просто хранятся SCN для сопоставлений временных меток. Если строка была вставлена ​​более, чем, скажем, неделю назад (и точное ограничение зависит от базы данных и версии базы данных), SCN_TO_TIMESTAMP не сможет преобразовать SCN в метку времени и вернет ошибку.

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