管理分区表(自动创建和删除子分区)

        我管理的数据库是一个数据仓库系统,数据量比较大,对一些系统ETL产生的中间表打算只保存半年,因此我设计了一个程序来帮助我管理我的分区表。他会自动创建子分区,并且把半年以前的子分区删除。

------------------------自动创建子分区的存储过程----------------------------

CREATE OR REPLACE PROCEDURE GENE_AUTO_ADD_PARTITION(part_month        varchar2)
IS

/***********************************************************************
/* Procedure   : GENE_AUTO_ADD_PARTITION
/* Description : General类程序,用于自动增加分区表的分区 == 计算到part_month为止,该增加多少个分区
/* Logic       : 1、找出需要增加分区的分区表,以及这些分区表的最近分区
/*               2、计算这些分区表要增加几个分区
/*               3、循环为这些分区表增加分区,直至增加到part_month分区为止
/*               4、记录日志
/* Warning     : 确保有足够权限,需显示授权:Grant select on dba_segments to user;
/* eg          : call gene_auto_add_partition(201210);
/* Author       YYYY-MM-DD      DSC
/* Feng         2012-07-30      初始版本
/*
/*********************************************************************/
  vcurrPartitionName                 varchar2(100);
  vhistPartitionName                 varchar2(100);
  vCount                             number;
  vDDLSql                            varchar2(1024);
  vLessthan                          varchar2(24);
  i1                                 number;
  i2                                 number;
 
BEGIN
 
  --format current partition name
  vcurrPartitionName := 'M_'||part_month;
 
  For x in (
    SELECT segment_name , max(partition_name) partition_name, max(tablespace_name) tablespace_name
      FROM dba_segments a
     WHERE wner = 'BAM'
       AND segment_type = 'TABLE PARTITION'
       AND segment_name not like '%BIN%'
       AND not exists (
          SELECT 1
            FROM dba_segments b
           WHERE a.segment_name = b.segment_name
             AND b.partition_name = vcurrPartitionName)
     GROUP BY a.segment_name
  ) LOOP
 
    --计算需要增加几个分区
    SELECT (extract(year from to_date(part_month,'yyyymm')) - extract(year from to_date(substr(x.partition_name,3),'yyyymm')))*12 +
           (extract(month from to_date(part_month,'yyyymm')) - extract(month from to_date(substr(x.partition_name,3),'yyyymm')))
      INTO vCount
      FROM dual;
   
    For j in 1.. vCount LOOP
     
      --get history Partition name
      vhistPartitionName := 'M_'||to_char(add_months(to_date(substr(x.partition_name,3),'yyyymm'),j),'yyyymm');
      vLessthan := to_char(add_months(to_date(substr(x.partition_name,3),'yyyymm'),j),'yyyymmdd');
     
      vDDLSql := 'ALTER TABLE '||x.segment_name||' ADD PARTITION '||vhistPartitionName||' VALUES LESS THAN('||vLessthan||') TABLESPACE '||x.tablespace_name;
     
      DBMS_UTILITY.exec_ddl_statement(vDDLSql);
     
      i1:= i1 + 1;
     
    END LOOP;
   
    i1 := i1;
    i2 := i2 + 1;
  
  END LOOP;
 
  raise_log('GENE_AUTO_ADD_PARTITION','为'||part_month||'创建子分区成功,共创建了'||i2||'张表的'||i1||'个分区');
 
EXCEPTION
  WHEN others THEN
    raise_application_err(SQLCODE,'GENE_AUTO_ADD_PARTITION',SQLERRM);
END;

------------------------自动删除子分区的存储过程----------------------------

CREATE OR REPLACE PROCEDURE GENE_AUTO_DROP_PARTITION(part_month      varchar2
                                                    ,period          number default 6)
IS

/***********************************************************************
/* Procedure   : GENE_AUTO_DROP_PARTITION
/* Description : General类程序,用于自动删除分区表的分区
/* Logic       : 1、找出需要删除分区的分区表,以及这些分区表的最远分区,确保只删除bam_cur_dat, bam_plf_dat表空间中的分区表
/*               2、以period为界限,计算这些分区表要删除几个分区
/*               3、循环为这些分区表删除分区,直至删除到part_month分区为止
/*               4、检查表索引的状态,对于失效的索引进行重新分析。
/*               5、记录日志
/* Warning     : 确保有足够权限,需显示授权:Grant select on dba_segments to user;
/*               分区索引(local)不存在删除索引后索引失效的问题,因此在此不考虑索引失效的rebuild问题。
/*               由于数据仓库事实表中极少用到主外键约束,因此在此不考虑暂时停用约束和启用约束的问题。
/*               所删除的分区采用直接丢弃方式,因此在此不考虑删除分区前,对分区的数据进行备份。
/* eg          : call gene_auto_drop_partition(201210);
/*               call gene_auto_drop_partition(201210,12);
/* Author       YYYY-MM-DD      DSC
/* Feng         2012-07-31      初始版本
/*
/*********************************************************************/

  vPartMonth                             varchar2(100);
  vOldPartitionName                      varchar2(100);
  vhistPartitionName                     varchar2(100);
  vCount                                 number;
  vDDLSql                                varchar2(1024);
  i                                      number;
  i2                                     number;
 
BEGIN
 
  --format Old partition name
  vPartMonth := to_char(add_months(to_date(part_month,'yyyymm'),-period),'yyyymm');
  vOldPartitionName := 'M_'||vPartMonth;
  dbms_output.put_line(vOldPartitionName);
 
  i := 0;
  i2:= 0;
 
  For x in (
    SELECT segment_name , min(partition_name) partition_name, min(tablespace_name) tablespace_name
        FROM dba_segments a
       WHERE wner = 'BAM'
         AND segment_type = 'TABLE PARTITION'
         AND segment_name not like '%BIN%'
         AND tablespace_name = any('BAM_CUR_DAT','BAM_PLF_DAT')
         AND exists (
            SELECT 1
              FROM dba_segments b
             WHERE a.segment_name = b.segment_name
               AND b.partition_name = vOldPartitionName)
       GROUP BY a.segment_name
  ) LOOP
 
    --计算要删除几个分区
    SELECT (extract(year from to_date(vPartMonth,'yyyymm')) - extract(year from to_date(substr(x.partition_name,3),'yyyymm')))*12 +
           (extract(month from to_date(vPartMonth,'yyyymm')) - extract(month from to_date(substr(x.partition_name,3),'yyyymm')))
      INTO vCount
      FROM dual;
 
    For j in 0.. vCount LOOP
     
      --get history partition name
      vhistPartitionName := 'M_'||to_char(add_months(to_date(substr(x.partition_name,3),'yyyymm'),j),'yyyymm');
     
      vDDLSql := 'ALTER TABLE '||x.segment_name||' DROP PARTITION '||vhistPartitionName;
     
      i := i + 1;
     
      raise_log('GENE_AUTO_DROP_PARTITION','删除'||x.segment_name||'表分区成功!删除了'||vhistPartitionName);
     
      DBMS_UTILITY.exec_ddl_statement(vDDLSql);
     
    END LOOP;
   
    i := i ;
    i2 := i2 + 1;
   
  END LOOP;
 
  raise_log('GENE_AUTO_DROP_PARTITION','删除'||vPartMonth||'之前的分区成功,删除了'||i2||'张表的'||i||'个分区。');
 
EXCEPTION
  WHEN others THEN
    raise_application_err(SQLCODE,'GENE_AUTO_DROP_PARTITION',SQLERRM);
END GENE_AUTO_DROP_PARTITION;

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10356975/viewspace-739345/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10356975/viewspace-739345/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值