范围分区的自动分区命名

automatic partition naming for range partitioning

我有一个table这样的

CREATE TABLE data_audit(
    id_col     NUMBER(*,0)   NOT NULL ENABLE,
    col_2      VARCHAR2(10)  NOT NULL ENABLE,
    col_3      NUMBER(*,0)   NOT NULL ENABLE,
    col_4      VARCHAR2(10)  NOT NULL ENABLE,
    col_5      VARCHAR2(10)  NOT NULL ENABLE,
    created_at TIMESTAMP (3) DEFAULT current_timestamp,
    CONSTRAINT DATA_AUDIT_PK PRIMARY KEY (col_2,col_3,col_4)
 USING INDEX ENABLE
)
 PARTITION BY RANGE(created_at)
(
   PARTITION p2022_jan
      VALUES LESS THAN (TO_DATE('01-jan-2022')),
   PARTITION p2022_feb
      VALUES LESS THAN (TO_DATE('01-feb-2022')),
   PARTITION p2022_mar
      VALUES LESS THAN (TO_DATE('01-mar-2022'))
)

此处 - 在上面的示例中 - 我需要在 DDL

中明确提及该名称

我想为每个月的数据自动创建新分区 我怎样才能实现它自动命名 - 我可以使用任何随机的分区名称

我正在使用 oracle - Oracle Database 19c Enterprise Edition Release 19.0.0.0

假设table只有第一个分区(p2022_jan),每个月都会向table添加新的分区,那么首先创建一个存储过程,例如

CREATE OR REPLACE PROCEDURE Pr_Add_Part_to_Data_Audit is
  v_ddl       VARCHAR2(32767);
  v_date      DATE := TO_DATE(TO_CHAR(sysdate,'yyyy-mm-')||'01','yyyy-mm-dd');  
BEGIN 
  v_ddl :='ALTER TABLE data_audit ADD PARTITION p'||TO_CHAR(v_date,'yyyy')||'_'||TO_CHAR(v_date,'mon')||' VALUES LESS THAN ('''||v_date||''')';
  EXECUTE IMMEDIATE v_ddl;
END;
/

然后,在接下来的几个月开始时从调度程序调用它,例如

DECLARE
  v_job_name VARCHAR2(32) := 'jb_add_part_data';
BEGIN
  DBMS_SCHEDULER.CREATE_JOB(job_name        => v_job_name,
                            job_type        => 'STORED_PROCEDURE',
                            job_action      => 'Pr_Add_Part_to_Data_Audit',
                            start_date      => TO_DATE('01-02-2021 01:00:10',
                                                       'DD-MM-YYYY HH24:MI:SS'),
                            repeat_interval => 'FREQ=MONTHLY; BYHOUR=1;',
                            auto_drop       => false,
                            comments        => 'Adds a new partition every month');

  DBMS_SCHEDULER.ENABLE(v_job_name);
END;
/  

我建议使用 INTERVAL 分区而不是 RANGE 分区:

CREATE TABLE DATA_AUDIT (
    id_col NUMBER(*,0) NOT NULL ENABLE,
    col_2 VARCHAR2(10) NOT NULL ENABLE,
    col_3 NUMBER(*,0) NOT NULL ENABLE,
    col_4 VARCHAR2(10) NOT NULL ENABLE,
    col_5 VARCHAR2(10) NOT NULL ENABLE,
    CREATED_AT TIMESTAMP (3) default current_timestamp ,
    CONSTRAINT DATA_AUDIT_PK PRIMARY KEY (col_2,col_3,col_4) USING INDEX  ENABLE
)
 partition by range (CREATED_AT) INTERVAL (INTERVAL '1' MONTH)
(PARTITION p2021_dec VALUES LESS THAN (TIMESTAMP '2022-01-01 00:00:00')); 

然后 Oracle 将每月自动创建新分区。

对于重命名,您可以按照 Barbaros Özhan 的建议通过每日调度程序作业运行此过程。

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 = 'DATA_AUDIT'
    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;
        ts := ADD_MONTHS(ts, -1);
        newName := 'p'||TO_CHAR(ts,'yyyy_mon', 'NLS_DATE_LANGUAGE = american');
        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;

或查看更通用的:

这里 Wernfried Domscheit 给出的答案是正确的

感谢您的回答 - 它显示了控制分区名称的方式 - 在我的例子中我不需要关心分区名称 - 我只需要确保 - 新分区是用新名称创建的 - 所以我使用了你评论的前半部分 -

验证它 - 我将它用于 DAY - 分区

CREATE TABLE DATA_AUDIT (
    id_col NUMBER(*,0) NOT NULL ENABLE,
    col_2 VARCHAR2(10) NOT NULL ENABLE,
    col_3 NUMBER(*,0) NOT NULL ENABLE,
    col_4 VARCHAR2(10) NOT NULL ENABLE,
    col_5 VARCHAR2(10) NOT NULL ENABLE,
    CREATED_AT TIMESTAMP (3) default current_timestamp ,
    CONSTRAINT DATA_AUDIT_PK PRIMARY KEY (col_2,col_3,col_4) USING INDEX  ENABLE
)
 partition by range (CREATED_AT) INTERVAL (INTERVAL '1' DAY)
(PARTITION p2021_dec VALUES LESS THAN (TIMESTAMP '2022-01-01 00:00:00')); 

然后它创建了像

这样的分区
partition name -    table name
P2021_DEC     -   DATA_PURGE_AUDIT
SYS_P8592     -     DATA_PURGE_AUDIT