我得到一些奇怪的行为。 我有一个更改表中分区名称的过程。 我创建了一个每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;
我该如何解决这个问题?
答案 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.