Para operações de delete em grandes tabelas, uma opção é utilizar o conceito de BULK o que garante não só uma melhor performance no DELETE com também diminui a quantidade de controles por causa dos COMMITs. Um exemplo seria:
CREATE OR REPLACE PROCEDURE PR_PURGE IS
CURSOR cdr_cur IS
SELECT ROWID FROM <TABELA> c where <CONDICAO>;
TYPE cdr_data IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
cdr cdr_data;
BEGIN
OPEN cdr_cur;
LOOP
cdr.DELETE;
FETCH cdr_cur BULK COLLECT INTO cdr LIMIT <LIMITE>; --LIMITE
IF cdr.COUNT>0 THEN
FORALL j IN 1..cdr.COUNT
DELETE FROM <TABELA> WHERE ROWID=cdr(j);
COMMIT;
ELSE
EXIT;
END IF;
END LOOP;
CLOSE cdr_cur;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF cdr_cur%ISOPEN THEN CLOSE cdr_cur; END IF;
END;
onde:
<TABELA> - Tabela que será manipulada
<CONDICAO> - Condição de pesquisa/seleção
<LIMITE> - Quantidade de registros transacionados por vez
exemplo:
CREATE OR REPLACE PROCEDURE PR_PURGE IS
CURSOR cdr_cur IS
SELECT ROWID FROM TABELA_A c where c.DATA > '20141201';
TYPE cdr_data IS TABLE OF ROWID INDEX BY BINARY_INTEGER;
cdr cdr_data;
BEGIN
OPEN cdr_cur;
LOOP
cdr.DELETE;
FETCH cdr_cur BULK COLLECT INTO cdr LIMIT 100000;
IF cdr.COUNT>0 THEN
FORALL j IN 1..cdr.COUNT
DELETE FROM TABELA_A WHERE ROWID=cdr(j);
COMMIT;
ELSE
EXIT;
END IF;
END LOOP;
CLOSE cdr_cur;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF cdr_cur%ISOPEN THEN CLOSE cdr_cur; END IF;
END;