2016-01-05 3 views
0

Как заголовок, я хочу создать процедуру в Oracle/PLSQL для удаления строк, которые используют одни и те же значения в некоторых столбцах. Я знаю, как реализовать его с помощью Query, но как это сделать с помощью процедуры? Должен ли я использовать любой цикл? Я очень новичок в PLSQLУдаление дублированных записей с использованием процедуры в Oracle/PLSQL

Пожалуйста, помогите, большое вам спасибо!

ответ

1

Если вы хотите простую процедуру, чтобы удалить из определенной таблицы вы можете использовать приведенный ниже фрагмент кода:

CREATE OR REPLACE PROCEDURE DELETE_DUPLICATE AS 

BEGIN 

    FOR I IN (SELECT TAB.A, TAB.B, MIN(ROWID) RID 
       FROM DUPLICATE_TABLE TAB 
      GROUP BY TAB.A, TAB.B 
      HAVING COUNT(*) > 1) LOOP 

    DELETE FROM DUPLICATE_TABLE TAB 
    WHERE I.RID <> TAB.ROWID 
     AND TAB.A = I.A 
     AND TAB.B = I.B; 

    COMMIT; 

    END LOOP; 

END; 

Здесь DUPLICATE_TABLE является таблица, имеющие одинаковые значения. Мы удаляем строки, имеющие одинаковые значения в столбцах A и B.

+0

большое спасибо! –

0

Если вы знаете, как это сделать в SQL, лучше сделать это в sql. PL/SQL следует использовать только тогда, когда вы не можете написать конкретную задачу в SQL-заявлении или если в запросе есть проблемы с производительностью, и может улучшиться, написав логику в PL/SQL (второй сценарий очень редок).

Если вы хотите написать процедуру PL/SQL для параметризации, чтобы любая таблица могла быть передана для удаления дубликатов из нее, тогда это имеет смысл. Вам необходимо динамически генерировать инструкцию delete в процедуре и выполнить с помощью execute immediate.

Если вы намереваетесь изучить PL/SQL, то это язык программирования, и вам нужно потратить некоторое время, как если бы вы изучали новый язык программирования.

+0

Не совсем ответ. Должен быть комментарий. – Drumbeg

0

Не рекомендуется использовать PLSQL для чего-то, что можно сделать с использованием простого sql. Всякий раз, когда у вас есть комбинация sql и plsql, вы переключаетесь между sql и plsql двигателем. Поэтому не имеет смысла выполнять эти накладные расходы без надлежащего требования.

Если по какой-то причине по-прежнему необходимо это сделать, вы можете по крайней мере реализовать массовое удаление, чтобы уменьшить некоторые накладные расходы. Пожалуйста, обратитесь к приведенной ниже код, чтобы узнать, как сделать это -

DECLARE 
TYPE t_del IS TABLE OF VARCHAR2(100); 
l_del t_del; 

CURSOR c IS 
SELECT MIN(ROWID) RID 
    FROM test_tbl TAB 
    GROUP BY TAB.age, TAB.gender 
    HAVING COUNT(*) > 1; 

BEGIN 
    OPEN c; 
    LOOP 
    FETCH c BULK COLLECT INTO l_del; 
    EXIT WHEN l_del.COUNT = 0; 
    FORALL i IN l_del.FIRST..l_del.last 
    DELETE FROM test_tbl WHERE ROWID = l_del(i); 
    END LOOP; 
END; 
0

Эй. В соответствии с вашим вопросом, хотя не рекомендуется создавать процедуру для этой более простой задачи, которую легко выполнить с помощью Pure SQL. Но если его действительно сделать, чтобы сделать его хранимой процедурой, я бы предложил использовать логику PURE SQL, чем использовать какой-либо цикл, так как там будет преобразовывать контекст, который будет иметь значение в базе данных. Ниже приведен фрагмент, который, я думаю, будет полезен. Аналитическая функция, достаточная для решения вашей проблемы. Дайте мне знать, если это поможет.

CREATE OR REPLACE PROCEDURE Dup_DELETE 
AS 
BEGIN 
    DELETE 
    FROM EMP 
    WHERE EMP.ROWID IN 
    -- Assuming that i am trying to segregate the duplicate values on Empno and ename 
    (SELECT A.ROWID 
    FROM 
     (SELECT ROW_NUMBER() OVER(PARTITION BY EMPNO,ENAME ORDER BY JOB DESC) RNK, 
     empno, 
     ename, 
     rowid 
     FROM EMP 
    )A 
    WHERE A.RNK <> 1 
    ); 
END; 
1

Просто поместите ваш SQL заявление в порядке. Не существует правила, согласно которому вы должны изменить подход, потому что это PL/SQL. Например,

create or replace procedure dedupe_sometable 
as 
begin 
    delete sometable 
    where rowid in 
      (select lag(rowid) over (partition by id order by null) 
      from sometable); 
end dedupe_sometable; 

Добавить регистрацию и т. Д. По мере необходимости.

(В идеале это было бы в рамках пакета, а не отдельной процедуры.)

Смежные вопросы