how to get names of partition in oracle while i input a date

本小妞迷上赌 提交于 2021-02-07 03:22:27

问题


I have a table with many partitions range. I need to get the name of all partition when I give a date. For eg: if I input date 20/09/2014, it should list all partitions before that given date.

create or replace function get_part_name(p_date in date)
return varchar2 is
d date;
retp varchar2(30);
mind date:=to_date('4444-01-01','yyyy-mm-dd');
str varchar2(32000);
cursor c is
select high_value, partition_name p
  from user_tab_partitions
 where table_name='TEST';
begin
  for r in c loop
     str := r.high_value;
     execute immediate 'select '||str||' from dual' into d;     
     if p_date<d and d<mind then
        retp:=r.p;
        mind:=d;
     end if;
  end loop;
  return retp;
end;

This is returing a single date. I need all the dates, is it possible?


回答1:


WITH DATA AS (
select table_name,
       partition_name,
       to_date (
          trim (
          '''' from regexp_substr (
                     extractvalue (
                       dbms_xmlgen.getxmltype (
                       'select high_value from all_tab_partitions where table_name='''
                                || table_name
                                || ''' and table_owner = '''
                                || table_owner
                                || ''' and partition_name = '''
                                || partition_name
                                || ''''),
                             '//text()'),
                          '''.*?''')),
          'syyyy-mm-dd hh24:mi:ss')
          high_value_in_date_format
  FROM all_tab_partitions
 WHERE table_name = 'SALES' AND table_owner = 'SH'
 )
 SELECT * FROM DATA
   WHERE high_value_in_date_format < SYSDATE
/

TABLE_NAME           PARTITION_NAME       HIGH_VALU
-------------------- -------------------- ---------
SALES                SALES_Q4_2003        01-JAN-04
SALES                SALES_Q4_2002        01-JAN-03
SALES                SALES_Q4_2001        01-JAN-02
SALES                SALES_Q4_2000        01-JAN-01
SALES                SALES_Q4_1999        01-JAN-00
SALES                SALES_Q4_1998        01-JAN-99
SALES                SALES_Q3_2003        01-OCT-03
SALES                SALES_Q3_2002        01-OCT-02
SALES                SALES_Q3_2001        01-OCT-01
SALES                SALES_Q3_2000        01-OCT-00
SALES                SALES_Q3_1999        01-OCT-99
SALES                SALES_Q3_1998        01-OCT-98
SALES                SALES_Q2_2003        01-JUL-03
SALES                SALES_Q2_2002        01-JUL-02
SALES                SALES_Q2_2001        01-JUL-01
SALES                SALES_Q2_2000        01-JUL-00
SALES                SALES_Q2_1999        01-JUL-99
SALES                SALES_Q2_1998        01-JUL-98
SALES                SALES_Q1_2003        01-APR-03
SALES                SALES_Q1_2002        01-APR-02
SALES                SALES_Q1_2001        01-APR-01
SALES                SALES_Q1_2000        01-APR-00
SALES                SALES_Q1_1999        01-APR-99
SALES                SALES_Q1_1998        01-APR-98
SALES                SALES_H2_1997        01-JAN-98
SALES                SALES_H1_1997        01-JUL-97
SALES                SALES_1996           01-JAN-97
SALES                SALES_1995           01-JAN-96

28 rows selected.

SQL>

Use your desired date in place of SYSDATE in above query. Or you can pass it as INPUT through the FUNCTION and RETURN the result set.




回答2:


Find Partition name using date IF you have a meaningful date column in the table in Oracle DB

WITH table_sample AS (select COLUMN_WITH_DATE from table SAMPLE (5))

SELECT uo.SUBOBJECT_NAME AS "PARTITION_NAME_1" FROM table_sample sw,
SYS.USER_OBJECTS uo
WHERE sw.COLUMN_WITH_DATE = TRUNC(SYSDATE) -- ENTER DATE HERE AS 'DD-MM-YYYY 00:00:00'
AND OBJECT_ID = dbms_rowid.rowid_object(sw.rowid)
AND ROWNUM < 2;




回答3:


Single SQL Solution: (high_value has to converted to date with correct format!)

SELECT
 partition_name p
  from user_tab_partitions
 where table_name='TEST'
 AND high_value < to_date('4444-01-01','yyyy-mm-dd') AND high_value > SYSDATE;

PL/SQL Solution:

Create a global type;

create type ty_partition_names is table of varchar2(30);
/

Function:

create or replace function get_part_name(p_date in date)
return ty_partition_names is
d date;
retp ty_partition_names := ty_partition_names();
mind date:=to_date('4444-01-01','yyyy-mm-dd');
str varchar2(32000);
idx number := 0;
cursor c is
select high_value, partition_name p
  from user_tab_partitions
 where table_name='test';
begin
  for r in c loop
     str := r.high_value;
     /*execute immediate 'select '||str||' from dual' into d;     */
     if p_date<str and str <mind then
        retp.extend(1);
        idx := idx + 1;
        retp(idx):=r.p;
        mind:=str;
     end if;
  end loop;
  return retp;
end;

And Finally,

SELECT * FROM TABLE(get_part_name(sysdate));



回答4:


I know this issue is old, but I ran across it looking for something and thought I'd weigh in to prevent others from going down the road above.The answers provided make it way more difficult than it has to be. You can use the dbms_rowid.rowid_object() to get the data object id of the row and join that with either user_objects, all_objects or dba_objects (whichever fits your needs).

Something like this should work ...

select distinct 
       o.subobject_name
  from user_objects o,
       my_table x
 where o.object_name = 'MY_TABLE'
   and dbms_rowid.rowid_object( x.rowid ) = o.data_object_id
   and trunc( x.stamp ) > ( current_timestamp - 31 );

I use this for code that has to determine partition names, for various reasons (queries, DML, etc...). I even used this very recently identify the partitions which have fallen outside of a defined window, as an auto-drop feature for an interval partitioned table.



来源:https://stackoverflow.com/questions/26399000/how-to-get-names-of-partition-in-oracle-while-i-input-a-date

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!