Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, PAUL.

Asked: December 13, 2016 - 7:20 pm UTC

Last updated: December 15, 2016 - 4:33 am UTC

Version: 11g

Viewed 1000+ times

You Asked

Hi Chris,

I tried using one of your suggestions as sub-query but seems the " partition for " does not support it.

select partition_name from
( select distinct 'SCHEMA.'||table_name from dba_tab_partitions
where table_owner= 'SCHEMA' and table_name not like 'BIN%' and table_name not like '%$%') partition for (to_date('01-DEC-2016','dd-mon-yyyy'));

and Connor said...

'for partition' only works for reference to the partitioned table itself, eg

select * from MY_PART_TABLE partition for ( to_date(...) );

If you want to get the "last" partition, no matter what the date was, simply get the partition with the highest PARTITION_POSITION column for that table.

If you want to get the partition that spans a particular range of values, then you could write a little plsql routine to help, eg

SQL> create or replace
  2  function par_name_for_val(t varchar2, d date) return varchar2 is
  3    l_hival   varchar2(2000);
  4    l_dte     date;
  5  begin
  6    for i in (
  7         select partition_name,high_value
  8         from   user_tab_partitions
  9         where  table_name  = upper(t)
 10         order by partition_position
 11         )
 12    loop
 13       l_hival := i.high_value;
 14       if l_hival like '%MAXVALUE%' then
 15          l_hival := 'DATE ''9999-01-01''';
 16       end if;
 17
 18       if l_hival like 'TIMESTAMP%' or l_hival like '%DATE%' then
 19          execute immediate 'select '||l_hival||' from dual' into l_dte;
 20          if l_dte > d then
 21             return i.partition_name;
 22          end if;
 23       else
 24          raise_application_error(-20000,'Did not find a date or timestamp string');
 25       end if;
 26    end loop;
 27    raise_application_error(-20000,'Value exceeds last partition');
 28  end;
 29  /

Function created.

SQL> sho err
No errors.
SQL>
SQL> drop table t purge;

Table dropped.

SQL>
SQL> create table t ( x date, y int )
  2  partition by range ( x )
  3  (
  4    partition p1 values less than ( date '2010-01-01'),
  5    partition p2 values less than ( date '2011-01-01'),
  6    partition p3 values less than ( date '2012-01-01'),
  7    partition p4 values less than ( date '2013-01-01'),
  8    partition p5 values less than ( date '2014-01-01'),
  9    partition p6 values less than ( date '2015-01-01'),
 10    partition p7 values less than ( maxvalue)
 11  );

Table created.

SQL>
SQL> select   par_name_for_val('t',date '2012-04-05') from dual;

PAR_NAME_FOR_VAL('T',DATE'2012-04-05')
---------------------------------------------------------------------------------------------
P4

SQL> select   par_name_for_val('t',date '2017-04-05') from dual;

PAR_NAME_FOR_VAL('T',DATE'2017-04-05')
---------------------------------------------------------------------------------------------
P7



You can add or remove functionality depending on your needs

Is this answer out of date? If it is, please let us know via a Comment

More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.