在数据库日常管理中,对大表进行分区表是一个不错的策略,分区不仅可以优化表的性能还能对数据进行归档和易于管理。但是如果表的数据会定期删除,比如保留3-6个月的数据,那么会有很多数据保留在数据库中,需要进行定期清理。一下存储过程是识别空行分区并定期删除。
CREATE OR REPLACE PROCEDURE TEST_SCHEMA.TRUNC_SUB_PARTITION
(
TNAME IN VARCHAR2 --TABLE NAME
--PROC_STATUS OUT VARCHAR2, --PROCEDURE EXCEPTION CODE.
--IMP_ROWS OUT NUMBER --THE ARCHIVED ROWS
)
AS
PROC_NAME VARCHAR2(32); ---PARTITION NAME
NUM_ROWS NUMBER; ---PARTITION ROWS
TOWNER VARCHAR2(32) default SYS_CONTEXT('USERENV','CURRENT_SCHEMA');
OPT_MSG VARCHAR2(512);
QUERYTAB VARCHAR2(128);
TRUNCTAB VARCHAR2(128);
CURSOR GET_PART IS
SELECT PARTITION_NAME,PARTITION_POSITION,NUM_ROWS,HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = TNAME ORDER BY 2;
CUR GET_PART%ROWTYPE;
BEGIN
--SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') INTO TOWNER FROM DUAL;
DBMS_OUTPUT.PUT_LINE(TOWNER);
PROC_NAME := 'TRUNC_SUB_PARTITION';
--TOWNER := 'TEST_SCHEMA';
--DBMS_STATS.GATHER_TABLE_STATS(TOWNER,TNAME); --GATHER THE STATISTICS OF THE TABLE
--DBMS_OUTPUT.PUT_LINE(TRUNCTAB);
FOR CUR IN GET_PART LOOP
QUERYTAB := 'select count(1) from '||TOWNER||'.'||TNAME||' partition ('||CUR.PARTITION_NAME||')';
DBMS_OUTPUT.PUT_LINE(QUERYTAB);
EXECUTE IMMEDIATE QUERYTAB INTO NUM_ROWS;
IF NUM_ROWS = 0
THEN
TRUNCTAB := 'ALTER TABLE '||TOWNER||'.'||TNAME||' DROP PARTITION ('||CUR.PARTITION_NAME||') UPDATE INDEXES';
--NUM_ROWS := CUR.NUM_ROWS;
DBMS_OUTPUT.PUT_LINE(TRUNCTAB);
DBMS_OUTPUT.PUT_LINE('DROP table success');
EXECUTE IMMEDIATE TRUNCTAB;
--IMP_ROWS := SQL%ROWCOUNT;
OPT_MSG := 'SUCCESSFUL';
GEN_TEST_SCHEMA.PROC_EXEC_TT(PROC_NAME,0,TNAME,NUM_ROWS,OPT_MSG);
Else
OPT_MSG := 'Partition number:'||NUM_ROWS;
DBMS_OUTPUT.PUT_LINE(OPT_MSG);
--GEN_TEST_SCHEMA.PROC_EXEC_TT(PROC_NAME,1,TNAME,NUM_ROWS,OPT_MSG);
END IF;
END LOOP;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
OPT_MSG := 'NO PARTITION FOUND!';
GEN_TEST_SCHEMA.PROC_EXEC_TT(PROC_NAME,1,TNAME,NUM_ROWS,OPT_MSG);
COMMIT;
WHEN OTHERS THEN
--PROC_STATUS := SQLERRM;
DBMS_OUTPUT.PUT_LINE('SQLCODE : ' ||SQLCODE);
DBMS_OUTPUT.PUT_LINE('SQLERRM : ' ||SQLERRM);
OPT_MSG := SQLCODE||':'||SQLERRM;
GEN_TEST_SCHEMA.PROC_EXEC_TT(PROC_NAME,3,TNAME,NUM_ROWS,OPT_MSG);
COMMIT;
END;
/
该存储过程会自动识别空行分区并删除,同时重建索引。