根据日期删除多个分区

时间:2018-01-04 05:28:21

标签: oracle partition

我有一个基于每日分区的表。

我可以使用以下查询删除paritition

ALTER TABLE MY_TABLE DROP PARTITION FOR(TO_DATE('19-DEC-2017','dd-MON-yyyy'))

如何在15天之前删除所有分区(多个分区)?

2 个答案:

答案 0 :(得分:5)

您可以像这样使用PL / SQL。

DECLARE
    CANNOT_DROP_LAST_PARTITION EXCEPTION;
    PRAGMA EXCEPTION_INIT(CANNOT_DROP_LAST_PARTITION, -14758);

   ts TIMESTAMP;
BEGIN
   FOR aPart IN (SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'MY_TABLE') LOOP
      EXECUTE IMMEDIATE 'BEGIN :ret := '||aPart.HIGH_VALUE||'; END;' USING OUT ts;
      IF ts < SYSTIMESTAMP - INTERVAL '15' DAY THEN
      BEGIN
         EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE DROP PARTITION '||aPart.PARTITION_NAME|| ' UPDATE GLOBAL INDEXES';
      EXCEPTION
            WHEN CANNOT_DROP_LAST_PARTITION THEN
                EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE SET INTERVAL ()';
                EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE DROP PARTITION '||aPart.PARTITION_NAME;
                EXECUTE IMMEDIATE 'ALTER TABLE MY_TABLE SET INTERVAL( INTERVAL ''1'' DAY )';            
      END;
      END IF;
   END LOOP;
END;

答案 1 :(得分:1)

对于间隔分区表(您可能基于例外ORA-14758使用),您可以使用partition_extended_name语法。

您不需要知道分区名称,请使用DATE引用分区,例如

alter table INT_PART drop partition for (DATE'2018-09-01')

因此要删除从当前日期开始的最后15个分区,将执行此循环:

declare
 v_sql VARCHAR2(4000);
begin
  for cur in (select  
                trunc(sysdate,'MM') - numtodsinterval(rownum - 1, 'day') my_month
              from dual connect by level <= 15) 
  loop
     v_sql := q'[alter table INT_PART drop partition for (DATE']'||
                 to_char(cur.my_month,'YYYY-MM-DD')||q'[')]';
     execute immediate v_sql;
  end loop;
end;
/

您必须使用execute immediate作为ALTER TABLE语句中DATE的日期,并且必须是静态的。 生成并执行以下语句:

alter table INT_PART drop partition for (DATE'2018-09-01')
alter table INT_PART drop partition for (DATE'2018-08-31')
....
alter table INT_PART drop partition for (DATE'2018-08-19')
alter table INT_PART drop partition for (DATE'2018-08-18')

除了异常ORA-14758(我忽略了-请参阅下面的注释)之外,您还应处理异常

  

ORA-02149:指定的分区不存在

取决于您的业务,应该将其忽略-到目前为止,没有分区存在(并且您将永远不会使用分区字典元数据来引用这一天)。

注意,要解决ORA-14758 Last partition in the range section cannot be dropped异常,您可以使用此小技巧。

我创建了一个名为P_MINVALUE dummy 分区(无范围),该分区起着间隔开始的作用,因此它将永远不会消失。

CREATE TABLE int_part
      (
     transaction_date TIMESTAMP not null,
     vc_pad VARCHAR2(100)
      )
     SEGMENT CREATION DEFERRED 
     PARTITION BY RANGE (transaction_date) INTERVAL (NUMTODSINTERVAL(1,'DAY'))
      (
     PARTITION P_MINVALUE  VALUES LESS THAN (TO_DATE('2000-01-01', 'YYYY-MM-DD') ) 
   );