以下语句允许我检索有关表分区的信息:
select table_name, partition_name, high_value from user_tab_partitions where table_name = 'T1';
问题在于,由于某些未知原因,high_value列的值表示为:
TO_DATE(' 2015-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
可以将它们作为日期检索吗?或者至少在表达式上做“eval”这样的事情?
答案 0 :(得分:2)
该字段被定义为long类型,因此根据分区方案,它可以包含各种值(类似于' ABC',数字123,日期的字符串表示,等等) 。
无论如何,听起来你想要从特定分区获取数据,并且你正试图从元数据中找出分区名称。如果是这种情况,您只需使用partition for子句:
select * from my_partitioned_table partition for (to_date('20150801', 'YYYYMMDD'));
哪个会从特定日期的分区中选择数据(假设您按日期分区)。这在间隔分区中特别有用,在这种情况下,Oracle会分配像SYS_xxxx这样的分区名称,这些名称看起来是任意的。
如果你想删除比给定日期更早的分区,那就有点棘手了。上面的语法用于选择数据,而不是DDL(alter table)。要做到这一点,你可以做这样的事情(经过严格测试):
创建一个函数来识别哪些分区包含日期小于给定参考日期的数据:
create or replace function fn_partition_is_earlier(i_part_tab_name varchar2, i_partition_position number, i_ref_date in date)
return number
is
l_date_str varchar2(2000);
l_date date;
begin
execute immediate 'select high_value from all_tab_partitions where table_name = :tab and partition_position = :pos'
into l_date_str
using i_part_tab_name, i_partition_position;
execute immediate 'select ' || l_date_str || ' from dual' into l_date;
if (l_date < i_ref_date) then
return 1;
end if;
return 0;
end;
使用以下功能:
with part_name as (
select partition_name
from (
select fn_partition_is_earlier(p.table_name, p.partition_position, to_date('20130501', 'YYYYMMDD')) should_drop_flag, p.*
from all_tab_partitions p
where table_name = 'MY_TAB'
)
where should_drop_flag = 1
)
select 'alter table MY_TAB drop partition ' || part_name.partition_name || ' update global indexes;'
from part_name;
输出会为您提供DBA运行时间的脚本。
希望有所帮助。