oracle调度程序重命名间隔分区

时间:2013-02-14 13:39:38

标签: oracle dbms-scheduler

我得到一些奇怪的行为。 我有一个更改表中分区名称的过程。 我创建了一个每2分钟运行一次这个程序的工作进行测试。 第一次运行非常顺利,到目前为止没有任何错误。 但是,从第二轮开始我得到以下错误

"ORA-00054: resource busy and acquire with NOWAIT  specified or timeout expired
       ORA-06512: at "CDS_USER.RENAMING_PARTITIONS", line 17"

是的,我的桌子是现场的。但是当我使用调度程序显式运行我的程序时,它运行得非常好。没问题。调度程序的每次运行都是完美的。

以下是调度程序的代码

    begin
    bms_Scheduler.create_job(
    job_name => 'drop_user1' ,
    job_action => 'RENAMING_PARTITIONS' 
    job_action => 'DROP_PARTITIONS' 
    ,start_date => SYSDATE ,
     repeat_interval => 'freq=hourly;INTERVAL=7',bysecond=0;' ,
     enabled => TRUE ,
     comments => 'schduling drop job.');
     END; 

以下是程序代码

     create or replace PROCEDURE RENAMING_PARTITIONS
   AS
   hv varchar2(9);
   max_part VARCHAR2(9);
   begin
   select  max(partition_position)  into max_part from user_tab_partitions where  table_name='DEMO'; 
  for x in (select partition_name, high_value, partition_position
          from user_tab_partitions
          where table_name = 'DEMO' and partition_name  like 'SYS%')
 loop
 if x.partition_position  <> max_part THEN

       execute immediate 'select to_char('||x.high_value||'-1,''YYYYMMDD'') from dual' into hv;
partition '||x.partition_name
                   --||' to DATE_'||hv);
       execute immediate('alter table DEMO rename partition '||x.partition_name
                  ||' to DATE_'||hv);   
end if;
end loop;   
 end;

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

不要这样做。我知道Oracle不会遵循系统创建的间隔分区的预定义分区命名方案(可能是未来的增强),但是每隔2分钟更改一次表不是一个好的选择。

幸运的是,在查询中指定分区名称时,您实际上只需要事先知道分区名称。典型的查询类似于:

select * from my_table partition (blah);

在11g中,您可以使用“partition for”子句来解决系统生成的名称,如下所示(区间DATE分区的示例):

SQL> set display on
SQL> set linesize 200
SQL> drop table test_data
Table dropped.
SQL> create table test_data (
   start_date        DATE,
   store_id          NUMBER,
   inventory_id      NUMBER,
   qty_sold          NUMBER
)
PARTITION BY RANGE (start_date)
INTERVAL(NUMTOYMINTERVAL(1, 'MONTH'))
(
   PARTITION part_01 values LESS THAN (TO_DATE('20130101','YYYYMMDD'))
)
Table created.
SQL> insert into test_data values (to_date('20121231', 'YYYYMMDD'), 1, 2, 1)
1 row created.
SQL> commit
Commit complete.
SQL> SELECT table_name, partition_name, high_value
FROM   user_tab_partitions
WHERE table_name = 'TEST_DATA'
ORDER BY table_name, partition_name

TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE                                        
------------------------------ ------------------------------ --------------------------------------------------
TEST_DATA                      PART_01                        TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
                                                              MI:SS', 'NLS_CALENDAR=GREGORIAN')                 

1 row selected.
SQL> insert into test_data values (to_date('20130101', 'YYYYMMDD'), 1, 5, 8)
1 row created.
SQL> insert into test_data values (to_date('20130115', 'YYYYMMDD'), 2, 4, 5)
1 row created.
SQL> insert into test_data values (sysdate, 2, 3, 2)
1 row created.
SQL> commit
Commit complete.
SQL> SELECT table_name, partition_name, high_value
FROM   user_tab_partitions
WHERE table_name = 'TEST_DATA'
ORDER BY table_name, partition_name

TABLE_NAME                     PARTITION_NAME                 HIGH_VALUE                                        
------------------------------ ------------------------------ --------------------------------------------------
TEST_DATA                      PART_01                        TO_DATE(' 2013-01-01 00:00:00', 'SYYYY-MM-DD HH24:
                                                              MI:SS', 'NLS_CALENDAR=GREGORIAN')                 

TEST_DATA                      SYS_P67                        TO_DATE(' 2013-02-01 00:00:00', 'SYYYY-MM-DD HH24:
                                                              MI:SS', 'NLS_CALENDAR=GREGORIAN')                 

TEST_DATA                      SYS_P68                        TO_DATE(' 2013-03-01 00:00:00', 'SYYYY-MM-DD HH24:
                                                              MI:SS', 'NLS_CALENDAR=GREGORIAN')                 


3 rows selected.
SQL> -- get data for January partition only
SQL> select * from test_data partition for (to_date('20130101', 'YYYYMMDD'))

START_DATE    STORE_ID INVENTORY_ID   QTY_SOLD
----------- ---------- ------------ ----------
01-JAN-2013          1            5          8
15-JAN-2013          2            4          5

2 rows selected.