I would like to delete millions of records from lots many tables. In the below code, i'm trying to select a table with some filter condition and trying to delete using its row id. In the below, for the cursor test_cusr i'm selecting from (region) table and column (code) = 'XY'. I would like to pass the table, column and the value in dynamically. I tried with for loop and ref cursor but getting some error. Can any one help me in this.
DECLARE
CURSOR test_cur
IS
SELECT rowid row_id FROM region WHERE code = 'XY';
TYPE test_aat
IS
TABLE OF ROWID INDEX BY PLS_INTEGER;
l_test test_aat;
limit_in NUMBER := 10000;
BEGIN
OPEN test_cur;
LOOP
FETCH test_cur BULK COLLECT INTO l_test LIMIT limit_in;
IF l_test.COUNT = 0 THEN
EXIT;
END IF;
FORALL indx IN l_test.FIRST .. l_test.LAST
DELETE FROM region WHERE rowid = l_test(indx);
COMMIT;
END LOOP;
IF test_cur%ISOPEN THEN
DBMS_OUTPUT.PUT_LINE(test_cur%ROWCOUNT);
CLOSE test_cur;
END IF;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF test_cur%ISOPEN THEN
CLOSE test_cur;
END IF;
ROLLBACK;
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
Best Answer
If I were you, I'd put the values of the tables being deleted into an array, and then loop through that to do a single delete on that table. E.g.:
I've put what I thought was relevant into the array record type, but you may need more or fewer fields as you see fit.
I've also used a single DELETE statement, since that will be faster than committing every N rows. If you don't have enough UNDO tablespace to do a single delete, I recommend you get it extended, rather than having to commit periodically.