Oracle dbms_job管理

0、参考资料&注意事项

Oracle Database Administrator’s Guide -> Support for DBMS_JOB in Release 11gR2

注意事项:

修改完dbms_job的属性后记着要commit

dbms_job说明:

dbms_job是个pl/sql包,可以让你创建oracle job,oracle 10g以后被scheduler取代,10g以上版本中保留dbms_job功能仅仅是为了向前兼容,就像exp/imp一样。

1、dbms_jobs相关视图和参数

相关视图:

dba_jobs_running
dba_jobs

相关参数:

初始化相关的参数:job_queue_process
建议最大job进程数不要超过1000,oracle11g默认job队列进程数为1000.

查看所有的 JOB &查询正在运行的JOB

select * from dba_jobs;
select job,what,to_char(last_date,'yyyy-mm-dd HH24:mi:ss'),to_char(next_date,'yyyy-mm-dd HH24:mi:ss'),interval from dba_jobs ;
select * from dba_jobs_running;

字段说明:

job : job
what : 执行的存储过程或SQL语句
failures : 失败次数
broken : 状态

2、dbms_job管理

dbms_job停止启动案例

--A层库查询出dbms_job的停止脚本
select 'exec dbms_ijob.broken('||job||',true);' from dba_jobs  where broken='N';
--A层库查询出dbms_job的启动脚本
select 'exec dbms_ijob.broken('||job||',false);' from dba_jobs  where broken='N';

2.1、创建 DBMS_JOB

使用以下语句:

VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno, --job号,ORACLE自动分配
    'your_procedure;',  --执行的存储过程或SQL语句,';'不能省略
    next_date, --下次执行时间
    'interval' --每次间隔时间,以天为单位
  );    
commit;
end;

创建dbms_job案例:
为了示范,先创建一张简单的表:

CREATE TABLE T_TIME(JOB_TIME DATE not null);
  1. 每分种为 T_TIME 表插入一条数据:
VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno,
    'insert into T_TIME values (sysdate);',
    Sysdate,
    'sysdate+1/24/60'
  );    
commit;
end;
  1. 每天删除前一天的数据:
VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno,
    'delete T_TIME where JOB_TIME < sysdate-1;',
    Sysdate,
    'sysdate+1/24'
  );    
commit;
end;
  1. 特殊情况(sql语句中包含单引号)
declare   
      job_id   pls_integer; 
begin
sys.dbms_job.submit(job => job_id,
                    what => 'insert into  sess_lgwr SELECT sysdate check_time,SECONDS_IN_WAIT,BLOCKING_SESSION, PROGRAM FROM GV$SESSION@TEST_CAS1 WHERE PROGRAM LIKE ''%LGWR%'';',
                    next_date =>sysdate,
                    interval => 'sysdate+3/24/60/60'
                    );
commit;
end;

2.2、启停\修改dbms_job

停止 JOB

BEGIN DBMS_JOB.BROKEN(jobno, TRUE); END;
参数 jobno 为对应的JOB号,如 BEGIN DBMS_JOB.BROKEN(2, TRUE); END;

启动 JOB

BEGIN DBMS_JOB.run(jobno); END;
或者
exec dbms_job.broken(1,false);
commit; 

删除 JOB

BEGIN DBMS_JOB.remove(jobno); END;

修改 JOB

修改运行的内容

BEGIN DBMS_JOB.what(
    jobno,   --对应的job号
    'your_procedure;'  --执行的存储过程或SQL语句,';'不能省略
); 
END;

修改时间间隔

BEGIN DBMS_JOB.interval(
    jobno,   --对应的job号
    'interval' --每次间隔时间,以天为单位
); END;

修改下一次执行时间

exec dbms_ijob.next_date(22,to_date('2019-09-15 04:00:00','yyyy-mm-dd hh24:mi:ss'));
BEGIN DBMS_JOB.next_date(
    jobno,   --对应的job号
    next_date, --下次执行时间
); END;

2.3、非job owner用户管理job

不是job的owner的用户delete,remove,broken 一个job时,会报错:ORA-23421: job number XXXX is not a job in the job queue

只有job的owner才能够对job进行修改变更,比如下面的脚本所示:

sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
       JOB WHAT                                     LOG_USER   PRIV_USER  B
---------- ---------------------------------------- ---------- ---------- -
       275 WEB_SMS.cleanAppBuffer;                  SYSTEM     SYSTEM     N
system@im1>exec DBMS_JOB.broken(295,false);
PL/SQL procedure successfully completed.
system@im1>exec DBMS_JOB.broken(295,true);
PL/SQL procedure successfully completed.
system@im1>commit;
Commit complete.
system@im1>select job, log_user, priv_user,broken from dba_jobs where job in (295);
       JOB LOG_USER   PRIV_USER  B
---------- ---------- ---------- -
       295 SYSTEM     SYSTEM     Y

如果登录的用户不是job的owner,比如sys用户:

sys@im1>exec DBMS_IJOB.broken(275,true);
PL/SQL procedure successfully completed.
sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
       JOB WHAT                                     LOG_USER   PRIV_USER  B
---------- ---------------------------------------- ---------- ---------- -
       275 WEB_SMS.cleanAppBuffer;                  SYSTEM     SYSTEM     Y
sys@im1>exec DBMS_IJOB.broken(275,false);
PL/SQL procedure successfully completed.

3、关于 interval 的一些设置技巧

关于job运行时间

1:每分钟执行
'sysdate+1/24/60'
Interval => TRUNC(sysdate,'mi') + 1/(24*60)
2:每天定时执行
例如:每天的凌晨1点执行
Interval => TRUNC(sysdate) + 1 +1/(24)
3:每周定时执行
例如:每周一凌晨1点执行
Interval => TRUNC(next_day(sysdate,'星期一'))+1/24
4:每月定时执行
例如:每月1日凌晨1点执行
Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24
5:每季度定时执行
例如每季度的第一天凌晨1点执行
Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24
6:每半年定时执行
例如:每年7月1日和1月1日凌晨1点
Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24
7:每年定时执行
例如:每年1月1日凌晨1点执行
Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'), 12)+1/24

job的运行频率设置

1.每天固定时间运行,比如早上8:10分钟:Trunc(Sysdate+1) + (8*60+10)/24*60
2.Toad中提供的:
每天:trunc(sysdate+1)
每周:trunc(sysdate+7)
每月:trunc(sysdate+30)
每个星期日:next_day(trunc(sysdate),'星期日')
每天6点:trunc(sysdate+1)+6/24
半个小时:sysdate+30/(24*60)
3.每个小时的第15分钟运行,比如:8:15,9:15,10:15…:trunc(sysdate,'hh')+(60+15)/(24*60)。

描述 INTERVAL参数值

 每天午夜12点 'TRUNC(SYSDATE + 1)'
 每天早上8点30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
 每星期二中午12点 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
 每个月第一天的午夜12点 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
 每个季度最后一天的晚上11点 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
 每星期六和日早上6点10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章