我有这个Oracle表,当我达到2000行数据时,我想不时清理它:
CREATE TABLE AGENT_HISTORY(
EVENT_ID INTEGER NOT NULL,
AGENT_ID INTEGER NOT NULL,
EVENT_DATE DATE NOT NULL
)
/
当表达到2000行时,如何从表中删除最旧的行?
答案 0 :(得分:3)
您可以使用以下查询删除除最新2000行以外的所有行:
DELETE FROM agent_history a
WHERE 2000 < ( SELECT COUNT(1) cnt FROM agent_history b WHERE b.event_date < a.event_date )
查询检查表(a)中的每一行,以查看event_date少于该行的行数。如果有超过2000行,那么它将删除该行。
如果这不起作用,请告诉我。
答案 1 :(得分: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;
/
答案 2 :(得分: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;
假设我们插入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