在 Oracle 中,您有两种方法来寻址分区,它们是等效的。
ALTER TABLE prova_log DROP PARTITION p0816;
ALTER TABLE prova_log DROP PARTITION FOR ( to_date('01/09/2016','dd/mm/yyyy') );
如果您想处理 SUBPARTITION,语法如下:
ALTER TABLE prova_log TRUNCATE SUBPARTITION FOR ( to_date('01/09/2016','dd/mm/yyyy'), 2 );
为了删除(或截断)分区,我有这个通用的 PL/SQL 包。最棘手的部分是将HIGH_VALUE(LONG 数据类型)转换为可用值。
FUNCTION DailyPartition(tableName IN VARCHAR2) RETURN BOOLEAN IS
EXPRESSION_IS_OF_WRONG_TYPE EXCEPTION;
PRAGMA EXCEPTION_INIT(EXPRESSION_IS_OF_WRONG_TYPE, -6550);
ds INTERVAL DAY TO SECOND;
ym INTERVAL YEAR TO MONTH;
str VARCHAR2(1000);
BEGIN
SELECT INTERVAL INTO str FROM USER_PART_TABLES WHERE TABLE_NAME = tableName;
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ym;
RETURN FALSE;
EXCEPTION
WHEN EXPRESSION_IS_OF_WRONG_TYPE THEN
EXECUTE IMMEDIATE 'BEGIN :ret := '||str||'; END;' USING OUT ds;
RETURN TRUE;
END DailyPartition;
PROCEDURE DropPartition(tableName IN VARCHAR2, ts IN TIMESTAMP) IS
PARTITION_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(PARTITION_DOES_NOT_EXIST, -2149);
sqlstr VARCHAR2(1000);
BEGIN
sqlstr := 'ALTER TABLE '||tableName||' DROP PARTITION FOR (TIMESTAMP '''||TO_CHAR(ts, 'yyyy-mm-dd hh24:mi:ss')||''') UPDATE GLOBAL INDEXES';
EXECUTE IMMEDIATE sqlstr;
EXCEPTION
WHEN PARTITION_DOES_NOT_EXIST THEN
NULL;
END DropPartition;
PROCEDURE CleanupPartitions IS
sqlstr VARCHAR2(10000);
ts TIMESTAMP;
tableName VARCHAR2(30) := 'PROVA_LOG';
CURSOR TabPartitions IS
SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
FROM USER_TAB_PARTITIONS
WHERE TABLE_NAME = tableName
AND PARTITION_NAME <> 'P0816' -- Inital partition cannot be dropped
ORDER BY 1,2;
BEGIN
ts := ADD_MONTHS(TRUNC(LOCALTIMESTAMP) - INTERVAL '1' DAY, -6);
IF DailyPartition(tableName) THEN
DropPartition(tableName, ts);
IF EXTRACT(DAY FROM ts) >= 30 THEN
DropPartition(tab, ts - INTERVAL '1' DAY);
END IF;
IF TO_CHAR(ts, 'MM-DD') = '08-31' THEN
-- Ensure proper cleanup for February
DropPartition(tableName, ts - INTERVAL '2' DAY);
DropPartition(tableName, ts - INTERVAL '3' DAY);
END IF;
ELSE
DropPartition(tableName, ts);
END IF;
END CleanupPartitions;
保留时间为 6 个月。根据您的需要制作应该没有问题。您甚至可以多次调用程序CleanupPartitions;。通常它会由调度程序作业每月或每天执行一次。
该软件包适用于 daily 和 monthly 分区。