oracle 数据库通过job定时删除表分区-ok

通过job实现定时去调用一个删除分区的存储过程,完成分区删除。

以下步骤是删除分区的过程,希望能够帮到大家。

测试环境:11.2.0.4
需求:每天1点删除 test_part 表前3天前的分区。

创建测试环境 test_part 表,并插入数据。

drop table scott.test_part purge ;
CREATE TABLE test_part (create_time TIMESTAMP)
PARTITION BY RANGE (create_time) INTERVAL (NUMTODSINTERVAL(1,'DAY')) 
(PARTITION create_time_other  VALUES LESS THAN (TIMESTAMP' 2019-09-01 00:00:00')) ;
insert into scott.test_part values(to_date('2022-07-01 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-02 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-03 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-04 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-05 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-06 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-07 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-08 00:00:00','YYYY-MM-DD HH24:MI:SS'));
insert into scott.test_part values(to_date('2022-07-09 00:00:00','YYYY-MM-DD HH24:MI:SS'));
commit;

收集统计信息

begin
dbms_stats.gather_table_stats(
    ownname        =>'scott',
    tabname        =>'test_part',
    degree        =>4, 
    estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, 
    cascade        =>true,
    method_opt=>'for all columns size AUTO');
end;
/

检查分区信息及分区表的表空间

set lines 200 pages 200
set long 1000
col table_name for a30
col partition_name for a20
col partition_position for 9999
col tablespace_name for a20
col HIGH_VALUE format a85 wrapped
select table_name, partition_position,partition_name,tablespace_name,high_value,num_rows 
from dba_tab_partitions  
where TABLE_OWNER=upper('scott')
and table_name=upper('test_part')
order by partition_position;

TABLE_NAME                     PARTITION_POSITION PARTITION_NAME       TABLESPACE_NAME      HIGH_VALUE                                                                              NUM_ROWS
------------------------------ ------------------ -------------------- -------------------- ------------------------------------------------------------------------------------- ----------
TEST_PART                                       1 CREATE_TIME_OTHER    USERS                TIMESTAMP' 2019-09-01 00:00:00'                                                                0
TEST_PART                                       2 SYS_P863             USERS                TIMESTAMP' 2022-07-02 00:00:00'                                                                1
TEST_PART                                       3 SYS_P864             USERS                TIMESTAMP' 2022-07-03 00:00:00'                                                                1
TEST_PART                                       4 SYS_P865             USERS                TIMESTAMP' 2022-07-04 00:00:00'                                                                1
TEST_PART                                       5 SYS_P866             USERS                TIMESTAMP' 2022-07-05 00:00:00'                                                                1
TEST_PART                                       6 SYS_P867             USERS                TIMESTAMP' 2022-07-06 00:00:00'                                                                1
TEST_PART                                       7 SYS_P868             USERS                TIMESTAMP' 2022-07-07 00:00:00'                                                                1
TEST_PART                                       8 SYS_P869             USERS                TIMESTAMP' 2022-07-08 00:00:00'                                                                1
TEST_PART                                       9 SYS_P870             USERS                TIMESTAMP' 2022-07-09 00:00:00'                                                                1
TEST_PART                                      10 SYS_P871             USERS                TIMESTAMP' 2022-07-10 00:00:00'                                                                1

10 rows selected.

编写删除过程。

--grant select on dba_objects to scoot ;
create or replace procedure table_drop_partition as
    table_owner varchar2(50); --存储拥有者
    table_name varchar2(100); --存储表名
    table_subobject_name varchar2(100); --存储分区表名
    v_SqlExec varchar2(200); --存储拼接后的语句
    cursor fetch_cursor is select owner,object_name,subobject_name,created 
                             from dba_objects 
                            where owner='SCOTT' 
                              and object_type ='TABLE PARTITION'
                              and GENERATED ='Y' --创建表时候创建的第一个分区(GENERATED ='N')是不允许被删除
                              and object_name in('TEST_PART')
                              and created<=TRUNC(SYSDATE+3);
