пятница, 20 мая 2016 г.

Удаление дубликатов с перебивкой айдишников

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

DECLARE
   l_id   NUMBER;

   PROCEDURE sp_merge_ids (p_old          IN INTEGER,
                           p_new          IN INTEGER,
                           p_table_name   IN VARCHAR2)
   IS
      v_str   VARCHAR2 (2000)
                 := 'update table set column = :new where column  = :old';
   BEGIN
      FOR rw
         IN (SELECT urcs2.table_name, uccs.column_name
               FROM user_constraints urcs1
               JOIN user_constraints urcs2
                 ON urcs1.constraint_name = urcs2.r_constraint_name
                AND urcs1.table_name = UPPER (p_table_name)
                AND urcs1.constraint_type = 'P'
               JOIN user_cons_columns uccs
                 ON uccs.constraint_name = urcs2.constraint_name)
      LOOP
         EXECUTE IMMEDIATE REPLACE (REPLACE (v_str, 'table', rw.table_name),
                                    'column',
                                    rw.column_name)
            USING p_new, p_old;
      END LOOP;
   END;
BEGIN
   FOR r IN (SELECT employee_id, employee_name
               FROM tbl_employee
              WHERE ROWID NOT IN (SELECT MAX (ROWID)
                                    FROM tbl_employee
                                   GROUP BY employee_name))
   LOOP
      SELECT employee_id
        INTO l_id
        FROM tbl_employee
       WHERE employee_name = r.employee_name
         AND employee_id <> r.employee_id
         AND ROWNUM = 1;

      sp_merge_ids (r.employee_id, l_id, 'tbl_employee');

      DELETE FROM tbl_employee
            WHERE employee_id = r.employee_id;
   END LOOP;
END;
/

В этом скрипте, удаляются дубликаты из таблицы tbl_employee. Сначала в цикле мы определяем записи для удаления. С помощью селекта находим дубликат, который должен остаться и при помощи процедуры sp_merge_ids перебиваем старые айдишники в подчиненных таблицах, на новые. И в заключении удаляем запись.

Комментариев нет:

Отправить комментарий