Очень часто, при удалении дубликатов из таблицы, оказывается, что на нее уже ссылаются записи из других таблиц. Поэтому перед удалением. нам нужно заменить айдишники в дочерних таблицах, а потом удалять дубликаты. Для этого, я использую следующий скрипт:
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 перебиваем старые айдишники в подчиненных таблицах, на новые. И в заключении удаляем запись.
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 перебиваем старые айдишники в подчиненных таблицах, на новые. И в заключении удаляем запись.
Комментариев нет:
Отправить комментарий