ORACEL创建存储过程和根据Oracle定时任务机制执行存储过程

oracle定时执行存储过程

--创建一个存储过程,每天定时执行,将满足条件的设备插入到pinpai_Report表中。
CREATE OR REPLACE
procedure prc_job_report is
begin

INSERT into
pinpai_Report
SELECT
  s.type,
  s.remark,
  G .GROUPID,
  s."CATEGORY" CATEGORY,
  s.DEVTYPE devtype,
  s.VENDOR vendor,
  SUM (CASE WHEN s.DEVSTATUS in (7,16,24,33,8) and ( nvl(s.REFURBISHED_NUM,0)=0) and s.FIRSTACCESSSTATUS=0 THEN 1 ELSE 0 END ) AS countky,
  SUM (CASE WHEN s.DEVSTATUS in (11,25) THEN 1 ELSE 0 END) AS countfx,
TO_CHAR(sysdate-1, 'YYYY-MM-DD')  as time 
FROM
  AMS_ASSET_INFO s,
  GROUP_INFO_TAB G
WHERE s.DOMAIN = TO_CHAR (G .GROUPID_OLD)
GROUP BY
  s."CATEGORY",
  s.DEVTYPE,
  s.VENDOR,
  G .GROUPID,
  s.remark,
  s.type 
HAVING s.remark in (0,1);

end prc_job_report;

建立定时器

declare   
   job NUMBER;
begin
dbms_job.submit(
    job=>job,
    what=>'prc_job_report;',
    next_date=>sysdate+1/(24*60),
    interval=>'sysdate+1+30/(24*60)',
    no_parse=>false);
end;

说明:job就是一个数字类型的变量可以随便定义
dbms_job.submit(
job => job, //以JOB的方式进行提交
what => '存储过程名称;', //job调用的存储过程,建job的目的是要调用存储过程
next_date => sysdate, // 设置的时间是由系统自动生成,可以根据自己的需要设置该时间
interval => 'sysdate+1'); // 多长时间调用一次,以天为单位的,根据需要可以自己设置
no_parse=>false //是否在执行时进行语法分析
--启动定时器
BEGIN
  DBMS_JOB.RUN(23);
  commit;
END;

23就是定时器的索引  可根据下面方式查出
--查看所有的调度任务
select * from user_jobs;
--查看正在执行的调度任务
select * from dba_jobs_running;
--查看执行完的调度任务
select * from dba_jobs;

关于定时器执行频率时间的设置 Interval

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

关于定时器下一次执行的时间的设置 next_date

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

关于定时器的其他操作,如修改、删除。

1.设置定时器开关
dbms_job.broken(jobid,off);
jobid:user_jobs表中的jobid(主键),数字格式
off:定时任务开关,true or false,true关闭,false开启

2.运行定时器
dbms_job.run(23);
jobid:user_jobs表中的jobid(主键),数字格式

3.删除定时器
dbms_job.remove(jobid);
jobid:user_jobs表中的jobid(主键),数字格式

4.修改定时器
dbms_job.change(jobid,what,next_date,interval);
jobid:user_jobs表中的jobid(主键),数字格式
what:要执行的存储过程,例如what=>'存储过程名;'
next_date:下一次执行的时间,这个参数是时间格式的
interval:执行频率,也就是计算下一次执行时间的公式,是字符串格式

其他相关知识

1、job如果由于某种原因未能成功执行,oracle将重试16次后,还未能成功执行,将被标记为broken,可以手动重启job。
2、dba_jobs,all_jobs,user_jobs,dba_jobs_running(包含正在运行job相关信息) 这些视图保存了job的相关信息
3、查看相关信息SELECT JOB, NEXT_DATE, NEXT_SEC, FAILURES, BROKEN FROM DBA_JOBS;
NEXT_DATE:表示下一次job执行的时间
FAILURES:表示job执行失败的次数
BROKEN:表示job状态,y表示停止,n表示启用成功

参考博文:
(1) https://www.cnblogs.com/manwwx129/p/11910196.html
(2) https://www.cnblogs.com/linjiqin/archive/2013/06/24/3152638.html