2013-02-18 54 views
4

我有一个基于日期字段的分区表。现在,我必须编写一个过程来删除所有2个月以上的分区,即test_date大于2个月。我该怎么做?丢弃2个月以上的分区

create table test_table 
(
test_id number, 
test_date date, 
constraint pk_test primary key (test_id) 
) 
partition by range (test_date) 
(
PARTITION pt01122012 VALUES LESS THAN (TO_DATE('01-DEC- 
2012', 'DD-MON-YYYY')), 
PARTITION pt01022013 VALUES LESS THAN (TO_DATE('01-FEB- 
2013', 'DD-MON-YYYY')), 
PARTITION pt01042013 VALUES LESS THAN (TO_DATE('01-APR- 
2013', 'DD-MON-YYYY')), 
PARTITION pt01062013 VALUES LESS THAN (TO_DATE('01-JUN- 
2013', 'DD-MON-YYYY')), 
PARTITION pt01082013 VALUES LESS THAN (TO_DATE('01-AUG- 
2013', 'DD-MON-YYYY')) 
); 

在此先感谢...

回答

11

首先,我想指出的是分区是Oracle先进的主题,因此,你可能想在开始手动运行所有DDL,直到你”运行DDL脚本足够自信。我还建议你永远不要运行在因特网上发现的脚本,而不必同时理解 it和测试,尤其是DDL脚本。

现在手头的事情,你可以查询*_TAB_PARTITIONS字典视图来获取分区边界:

SQL> SELECT partition_name, high_value 
    2 FROM user_tab_partitions 
    3 WHERE table_name = 'TEST_TABLE'; 

PARTITION_NAME HIGH_VALUE 
--------------- -------------------------------------------------------- 
PT01122012  TO_DATE(' 2012-12-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' 
PT01022013  TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' 
PT01042013  TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' 
PT01062013  TO_DATE(' 2013-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' 
PT01082013  TO_DATE(' 2013-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS' 

此列LONG型(=弃用LOB)的,所以我们有一些工具,过滤SQL,我们将不得不使用PL/SQL。

SQL> BEGIN 
    2  FOR cc IN (SELECT partition_name, high_value -- 
    3     FROM user_tab_partitions 
    4     WHERE table_name = 'TEST_TABLE') LOOP 
    5  EXECUTE IMMEDIATE 
    6   'BEGIN 
    7    IF sysdate >= ADD_MONTHS(' || cc.high_value || ', 2) THEN 
    8     EXECUTE IMMEDIATE 
    9      ''ALTER TABLE TEST_TABLE DROP PARTITION ' 
10      || cc.partition_name || ' 
11      ''; 
12    END IF; 
13   END;'; 
14  END LOOP; 
15 END; 
16/

PL/SQL procedure successfully completed 

SQL> SELECT partition_name, high_value 
    2 FROM user_tab_partitions 
    3 WHERE table_name = 'TEST_TABLE'; 

PARTITION_NAME HIGH_VALUE 
--------------- ----------------------------------------------------------- 
PT01022013  TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
PT01042013  TO_DATE(' 2013-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
PT01062013  TO_DATE(' 2013-06-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
PT01082013  TO_DATE(' 2013-08-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 
+0

你可以建议任何其他方式删除这种其他程序方法吗? – TomJava 2018-01-03 05:09:03

+0

表中存在的主键会发生什么情况? – TomJava 2018-01-03 05:10:29

+1

@TomJava我知道这是迟到,但对于其他人来说:这是手动以外的最佳方式。您将需要添加更新索引语句,以便由于分区删除而重建它。如果您有IOT分区,请使用“更新全局索引” – 2018-03-05 17:03:32