这几天在工作中遇到一个问题就是:要删除表在备份表中已存在的数据(2000多万数据),这个数据是SQL查出来的,例如:
select count(1)
from JY_SALE_FULLORDER_DTL
where LINE_NUM in (
select b.LINE_NUM
from JY_SALE_FULLORDER_DTL a join JY_SALE_FULLORDER_DTL_HIS B ON A.LINE_NUM = B.LINE_NUM
);
删除SQL:
DELETE FROM JY_SALE_FULLORDER_DTL
WHERE LINE_NUM IN (
SELECT b.LINE_NUM
FROM JY_SALE_FULLORDER_DTL a
JOIN JY_SALE_FULLORDER_DTL_HIS B ON A.LINE_NUM = B.LINE_NUM
)
之前用 DBvaver 创建任务,每次删除或者更新10万条数据,结果导致表被锁死了
现在不能再用这个方法来删数据了,因为删除数据的时候不会停顿,我需要的是每一分钟删除2万条数据,这样的话,就不会让表被锁死了
在网上搜索到 oracle有自带的定时任务 user_jobs, 后面慢慢研究了一下
参考博客:oracle创建定时任务
SELECT * FROM USER_JOBS;
通过这个user_jobs知道,我要先创建一个存储过程,这个存储过程干什么事情呢,就是删除我要删除的数据
CREATE OR REPLACE PROCEDURE 存储过程名字 AS
BEGIN
BEGIN
DELETE
FROM
JY_SALE_FULLORDER_DTL
WHERE
LINE_NUM IN (
SELECT
b.LINE_NUM
FROM
JY_SALE_FULLORDER_DTL a
JOIN JY_SALE_FULLORDER_DTL_HIS B ON
A.LINE_NUM = B.LINE_NUM)
AND ROWNUM < 20000;
COMMIT ;
END;
END;
上面SQL可以看出,这是创建一个存储过程,删除表数据,但是每次删除,查询20000条数据出来删除。
存储过程创建好了,接下来我创建一条user_jobs数据
declare
xjobid number;
BEGIN
DBMS_JOB.SUBMIT(
JOB => xjobid, /*自动生成JOB_ID*/
WHAT => 'declare BEGIN test_function(); END;', /*需要执行的存储过程名称或SQL语句*/
NEXT_DATE => sysdate+3/(24*60), /*初次执行时间-当前时间的3分钟后*/
INTERVAL => 'trunc(sysdate,''mi'')+1/(24*60)' /*每隔1分钟执行一次*/
);
commit;
end;
直接执行,然后user_jobs表就能生成一条数据
接下来,启动定时任务
-- 执行定时任务
begin
-- 这个job_id是自动生成的
dbms_job.run(81);
end;
接下来只需要等着就行,电脑一直开着,如果oracle是线上远程数据库,电脑关机都可以,因为存储过程和user_jobs不也都是在线上的嘛,创建完毕和开启定时任务之后,跟本地电脑有没有网没关系。
如果觉得有点慢,你可以30秒删除2万条,或者一分钟删除5万条等。可以自己修改间隔时间
begin
dbms_job.interval(126,interval => 'sysdate+1/(24*60)');
end;
还有其他,暂停任务,删除任务,间隔时间的表达式等具体请看
oracle 定时任务相关操作