从Oracle数据库的所有表中的所有子分区中提取第一行

时间:2015-04-23 15:37:31

标签: sql database oracle plsql partitioning

我想获取Oracle数据库中所有表的所有子分区的第一个值。 从我的结果集中,我想用返回的值更新另一个表,并为空的子分区插入注释(例如“No value”)。

我已经编写了一段代码,以一个表开头。 你能告诉我我使用的算法是否正确以及为什么没有输出?

DECLARE

BEGIN


for i in (select table_name, subpartition_name
from dba_tab_subpartitions
where table_name ='my_table'
order by 1)

loop

execute immediate ' insert into bkp_part (partition_name) values('||i.subpartition_name||')';

commit;

execute immediate 'select *
from '|| i.table_name||' subpartition('||i.subpartition_name||')
where rownum < 2';

end loop;

end;


END;
/

1 个答案:

答案 0 :(得分:0)

没有输出,因为您没有创建任何输出。您的动态查询不会被执行,因为您没有选择任何列;如果你真的想要整个行,你需要一个%rowtype变量来选择,但我不确定你是否真的需要整行或只需要一个值。选择了某些内容之后,您需要使用该变量 - 将其放入您所说的表格中,或通过dbms_output显示调试版本。

您的插入语句不需要是动态的;你可以这样做:

insert into bkp_part (partition_name) values (i.subpartition_name);

要获得每个子分区的第一行,您需要通过“first”确定您的意思。在这个例子中我使用了一个哈希子分区,所以为了参数,我将决定'first'行是该哈希桶中的最低值,为了保持简单,我只对那一列感兴趣

我已经设置了一个虚拟表:

create table my_table (id number, part_date date)
partition by range (part_date)
subpartition by hash (id)
subpartition template (
  subpartition subpart_1,
  subpartition subpart_2,
  subpartition subpart_3)
(
  partition part_1 values less than (date '2015-01-01')
);

insert into my_table values (1, date '2014-12-29');
insert into my_table values (2, date '2014-12-30');
insert into my_table values (4, date '2014-12-31');

看看数据是如何分配的,我在第一个子分区中没有任何内容,第二个分区中的ID 1和4以及第三个分区中的ID 2。

这意味着我可以做到:

set serveroutput on
declare
  l_id my_table.id%type;
begin
  for i in (
   select table_name, subpartition_name
   from user_tab_subpartitions
    where table_name = 'MY_TABLE'
    order by table_name, subpartition_position
  ) loop

    -- skipping because I don't have that table
    -- insert into bkp_part (partition_name) values (i.subpartition_name);

    execute immediate 'select min(id) from ' || i.table_name
      || ' subpartition(' || i.subpartition_name || ')'
      into l_id;

    -- just for debugging/demo
    dbms_output.put_line('Subpartition ' || i.subpartition_name
      || ' minimum ID is ' || l_id);

    -- do something else with the value; update or insert...
    -- update bkp_part set min_id = l_id
    -- where partition_name = i.subpartition_name;
  end loop;
end;
/

anonymous block completed
Subpartition PART_1_SUBPART_1 minimum ID is 
Subpartition PART_1_SUBPART_2 minimum ID is 1
Subpartition PART_1_SUBPART_3 minimum ID is 2

您可以调整它以获取您感兴趣的列并对它们执行更有用的操作(例如插入/更新bkp_part表)