begin
    for get_cursor in fetch_cursor loop
        table_owner:=get_cursor.OWNER;
        table_name:=get_cursor.OBJECT_NAME;
        table_subobject_name:=get_cursor.SUBOBJECT_NAME;
        
        --拼接删除分区语句
        v_SqlExec:='alter table '|| table_owner ||'.'||table_name||' DROP PARTITION '||table_subobject_name;
        
        --打印语句
        DBMS_OUTPUT.PUT_LINE('删除分区'||v_SqlExec);
        
        --执行语句
        execute immediate v_SqlExec;
    end loop;
end;
/

手工调用存储过程

set serveroutput on ;
set lines 200 pages 200 ;
exec table_drop_partition();

输出结果

删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P863
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P864
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P865
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P866
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P867
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P868
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P869
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P870
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P871

PL/SQL procedure successfully completed.

遇到的问题:
如果出现输出结果中有“????????????”,如下:
????????????alter table EHY.EM_REQUESTLOG DROP PARTITION SYS_P812
????????????alter table EHY.EM_REQUESTLOG DROP PARTITION SYS_P813
????????????alter table EHY.EM_REQUESTLOG DROP PARTITION SYS_P814
????????????alter table EHY.EM_REQUESTLOG DROP PARTITION SYS_P815
????????????alter table EHY.EM_REQUESTLOG DROP PARTITION SYS_P816

PL/SQL procedure successfully completed.

解决:设置环境变量,并且客户端工具的字符集也设置为UTF-8后重新创建该存储过就好了
export NLS_LANG=AMERICAN_AMERICA.UTF8

检查分区信息及分区表的表空间

set lines 200 pages 200
set long 1000
col table_name for a30
col partition_name for a20
col partition_position for 9999
col tablespace_name for a20
col HIGH_VALUE format a85 wrapped
select table_name, partition_position,partition_name,tablespace_name,high_value,num_rows 
from dba_tab_partitions  
where TABLE_OWNER=upper('scott')
and table_name=upper('test_part')
order by partition_position;

TABLE_NAME                     PARTITION_POSITION PARTITION_NAME       TABLESPACE_NAME      HIGH_VALUE                                                                              NUM_ROWS
------------------------------ ------------------ -------------------- -------------------- ------------------------------------------------------------------------------------- ----------
TEST_PART                                       1 CREATE_TIME_OTHER    USERS                TIMESTAMP' 2019-09-01 00:00:00'                                                                0

调整存储过程-动态赋值

grant select on dba_objects to scoot ;
create or replace procedure table_drop_partition(table_owner varchar2,table_name varchar2,keep_days in number) as
    --table_owner varchar2(50); --存储拥有者
    --table_name varchar2(100); --存储表名
    table_subobject_name varchar2(100); --存储分区表名
    v_SqlExec varchar2(200); --存储拼接后的语句
    cursor fetch_cursor is select owner,object_name,subobject_name,created 
                             from dba_objects 
                            where owner=upper(table_owner)
                              and object_type ='TABLE PARTITION'
                              and GENERATED ='Y' --创建表时候创建的第一个分区(GENERATED ='N')是不允许被删除
                              and object_name in( upper(table_name) )
                              and created<=TRUNC( SYSDATE + keep_days );
    --v_seg fetch_cursor%rowtype;
    
begin
    for get_cursor in fetch_cursor loop
        --table_owner:=get_cursor.OWNER;
        --table_name:=get_cursor.OBJECT_NAME;
        table_subobject_name:=get_cursor.SUBOBJECT_NAME;
        
        --拼接删除分区语句
        v_SqlExec:='alter table '|| table_owner ||'.'||table_name||' DROP PARTITION '||table_subobject_name;
        
        --打印语句
        DBMS_OUTPUT.PUT_LINE('删除分区'||v_SqlExec);
        
        --执行语句
        execute immediate v_SqlExec;
    end loop;
end;
/

手工调用存储过程

