Skip to Main Content

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, roopa.

Asked: January 20, 2017 - 1:39 pm UTC

Last updated: January 23, 2017 - 5:13 pm UTC

Version: 11g

Viewed 1000+ times

You Asked

I want to generate the partition name by querying dba_tab_partitions and drop the oldest partition


declare
part_name varchar2(10);
drop_part varchar2(1000);
begin
select partition_name into part_name from dba_tab_partitions where (table_name='ORDERITEM_TEMP' and rownum=1);
select 'alter table orderitem_temp truncate partition "'
||'part_name'
||'update global indexes'"' into drop_part from dual;
execute immediate drop_part;
end;
/

ERROR MESG---------------------------------------------------------
Error starting at line 2 in command:
declare
myname varchar2(10);
myname2 varchar2(1000);
begin
select partition_name into myname from dba_tab_partitions where (table_name='ORDERITEM_TEMP' and rownum=1);
select 'alter table orderitem_temp drop partition "'
||'myname'
||'update global indexes'"' into myname2 from dual;
execute immediate myname2;
end;
Error report:
ORA-06550: line 8, column 27:
PLS-00112: end-of-line in quoted identifier
ORA-06550: line 8, column 28:
PL/SQL: ORA-00972: identifier is too long
ORA-06550: line 6, column 2:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:


Kindly suggest where I went wrong.

and Chris said...

Your quotes are all messed up. And, as much as I love SQL, there's no reason to "select ... from dual" just to assign a string:

declare 

part_name varchar2(10);
drop_part varchar2(1000);

begin

  select partition_name into part_name from dba_tab_partitions 
 where (table_name='ORDERITEM_TEMP' and rownum=1); 
  drop_part := 'alter table orderitem_temp truncate partition '|| part_name || ' update global indexes';

  execute immediate drop_part;
end;
/


Also: selecting the partition where rownum = 1 is saying "pick a random partition"! Probably not what you want.

Rating

  (2 ratings)

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

Comments

roopa P, January 23, 2017 - 6:48 am UTC

Thank you for your response Chris.. it was very helpful for me...to be frank i am an ameture in pl/sql coding.

can u pls suggest how can I query high_value column to get the oldest partition.
All I want to do is to schedule the script as such it will automatically truncate the oldest partition on quarterly basis.
I have created the table using range partitioning which will create a new partition for every quarter.

roopa B, January 23, 2017 - 1:50 pm UTC

thank you chris.....your suggestion was very helpful for me...

As you said Using rownum I couldn't get the desired results...all I want to do is to schedule a job to truncate the oldest partition on quarterly basis.
I have tried to extract the date from high_value using the script

declare
l_hival varchar2(4000);
l_sql varchar2(4000);
l_high_date date;
l_cursor integer default dbms_sql.open_cursor;
l_rows_back number;
l_oldest varchar2(200);
begin

select high_value
into l_hival
from dba_tab_partitions
where table_name = 'ORDERITEM_TEMP'
and partition_position = 1;

dbms_sql.parse (l_cursor,
'begin :retval := ' || l_hival || '; end;',
dbms_sql.native);

dbms_sql.bind_variable (l_cursor, ':retval', l_high_date);
l_rows_back := dbms_sql.execute (l_cursor);
dbms_sql.variable_value (l_cursor, ':retval', l_high_date);

select to_char(l_high_date, 'yyyy-mm-dd-hh24.mi.ss') into l_oldest from dual;

end;
/

can you suggest how can I do this to all the partitions at one go and find the oldest in them.
Chris Saxon
January 23, 2017 - 5:13 pm UTC

High_value is a LONG, which is a %$*# to query. You can find some approaches discussed at:

https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9532816200346994901