Проблема видалення дублів в таблицях oracle - все про it і програмуванні

Видалити такі дублі можна одним SQL-оператором:

Ми не будемо далі зупинятися на цьому завданні, оскільки зовсім не ця аспект є темою цієї статті. Більш того, темою статті не є навіть і відшукання дублів.

Нашою проблемою є видалення повторюваних записів, на які є посилання з інших таблиць. Самі повторювані рядки відомі заздалегідь.

Дуже часто виявляється, що користувачі не тільки кілька разів ввели одну і ту ж запис в таблицю, а й встигли кілька разів на неї послатися з інших таблиць, благо, додаток це дозволяло. Наприклад, не подивившись, що якась компанія вже є в списку контрагентів, користувач вніс її в довідник контрагентів ще раз, причому трохи помилився в назві, так що відстежити дубль за назвою не представлялося можливим. Потім він завів список контактних осіб, заповнив довідник синонімів назви компанії, і зареєстрував парочку замовлень. Згодом виявилося, що підприємство давно працює з даною компанією, і вже виконало для неї кілька десятків замовлень. І ось тепер нам потрібно видалити з довідника компаній зайву запис, переключивши попередньо всі посилання на неї на ту запис в таблиці, яка залишається.

Звичайно, облік психології користувача при розробці інтерфейсу програми може зменшити кількість таких дублів, але я не знаю абсолютно надійного способу запобігти подібну поведінку користувачів. Ручне ж лікування проблеми займає надто багато дорогоцінного часу адміністратора програми.

Якщо подібна проблема виникає тільки з однією таблицею, можна написати збережену процедуру саме під неї, але що робити, якщо таких таблиць кілька?

Ця проблема може виникнути і не з-за помилок користувача, а, наприклад, при злитті підрозділів, коли необхідно всіх співробітників перевести з одного підрозділу в інший.

Отже, спробуємо розробити універсальну процедуру для видалення повторюваних рядків в будь-яких таблицях, на які є посилання. Для спрощення завдання накладемо такі обмеження:
  1. Всі таблиці додатка зберігаються в одній схемі; в ній же ми і створимо нашу процедуру.
  2. Всі таблиці мають обмеження цілісності - первинні і зовнішні ключі.
  3. Використовуються тільки прості первинні ключі (що складаються з одного стовпчика).

Спочатку винесемо потрібну нам інформацію зі словника даних на прикладі таблиці підрозділів DEPARTMENTS.

  1. Використовуючи уявлення словника даних user_constraints, знайдемо всі зовнішні ключі, що посилаються на первинний ключ таблиці DEPARTMENTS:
  2. Потім, використовуючи уявлення словника user_cons_columns, відшукаємо відповідні їм імена таблиць і стовпців. Таким чином, ми отримаємо список таблиць і стовпців, значення яких потрібно буде змінювати:
  3. Використовуючи ті ж самі уявлення словника даних, знайдемо ім'я стовпця первинного ключа в таблиці

Знаючи ідентифікатор підрозділу, яке потрібно залишити (correct_id) і ідентифікатор удялять підрозділ (drop_id), ми можемо, використовуючи імена таблиць і стовпців зовнішнього ключа, отримані з другого запиту, сформувати запит на зміну значень зовнішнього ключа. А з третього запиту - отримати SQL - команду на видалення стала непотрібною рядка з таблиці DEPARTMENTS. Але ми підемо трохи далі, і створимо збережену процедуру, якої достатньо буде передати три параметри - ім'я таблиці, правильне і видаляється значення первинного ключа, і вона все зробить за нас. Щоб не замислюватися над типом стовпця первинного ключа, створимо дві ідентичних процедури з однаковими іменами, використовуючи принцип перевантаження, «засунь» їх в один зберігається пакет, і назвемо його DOUBLES (див. Додаток 1).

Тепер, щоб виконати розпорядження директора про злиття бухгалтерії (DEPT_ID = 28) і фінансового відділу (DEPT_ID = 101), досить виконати команду:

Додаток 1

Слід розуміти, що фрагментація таблиць відмінна від файлової фрагментації. Коли виконується серія операцій DML над таблицею, таблиця фрагментируется, тому що DML не звільняє вільний простір до HWM.HWM - це індикатор використання блоків (USED BLOCKS) в базі даних. Блоки йдуть до чи.

Default Permanent Tablespace Перейменування табличного пространстваТаблічное простір SYSAUX Складений табличний простір TempDefault Permanent TablespaceOracle 9i ввів поняття тимчасового табличного простору за замовчуванням (default temporary tablespace), що дозволило запобігти випадковим.

ALTER TABLE table_name READ ONLY; ALTER TABLE table_name READ WRITE; Наступний скрипт створює таблицю, додає в неї кілька рядків, потім переключається у режим регулювання таблицю в режим "тільки для читання" .CREATE TABLE ro_tab (id NUMBER); INSERT INTO ro_tab VALUES (1); INSERT INTO ro_tab VALUES (2).

Процедура створення практично не відрізняється від попередніх версій - 9i і 10g. У створюваній базі даних будемо використовувати такі опції: OMF (Oracle Managed File) для файлів даних, файлів журналів повторного виконання і керуючих файлів. FRA (Flash Recovery Area) для архівних журналів або резе.

Неможливість гарантувати, що всі зміни плану завжди будуть в кращу сторону, привела деяких замовників до того, щоб закріпити свої плани виконання (збережені плани) або блокувати статистику оптимізатора. Однак, якщо діяти таким чином, ми позбавляємо себе можливості коли-небудь вико.

Схожі статті