2016-02-18 5 views
1

У меня есть эта таблица Oracle, которую я хочу, чтобы очистить время от времени, когда я достигаю 2000 строк данных:Удаление строк Oracle в зависимости от размера

CREATE TABLE AGENT_HISTORY(
    EVENT_ID INTEGER NOT NULL, 
    AGENT_ID INTEGER NOT NULL, 
    EVENT_DATE DATE NOT NULL 
) 
/

Как я могу удалить самую старую строку из таблицы, когда таблица достигает 2000 строк?

ответ

3

Вы можете удалить все, кроме новейших 2000 строк с помощью следующего запроса:

DELETE FROM agent_history a 
WHERE 2000 < (SELECT COUNT(1) cnt FROM agent_history b WHERE b.event_date < a.event_date) 

проверяет, запросов каждой строки в таблице (а), чтобы увидеть, сколько строк имеют event_date МЕНЬШЕ, чем ряд. Если число строк меньше 2000, то оно удалит эту строку.

Дайте мне знать, если это не поможет.

1

Создайте DBMS_JOB или DBMS_SCHEDULER, который начнется через определенный интервал и вызовет процедуру. В этой процедуре проверьте количество и удалите строки на основе event_date.


Извините, я до сих пор не видел ваших комментариев. Вот код, который вы искали. Убедитесь, что у вас есть гранты для создания программы планировщика и заданий. Этот код предполагает, что event_id представляет собой последовательность из #s и не отстает от event_date. В противном случае измените ранг на основе как времени, так и идентификатора или вашего выбора. Также вы можете изменить временной интервал. Проверьте документацию пакета DBMS_SCHEDULER на наличие ошибок и исправлений.

create or replace procedure proc_house_keeping is 
begin 
    delete 
    from (
    select rank() over (order by event_id desc) rnk 
     from agent_history 
    ) 
    where rnk > 2000; 
    commit; 
end; 
/

begin 
    dbms_scheduler.create_program(
    program_name => 'PROG_HOUSE_KEEPING', 
    program_type => 'STORED_PROCEDURE', 
    program_action => 'PROC_HOUSE_KEEPING', 
    number_of_arguments => 0, 
    enabled  => FALSE, 
    comments  => 'Procedure to delete rows greater than 2000'); 
end; 
/

begin 
    dbms_scheduler.create_job(
     job_name => 'table_house_keeping', 
     program_name => 'PROG_HOUSE_KEEPING', 
     start_date => dbms_scheduler.stime, 
     repeat_interval => 'FREQ=MINUTELY;INTERVAL=1', 
     end_date => dbms_scheduler.stime+1, 
     enabled => false, 
     auto_drop => false, 
     comments => 'table house keeping, runs every minute'); 
end; 
/
+0

Можете ли вы показать мне пример с SQL запрос? –

+0

Просто увидел ваше сообщение и разместил образец кода. –

0

Подходом может быть добавление триггера в вашу таблицу, чтобы он проверял и удалял самые старые строки в каждом операторе INSERT; например, предполагая, что не более 3 строк:

CREATE OR REPLACE TRIGGER DELETE_3 
AFTER INSERT ON AGENT_HISTORY 
DECLARE 
    vNum number; 
    minDate date; 
BEGIN 

    delete AGENT_HISTORY 
    where (event_id, agent_id, event_date) in 
      ( select event_id, agent_id, event_date 
       from (  
         select event_id, agent_id, event_date, row_number() over (order by event_date desc) num 
         from AGENT_HISTORY 
        ) 
       where num > 3 /* MAX NUMBER OF ROWS = 3*/ 
      ); 
END; 

Say мы вводим 5 строк:

SQL> begin 
    2  insert into AGENT_HISTORY(EVENT_ID , AGENT_ID, EVENT_DATE) values (1, 1, sysdate); 
    3  dbms_lock.sleep(1); 
    4  insert into AGENT_HISTORY(EVENT_ID , AGENT_ID, EVENT_DATE) values (2, 2, sysdate); 
    5  dbms_lock.sleep(1); 
    6  insert into AGENT_HISTORY(EVENT_ID , AGENT_ID, EVENT_DATE) values (3, 3, sysdate); 
    7  dbms_lock.sleep(1); 
    8  insert into AGENT_HISTORY(EVENT_ID , AGENT_ID, EVENT_DATE) values (4, 4, sysdate); 
    9  dbms_lock.sleep(1); 
10  insert into AGENT_HISTORY(EVENT_ID , AGENT_ID, EVENT_DATE) values (5, 5, sysdate); 
11  commit; 
12 end; 
13/

PL/SQL procedure successfully completed. 

мы только новейший 3:

SQL> select * from AGENT_HISTORY; 

    EVENT_ID AGENT_ID EVENT_DATE 
---------- ---------- --------------------------------------------------------------------------- 
     3   3 18-FEB-16 17:05:24,000000 
     4   4 18-FEB-16 17:05:25,000000 
     5   5 18-FEB-16 17:05:26,000000 
Смежные вопросы