如何每天截断oracle创建的分区

问题描述 投票:0回答:1

我也为该分区创建了一个表,我也创建了该分区,并给了我提到的那个范围(1,'day')。.oracle每天为该表创建一个分区..我的项目与银行域..so到该表中记录了许多交易,因此银行团队要求每天截断该分区。当前的分区不应截断,而应该截断前一天的分区,有什么办法可以解决这个问题,请让我知道...删除正在产生碎片,因此他们要求截断或删除。

partitioning
1个回答
0
投票

欢迎您!请参见下面的基本示例,该示例根据传递的日期从间隔分区表中截断/删除先前的分区。注意:您可能需要根据特定的数据加载行为和要求进一步进行微调,以适应各种情况和边缘情况。为了说明起见,我正在创建一个具有以下间隔分区的示例表...

create table testpart
(  value_date date  )
partition by range ( value_date )
interval ( NUMTODSINTERVAL(1,'day') )
( partition p1 values less than ( date '2020-01-01' ));

正在检查新创建的表上的默认分区..

select table_name, partition_name, interval from dba_tab_partitions where table_name = 'TESTPART';

|TABLE_NAME  |PARTITION_NAME    |INTERVAL |
|TESTPART    |P1                |NO       |  

插入数据的当前日期(例如4月16日)和上一个日期(4月15日)..

insert into testpart select date '2020-04-15' from dual;
insert into testpart select date '2020-04-16' from dual;
commit;

正在检查插入的数据..

select * from testpart;

| VALUE_DATE |
| 4/15/2020  |
| 4/16/2020  |

检查自动创建的间隔分区以及转换为日期格式的高值(注释旁边提到的解释)...注意:我已经改编自this SO上的逻辑

select 
table_name,
partition_name,
to_date ( -- convert to date datatype
          trim ( -- trim whitespaces
          '''' from regexp_substr ( 
                     extractvalue ( -- return scalar value of the single text node viz., high_value
                       dbms_xmlgen.getxmltype ( -- converts the results of a SQL query into XML format
                       'select high_value from all_tab_partitions where table_name='''
                                || table_name
                                || ''' and partition_name = '''
                                || partition_name
                                || ''''),
                             '//text()'),
                          '''.*?''')), -- regex pattern matching to fetch value between the first set of quotes
          'syyyy-mm-dd hh24:mi:ss')
          high_value_in_date_format
  FROM all_tab_partitions
 WHERE table_name = 'TESTPART' 
;

|TABLE_NAME |PARTITION_NAME |HIGH_VALUE_IN_DATE_FORMAT  |
|TESTPART   |SYS_P9064429   |4/17/2020                  |
|TESTPART   |SYS_P9064428   |4/16/2020                  |
|TESTPART   |P1             |1/1/2020                   |

创建一个接受日期并将其与high_value匹配的过程,以标识指定表中紧接在前的分区,并截断/删除该分区...

create or replace procedure int_part_housekeeping
    ( p_date        date,
      p_table_name  varchar2
    )
as
    l_part_name     varchar2(30);
begin

    -- identifying partition based on high value in all_tab_partitions 
    select partition_name
    into l_part_name
    from all_tab_partitions
    where table_name = p_table_name
    and  
       to_date ( -- convert to date datatype
          trim ( -- trim whitespaces
          '''' from regexp_substr ( 
                     extractvalue ( -- return scalar value of the single text node
                       dbms_xmlgen.getxmltype ( -- converts the results of a SQL query into XML format
                       'select high_value from all_tab_partitions where table_name='''
                                || table_name
                                || ''' and table_owner = '''
                                || table_owner
                                || ''' and partition_name = '''
                                || partition_name
                                || ''''),
                             '//text()'),
                          '''.*?''')), -- regex pattern matching to fetch value between the first set of quotes
          'syyyy-mm-dd hh24:mi:ss') = p_date
    ;

    -- truncating preceding partition
    dbms_output.put_line('Trucating partition for preceding interval partition :' || l_part_name );    
    execute immediate 'ALTER TABLE ' || p_table_name || ' TRUNCATE PARTITION (' || l_part_name || ')';

    -- dropping preceding partition (note: interval needs to be reset before and after the drop operation)
    dbms_output.put_line('Dropping partition for preceding interval partition :' || l_part_name); 
    execute immediate 'ALTER TABLE ' || p_table_name || ' SET INTERVAL ()';
    execute immediate 'ALTER TABLE ' || p_table_name || ' DROP PARTITION (' || l_part_name || ')';
    execute immediate 'ALTER TABLE ' || p_table_name || ' SET INTERVAL ( NUMTODSINTERVAL(1,''day'') )';

exception 
    when others then
    dbms_output.put_line(sqlerrm);
    raise;
end;

执行通过当前日期和表名的过程..

set serveroutput on;
begin
    int_part_housekeeping(date'2020-04-16','TESTPART');
end;

Output:
Trucating partition for preceding interval partition :SYS_P9064428
Dropping partition for preceding interval partition :SYS_P9064428
 PL/SQL procedure successfully completed.

使用先前的select语句检查是否删除了所需的分区...

|TABLE_NAME |PARTITION_NAME |HIGH_VALUE_IN_DATE_FORMAT  |
|TESTPART   |SYS_P9064429   |4/17/2020                  |
|TESTPART   |P1             |1/1/2020                   |

然后您可以按需执行此过程,或使用dbms调度程序在特定时间运行。

如果这符合您的要求,请随时使用acceptvote

© www.soinside.com 2019 - 2024. All rights reserved.