zoukankan      html  css  js  c++  java
  • Oracle表增删分区的脚本

    一、前言

    项目中的Oracle库中有一张表(假设表名为Part_Tab),其中一列为Part_ID(int型),计划以该列作为分区依据。

    通常Part_ID的值有较固定区间(假设为1~10),但特殊情况下可能超出此范围;此外,其值并不连续。

    根据业务,要求以存储过程实现按照Part_ID增、删分区的功能。

    二、设计

    1 根据需求,不宜采用list型分区,万一删除某个Part_ID后忘记了,又按这个Part_ID插入数据,就会产生运行错误。最终采用传统的range型方式。

    2 删除分区没有特别的难度,但在增加分区时,要考虑到如果Part_ID的值如果不比现有分区的range值都大,则不能简单地add分区,而要把某个现有分区进行split。

    3 确定split哪个具体分区时,依据是user_tab_partition视图的high_value字段,但很不幸该字段为long类型,无法直接用在where条件中(报Ora-00997错误),虽然可转换成number型,但过程却十分麻烦(不能直接使用to_number,报Ora-00932错误)。

    4 为此进行一点变通,将该表的分区名设定为:“表名_“||指定位数的PART_ID(这应该也是许许多多表分区名的传统方法),再以user_tab_partition视图的parttion_name进行判断就方便多了。

    三、建表脚本

    --创建表按较固定的范围创建初始分区
    create
    table PART_TAB ( PART_ID int not null, ... primary key (PART_ID, ...) ) PARTITION BY RANGE(PART_ID) ( PARTITION PART_TAB_01 VALUES LESS THAN (2) TABLESPACE ..., PARTITION PART_TAB_02 VALUES LESS THAN (3) TABLESPACE ..., PARTITION PART_TAB_03 VALUES LESS THAN (4) TABLESPACE ..., PARTITION PART_TAB_04 VALUES LESS THAN (5) TABLESPACE ..., PARTITION PART_TAB_05 VALUES LESS THAN (6) TABLESPACE ..., PARTITION PART_TAB_06 VALUES LESS THAN (7) TABLESPACE ..., PARTITION PART_TAB_07 VALUES LESS THAN (8) TABLESPACE ..., PARTITION PART_TAB_08 VALUES LESS THAN (9) TABLESPACE ..., PARTITION PART_TAB_09 VALUES LESS THAN (10) TABLESPACE ..., PARTITION PART_TAB_10 VALUES LESS THAN (11) TABLESPACE ..., );

    四、删除分区脚本

    --存储过程:删除指定分区及数据
    --如果该分区不存在则直接退出
    create or replace procedure DROP_PART(pPartID in number) IS
      cnt       int;
      vPartName varchar2(20);
    BEGIN
      vPartName := 'PART_TAB_' || trim(to_char(pPartID, '09'));
      select count(*) into cnt
        from USER_TAB_PARTITIONS
       where table_name = 'PART_TAB'
         and partition_name = vPartName;
      if cnt >= 1 then
        execute immediate 'alter table PART_TAB DROP PARTITION ' ||
                          vPartName;
      end if;
    END;

    五、增加分区脚本

    --存储过程:增加指定分区
    --如果该分区已存在则直接退出
    create or replace procedure ADD_PART(pPartID in number) IS
      cnt          int;
      vNewPartName varchar2(20);
      vOldPartName varchar2(20);
    BEGIN
      vNewPartName := 'PART_TAB_' || trim(to_char(pPartID, '09'));
      select count(*) into cnt
        from USER_TAB_PARTITIONS
       where table_name = 'PART_TAB'
         and partition_name = vNewPartName;
      if cnt < 1 then
        --如果指定分区不存在,则继续
        select min(partition_name) into vOldPartName
          from USER_TAB_PARTITIONS
         where table_name = 'PART_TAB'
           and partition_name > vNewPartName;
        if vOldPartName is null then
          --仅当新分区的Range值比全部已有分区的Range值时,直接增加分区
          execute immediate 'alter table PART_TAB ADD PARTITION ' ||
                            vNewPartName || ' values less than (' ||
                            to_char(pPartID + 1) || ')';
        else
          --否则,要把最接近的分区按Range值进行split
          execute immediate 'alter table PART_TAB SPLIT PARTITION ' ||
                            vOldPartName || ' AT (' || to_char(pPartID + 1) ||
                            ') into (PARTITION ' || vNewPartName ||
                            ', PARTITION ' || vOldPartName || ')';
        end if;
      end if;
    END;

    PS:脚本没有考虑到表分区在不同表空间的情况(业务需求如此),加上也不难,对表空间名字做个类似限制即可,这里不再展开。

  • 相关阅读:
    prototype的初步理解
    arguemnts的初步理解
    this的初步理解
    js的内存释放初步理解
    私有作用域的初级理解
    预解释的初级理解
    sublime3的安装和插件之类的
    ionic的常用命令总结以及正式发布的准备
    js的DOM的方法和属性总结
    AynsTask1
  • 原文地址:https://www.cnblogs.com/wggj/p/7388370.html
Copyright © 2011-2022 走看看