Automating Old Partition Cleanup in Oracle with PL/SQL
- This PL/SQL block is designed to automate partition maintenance for all tables owned by the schema CMN_OWNR. It loops through each table partition (skipping ones with INIT in their name), extracts the partition boundary date from the high_value column, and checks if it is on or before 1st June 2025.
- If the condition is met, it tries to drop the partition along with updating indexes; however, if the partition cannot be dropped due to being the last one (ORA-14758), it instead truncates the partition to remove data while keeping structure intact.
- This ensures that only old partitions are purged while preserving the latest required ones. In short, it’s a safe cleanup mechanism for managing historical data in partitioned tables.
DECLARE
v_date DATE;
v_sql VARCHAR2(4000);
BEGIN
FOR i IN (SELECT dp.table_name,
dp.partition_name,
dp.high_value,
dp.partition_position
FROM dba_tab_partitions dp
WHERE dp.table_owner = 'CMN_OWNR'
and dp.partition_name not like '%INIT%'
--AND table_name = 'CMN_LOG'
ORDER BY dp.table_name, partition_position) LOOP
v_date := TO_DATE(substr(i.high_value, 12, 10), 'RRRR-MM-DD');
IF v_date <= to_date('01-JUN-2025', 'dd-mon-yyyy') THEN
v_sql := 'ALTER TABLE CMN_OWNR.' || i.table_name ||
' DROP PARTITION ' || i.partition_name || ' UPDATE INDEXES';
BEGIN
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -14758 THEN
v_sql := 'ALTER TABLE CMN_OWNR.' || i.table_name ||
' TRUNCATE PARTITION ' || i.partition_name ||
' UPDATE INDEXES';
EXECUTE IMMEDIATE v_sql;
ELSE
dbms_output.put_line(SQLERRM);
dbms_output.put_line(v_sql);
END IF;
END;
END IF;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
🔎 Step-by-step explanation
1. Loop through all partitions
FOR i IN (
SELECT dp.table_name,
dp.partition_name,
dp.high_value,
dp.partition_position
FROM dba_tab_partitions dp
WHERE dp.table_owner = 'CMN_OWNR'
AND dp.partition_name NOT LIKE '%INIT%'
ORDER BY dp.table_name, partition_position
) LOOP
- Finds all partitions of all tables owned by CMN_OWNR.
- Skips partitions whose name contains INIT.
- Loops through each partition in order.
2. Extract partition boundary date
v_date := TO_DATE(SUBSTR(i.high_value, 12, 10), 'RRRR-MM-DD');
- dba_tab_partitions.high_value is a text expression like:
- TO_DATE(' 2025-06-01 00:00:00','SYYYY-MM-DD HH24:MI:SS', ...)
- SUBSTR(...,12,10) picks 2025-06-01.
- TO_DATE(...,'RRRR-MM-DD') converts that to an Oracle DATE → 01-JUN-2025.
3. Check if partition is old
IF v_date <= TO_DATE('01-JUN-2025','DD-MON-YYYY') THEN
- If the partition’s upper boundary date is before or equal to 01-JUN-2025, it’s considered old → purge it.
4. Try to drop the partition
v_sql := 'ALTER TABLE CMN_OWNR.' || i.table_name ||
' DROP PARTITION ' || i.partition_name ||
' UPDATE INDEXES';
EXECUTE IMMEDIATE v_sql;
- Builds dynamic SQL to drop the old partition.
- UPDATE INDEXES ensures local/global indexes remain usable.
5. Handle errors
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -14758 THEN
v_sql := 'ALTER TABLE CMN_OWNR.' || i.table_name ||
' TRUNCATE PARTITION ' || i.partition_name ||
' UPDATE INDEXES';
EXECUTE IMMEDIATE v_sql;
ELSE
dbms_output.put_line(SQLERRM);
dbms_output.put_line(v_sql);
END IF;
- If DROP fails with ORA-14758 (cannot drop the last partition in a range), it falls back to:
- ALTER TABLE ... TRUNCATE PARTITION ...
- → keeps the partition structure but deletes its data.
- Any other error is logged with dbms_output.
6. Global error handling
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
- If the whole block fails for some reason, the error is printed.
Summary —
This PL/SQL script automatically manages old partitions in Oracle tables owned by CMN_OWNR. It checks each partition’s HIGH_VALUE date and, if it is on or before 01-JUN-2025, it attempts to drop the partition. If dropping is not allowed (SQL error -14758), it instead truncates the partition while updating indexes. This helps keep partitioned tables lean by cleaning up historical data without manual intervention.
Top comments (0)