需要删除超过三天的表

时间:2013-07-27 12:26:31

标签: oracle plsql

我对Oracle PL / SQL数据库应用程序的开发非常陌生......我有一个客户要求,我们为他们创建了一个ETL,它删除了前几天的表。该表是使用同义词创建的,它需要一个时间戳来创建表,例如:TEST_TEST_todaysdate

现在他们想改变ETL并且不想放弃前几天的表,而是他们希望保留三天的数据,并且在第四天......程序应该删除最后几天作为循环使表保留最后三天!我希望你们能得到我,但就像这样 - 从星期一到星期三,星期四然后删除星期一,星期五然后删除星期二等等。

以下是代码段:

   -- check &&1..&&3._&&2
   select count(*)
   into v_exist
   from all_tables
   where owner = upper('&&1')
   and   table_name = upper('&&3._&&2');

   if v_exist > 0 then
      for r in (select owner,table_name
                from all_tables
                where  owner = upper('&&1')
                and    table_name like upper('&&3%')  --- exclude MASTER_* tables
                and    table_name <>  upper('&&3')    --- just for precaution

这是我的代码:

and    table_name = start_day DATE as ((SELECT extract(hour from current_timestamp)) - 4 FROM dual
  --and    table name =' || previous_days_table ||' -- saving previous days table
                and    table_name < upper('&&3._&&2')) loop
          v_sql := 'DROP TABLE ' || r.owner || '.' || r.table_name || ' CASCADE CONSTRAINTS PURGE';
          dbms_output.put_line(v_sql);
          execute immediate v_sql;
      end loop;
   end if;
EXCEPTION
        WHEN OTHERS THEN
                RAISE;
END;

1 个答案:

答案 0 :(得分:2)

有两种方法可以做到这一点;第一个是基于你自己的日期戳;表创建日期的第二个。

假设您的日期戳格式为YYYYMMDD,我会这样做:

begin

   for xx in ( select owner, table_name
                 from all_tables
                where regexp_like(table_name, 'TEST_TEST_[[:digit:]]{8}')
                  and to_date(substr(table_name, -8), 'yyyymmdd') < trunc(sysdate) - 4
                  and owner = 'THE_OWNER'
                      ) loop

      execute immediate 'drop table ' ||
                          xx.owner || '.' ||
                          xx.table_name ||
                          ' purge';

   end loop;

end;
/

基本上,所有这些都是为了让你的SQL语句正确,以便你只包含你想要删除的表。

或者,您可以使用从ALL_OBJECTS创建对象的日期,使您的SQL语句如下:

select owner, object_name
  from all_objects
 where object_type = 'TABLE'
   and regexp_like(object_name, 'TEST_TEST_[[:digit:]]{8}')
   and trunc(created) < trunc(sysdate) - 4
   and owner = 'THE_OWNER'
       ;

请注意,这样做,特别是使用PURGE关键字本身就很危险。如果可能的话,最好将ETL更改为加载到单个表中,并将日期作为列,然后从该表中删除不再需要的任何数据。这也将消除动态创建和删除表的需要。