使用11G间隔分区,使用了interval(numtodsinterval(5,'day'))store in (tbs_data1,tbs_data2,.....tbs_data30) 按日期建立了分区,分区是随机分配的,但是怎么找到某个时间段对应的分区名称,以便删除该分区的数据,使空间可以循环利用;怎么找到某个时间段对应的分区呢?
---SYS_P942 对应时间为2016-05-04,查看是否删除分区SYS_P942
alter table my_solgle_table drop partition for(to_date('2016-05-04','yyyy-mm-dd')) update global indexes;
---结果:SYS_P942分区被删除
---删除失败
alter table my_solgle_table drop partition p1;
---执行报错,ORA-14006: invalid partition name
---执行失败
alter table my_solgle_table drop partition p1 update global indexes;
---执行报错:ORA-14758: Last partition in the range section cannot be dropped
---该分区是第一个建立的分区,不能被删除,但可以truncate
---加上update global indexes 可以删除分区了,并同时更新全局索引
alter table my_solgle_table drop partition SYS_P784 update global indexes;
----查询分区创建时间及对应表空间
select a.object_name,subobject_name,object_type,created,high_value,
b.table_name,b.partition_name,b.tablespace_name,partition_position
from user_objects a,
user_tab_partitions b
where a.subobject_name=b.partition_name(+)
and a.object_name=b.table_name(+)
and a.object_name='my_solgle_table'
--and a.subobject_name='SYS_P942'
order by partition_position asc;
----游标处理表分区,使用同类型方式,处理过久的分区,解决高水位问题,该分区内的数据也同样被删除
declare
temp_str varchar2(15);
begin
execute immediate 'alter session set nls_date_format=''yyyy-mm-dd''';
for rec in (select table_name,partition_name,high_value
from user_tab_partitions
where table_name='my_solgle_table')
loop
temp_str := substr(rec.high_value,12,10);
if to_date(temp_str,'yyyy-mm-dd')<sysdate-350 then
--dbms_output.put_line(substr(rec.high_value,12,10));
if upper(rec.partition_name)='P1' then
dbms_output.put_line('alter table my_solgle_table truncate partition '||rec.partition_name||' update global indexes');
execute immediate('alter table my_solgle_table truncate partition '||rec.partition_name||' update global indexes');
else
dbms_output.put_line('alter table my_solgle_table drop partition '||rec.partition_name||' update global indexes');
execute immediate('alter table my_solgle_table drop partition '||rec.partition_name||' update global indexes');
end if;
end if ;
end loop;
exception
when others then
dbms_output.put_line(sqlcode||'--'||sqlerrm);
end;
/
user_tab_partitions的high_value 应该怎么获取时间,这个不同的分区方式,可能还不一样,且这个字段还不好取值,是long类型的...
--定期收集及清楚没有数据的分区,降低高水位。
create or replace procedure proc_trunc_partition
is
type type_cursor is ref cursor;
cur_rs type_cursor;
cur_row temp_user_partition%rowtype;
rs_count number;
begin
--drop table temp_user_partition;
/*
create global temporary table temp_user_partition
(table_name varchar2(50),
partition_name varchar2(30),
high_value clob,
high_value_length number
)
on commit delete rows
nocache;
*/
execute immediate 'insert into temp_user_partition select table_name,partition_name,to_lob(high_value),high_value_length from user_tab_partitions';
open cur_rs for select * from temp_user_partition where rownum<500;
loop
fetch cur_rs into cur_row;
exit when cur_rs%notfound;
if cur_row.high_value_length>0 then
execute immediate 'select count(1) from '||cur_row.table_name|| ' partition ('|| cur_row.partition_name ||')' into rs_count;
if rs_count=0 and lower(cur_row.partition_name)='part_default' then
dbms_output.put_line('alter table '||cur_row.table_name||' truncate partition '||cur_row.partition_name||' update global indexes;');
elsif rs_count=0 and lower(cur_row.partition_name)<>'part_default' then
dbms_output.put_line('alter table '||cur_row.table_name||' drop partition '||cur_row.partition_name||' update global indexes;');
end if;
end if;
end loop;
close cur_rs;
commit;
end;
/