【问题标题】:Oracle automatic partitioning - name pattern for partitionsOracle 自动分区 - 分区的名称模式
【发布时间】:2018-03-09 07:20:38
【问题描述】:

我将使用 Oracle 11g 的自动分区,我想知道是否有任何选项可以指定分区名称特定模式?

例如我有:

create table 
pos_data ( 
   start_date        DATE,
   store_id          NUMBER,
   inventory_id      NUMBER(6),
   qty_sold          NUMBER(3),
) 
PARTITION BY RANGE (start_date) 
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH')) 
(  
   PARTITION pos_data_init VALUES LESS THAN (TO_DATE('01-01-2017', 'DD-MM-YYYY')),
   PARTITION pos_data_201702 VALUES LESS THAN (TO_DATE('01-02-2017', 'DD-MM-YYYY')),
   PARTITION pos_data_201703 VALUES LESS THAN (TO_DATE('01-03-2017', 'DD-MM-YYYY')),
);

我将在 2017 年之前使用 init 分区来保存所有行,然后每个月进行分区。

如何命名自动生成的分区? 是否有机会创建名称结尾为 YYYYMM 的模式?或者我必须稍后重命名这些分区?

【问题讨论】:

  • 您可以使用 PLSQL 和动态 SQL 来归档基于模式的命名
  • 所以只有 scirpt-way 和自动生成的名称只是提高了 part1、part2、part3 等处的值?
  • @Sarpens 如果您使用间隔分区,那么您会被数据库生成的名称所困扰。正如 GurV 建议的那样,如果您需要某种命名模式,那么您将需要编写自己的代码来追溯重命名分区

标签: oracle oracle11g partitioning


【解决方案1】:

不,没有这样的选项允许您为动态创建的分区指定分区名称模式。如果出现这种需要,您可以/应该稍后重命名它们。我个人认为没有必要重命名它们。如果您想为这些自动生成的分区赋予有意义的名称,以便您可以在查询中引用它们,例如:

select *
  from partitioned_table
  partition (part_1);

那么你可以很方便地使用partition for (<<date>>)子句来查询特定的分区,这不需要你知道要查询的分区名称:

select *
  from partitioned_table
  partition for (date '2017-01-01')

【讨论】:

  • 现在我明白了!感谢你的回答!我在这里查看的旧方式分区是使用特定名称模式创建的,只是想知道我是否可以通过自动方式获得相同的结果。新年最良好的祝愿:)
【解决方案2】:

我使用这个过程来重命名调度程序作业每天执行一次的分区:

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 RenamePartitions IS

    ts TIMESTAMP;
    newName VARCHAR2(30);

    CURSOR TabPartitions IS
    SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
    FROM USER_TAB_PARTITIONS 
    WHERE TABLE_NAME IN ('YOUR_TABLE', ...)
        AND PARTITION_NAME <> 'P_INITIAL'
    ORDER BY 1,2;

BEGIN

    EXECUTE IMMEDIATE 'ALTER SESSION SET DDL_LOCK_TIMEOUT = 180';

    FOR aPart IN TabPartitions LOOP
        EXECUTE IMMEDIATE 'BEGIN :ret := '||aPart.HIGH_VALUE||'; END;' USING OUT ts;
        IF DailyPartition(aPart.TABLE_NAME) THEN            
            ts := ts - INTERVAL '1' DAY;
            newName := 'P_'||TO_CHAR(ts,'yyyy_mm_dd');
        ELSE
            ts := ADD_MONTHS(ts, -1);
            newName := 'P_'||TO_CHAR(ts,'yyyy_mm');
        END IF;
        IF aPart.PARTITION_NAME <> newName THEN             
            EXECUTE IMMEDIATE 'ALTER TABLE '||aPart.TABLE_NAME||' RENAME PARTITION '||aPart.PARTITION_NAME||' TO '||newName;
        END IF;
    END LOOP;

END RenamePartitions;

【讨论】:

    猜你喜欢
    • 2020-07-11
    • 1970-01-01
    • 2014-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多