set serveroutput on ;
set lines 200 pages 200 ;
exec table_drop_partition('SCOTT','TEST_PART',5);

输出结果

删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P872
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P873
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P874
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P875
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P876
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P877
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P878
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P879
删除分区alter table SCOTT.TEST_PART DROP PARTITION SYS_P880

PL/SQL procedure successfully completed.

检查分区信息及分区表的表空间

set lines 200 pages 200
set long 1000
col table_name for a30
col partition_name for a20
col partition_position for 9999
col tablespace_name for a20
col HIGH_VALUE format a85 wrapped
select table_name, partition_position,partition_name,tablespace_name,high_value,num_rows 
from dba_tab_partitions  
where TABLE_OWNER=upper('scott')
and table_name=upper('test_part')
order by partition_position;

TABLE_NAME                     PARTITION_POSITION PARTITION_NAME       TABLESPACE_NAME      HIGH_VALUE                                                                              NUM_ROWS
------------------------------ ------------------ -------------------- -------------------- ------------------------------------------------------------------------------------- ----------
TEST_PART                                       1 CREATE_TIME_OTHER    USERS                TIMESTAMP' 2019-09-01 00:00:00'                                                                0

创建job

第一种:使用dbms_job

--调用存储过程:table_drop_partition
var job_num number;
begin
    dbms_job.submit(JOB  => :job_num,
                    WHAT => 'scott.table_drop_partition;',
                    NEXT_DATE => to_date('2022-07-10 01:00:00','yyyy-mm-dd hh24:mi:ss'),
                    INTERVAL =>'TRUNC(sysdate+1)+(1/24)'
                    );
    commit ;
end;
/

--或者调用存储过程:table_drop_partition('SCOTT','TEST_PART',5)
var job_num number;
begin
    dbms_job.submit(JOB  => :job_num,
                    WHAT => 'scott.table_drop_partition('SCOTT','TEST_PART',5);',
                    NEXT_DATE => to_date('2022-07-10 01:00:00','yyyy-mm-dd hh24:mi:ss'),
                    INTERVAL =>'TRUNC(sysdate+1)+(1/24)'
                    );
    commit ;
end;
/

第二种:使用dbms_scheduler

添加定时任务,每天1 点调用。

--调用存储过程:table_drop_partition
BEGIN
 DBMS_SCHEDULER.CREATE_JOB(
   job_name => 'AUTO_DROP_PARTITION_JOB',
   job_type => 'PLSQL_BLOCK',
   job_action => 'table_drop_partition;',
   start_date => to_date('2022-07-10 01:00:00','yyyy-mm-dd hh24:mi:ss'),
   repeat_interval => 'TRUNC(sysdate+1)+1/24');
END;
/

--或者调用存储过程:table_drop_partition('SCOTT','TEST_PART',5)
BEGIN
 DBMS_SCHEDULER.CREATE_JOB(
   job_name => 'AUTO_DROP_PARTITION_JOB',
   job_type => 'PLSQL_BLOCK',
   job_action => 'table_drop_partition('SCOTT','TEST_PART',5);',
   start_date => to_date('2022-07-10 01:00:00','yyyy-mm-dd hh24:mi:ss'),
   repeat_interval => 'TRUNC(sysdate+1)+1/24');
END;
/

检查job是否添加成功

select * from user_scheduler_jobs ;

手工调用job,检查job是否能够调用 delPart 过程,并删除分区。

begin
  dbms_scheduler.run_job('AUTO_DROP_PARTITION_JOB') ;
end;

检查job调用日志

select * from dba_scheduler_job_log where job_name='AUTO_DROP_PARTITION_JOB';

检查分区是否删除。

select OWNER,OBJECT_NAME,SUBOBJECT_NAME,CREATED,created
 from dba_objects 
where owner='SCOTT' 
  and  object_type ='TABLE PARTITION'
  and GENERATED ='Y' 
  and object_name in('TEST_PART')
  and created<=TRUNC(SYSDATE+3);

         


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值