我有一个包含几百个分区的表格,我通常对最新的35个分区感兴趣。
因此,我正在尝试创建可以动态访问这些视图的视图。即始终使用最新的情况。
查询:
select PARTITION_NAME,
PARTITION_POSITION,
NUM_ROWS,
AVG_ROW_LEN
from all_tab_partitions
where
table_name = 'MY_TABLE'
AND PARTITION_NAME <> 'P_LAST'
AND PARTITION_POSITION < (SELECT MAX(PARTITION_POSITION)
FROM all_tab_partitions) - 35
order by 2 DESC
;
似乎要回复我感兴趣的分区名称,但是,我没有设法使用它的结果来选择分区。 e.g:
CREATE OR REPLACE VIEW MY_VIIEW AS
WITH t AS ( [Above query] )
SELECT * FROM
MY_TABLE PARTITION (SELECT /*+ FIRST_ROWS(1) */ PARTITION_NAME
from t);
(不是实际视图,只是一个例子)
那我该怎么做?如何创建一个始终是最新分区的视图(&#34; MAX&#34; execpt)?
我正在使用Oracle 10g
感谢
答案 0 :(得分:4)
您只能使用PL / SQL
create or replace package my_table_ is
type t_records is table of my_table%rowtype;
function getpart(c_parts sys_refcursor) return t_records pipelined;
end;
create or replace package body my_table_ is
function getpart(c_parts sys_refcursor) return t_records pipelined is
v_partition all_tab_partitions.partition_name%type;
v_row my_table%rowtype;
c_mytab sys_refcursor;
begin
loop
fetch c_parts into v_partition;
exit when c_parts%notfound;
open c_mytab for 'select * from my_table partition ('||v_partition||')';
loop
fetch c_mytab into v_row;
exit when c_mytab%notfound;
pipe row (v_row);
end loop;
end loop;
end;
end;
现在你可以
select * from table(my_table_.getpart(cursor(<QUERY_RETURNING_PARTITION_NAMES>)));
答案 1 :(得分:3)
您可以在每个语句中使用一批具有分区名称的union all语句来构造视图查询,例如
create view p as
select * from my_table partition (part1)
union all
select * from my_table partition (part1)
...
union all
select * from my_table partition (part35)
答案 2 :(得分:3)
好的......我不认为您可以使用分区名称,但您可以使用分区的起始值来选择与这些分区匹配的数据...
所以你看起来像这样:
SELECT * FROM my_table WHERE date_col > get_part_limit( 'my_table', 35 ):
其中date_col是您用于分区的列 - 而get_part_limit是您编写的存储函数,如下所示:
...
BEGIN
SELECT high_value FROM all_tab_partitions
INTO local_var
WHERE table_name = parameter_name
AND PARTITION_POSITION = MAX... - 35
EXECUTE IMMEDIATE 'SELECT '||local_var||' FROM DUAL' INTO local_return_value;
RETURN local_return_value;
END;
答案 3 :(得分:2)
分区设计为对数据透明,因此当您编写查询时,您根本不知道数据的存储方式。
我看到只有一种可能性命中特定分区:WHERE子句应该匹配最新(或最新5)分区的分区列的值。
接下来的问题是动态构建这个WHERE子句。您已经知道oracle词典中有大量信息。因此,您将阅读该内容并创建一个构造函数,以将元数据条件转换回SQL。
答案 4 :(得分:1)
irl我们做同样的事情并使用falco的解决方案。 这是我的代码:
create or replace function longToDate( myOwner varchar2,
mytable_name in varchar2,
mypartition_name in varchar2
) return date
as
cDate date;
cvar varchar2(1024);
rq varchar2(1024);
infiniteValue EXCEPTION;
PRAGMA EXCEPTION_INIT(infiniteValue, -00904);
begin
select high_value into cvar FROM dba_tab_partitions t where t.table_owner=myOwner and table_name=mytable_name and partition_name=mypartition_name;
rq:='select '||cvar||' from dual';
execute immediate rq into cDate;
return cdate;
EXCEPTION
WHEN infiniteValue
then return'01 jan 3000';
when others
then return null;
end longToDate;
Ant视图是这样的
create or replace view last_35 as
with maxdate as
(select longToDate(p.table_owner,p.table_name,p.partition_name) mydate,
rank()over(order by p.partition_position desc) mypos,
p.* from all_tab_partitions p
where p.table_name='MY_TABLE'
)
select /*+full(a)*/* from MY_TABLE a, maxdate
where MY_TABLE.partition_name>maxdate.mydate
and maxdate.mypos=35