当前位置:   article > 正文

Oracle dbms_job和dbms_scheduler创建带参和不带参的定时任务使用教程_dbms_scheduler.run_job

dbms_scheduler.run_job

Oracle 定时任务

在工作中,有时候会需要定时执行存储过程或者一段sql,如果每次都人为执行,会很费力费时。所以需要使用数据库定时任务来按时执行对应sql,这样做有效的节约了时间和人力。

下面以oracle为基础,分别从oracle自带的dbms_job和dbms_scheduler两种方式来介绍定时任务的创建和执行。

一、dbms_job 方式

以下介绍定时执行存储过程,存储过程的作用是向临时表中插入每次定时执行时的日期。

  1. 首先创建临时表tmp_date,创建语句如下:
create table tmp_date(test_date varchar2(20));
  • 1
  1. 创建存储过程pro_date,创建语句如下:
create or replace procedure proc_date as
begin
  insert into tmp_date values (to_char(sysdate, 'yyyymmdd hh:mi:ss'));/*向测试表插入数据*/
  commit;
end;
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 创建job定时任务,实现定时自动调用存储过程。创建语句如下:
declare
  job number;
	begin
	 DBMS_JOB.SUBMIT(  
        JOB => job,  /*自动生成JOB_ID*/  
        WHAT => 'proc_date;',  /*需要执行的存储过程名称或SQL语句*/  
        NEXT_DATE => sysdate+3/(24*60),  /*初次执行时间-下一个3分钟*/  
        INTERVAL => 'trunc(sysdate,''mi'')+1/(24*60)' /*每隔1分钟执行一次*/
      );  
  commit;
end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 可以查询系统视图user_jobs查看创建的job定时任务,如下图。
    在这里插入图片描述
  • 查询临时表中数据,可以看到是按照存储过程,每分钟插入一条数据到临时表中。
    在这里插入图片描述
列名数据类型解释
JOBNUMBER任务的唯一标示号
LOG_USERVARCHAR2(30)提交任务的用户
PRIV_USERVARCHAR2(30)赋予任务权限的用户
SCHEMA_USERVARCHAR2(30)对任务作语法分析的用户模式
LAST_DATEDATE最后一次成功运行任务的时间
LAST_SECVARCHAR2(8)如HH24:MM:SS格式的last_date日期的小时,分钟和秒
THIS_DATEDATE正在运行任务的开始时间,如果没有运行任务则为null
THIS_SECVARCHAR2(8)如HH24:MM:SS格式的this_date日期的小时,分钟和秒
NEXT_DATEDATE下一次定时运行任务的时间
NEXT_SECVARCHAR2(8)如HH24:MM:SS格式的next_date日期的小时,分钟和秒
TOTAL_TIMENUMBER该任务运行所需要的总时间,单位为秒
BROKENVARCHAR2(1)标志参数,Y标示任务中断,以后不会运行
INTERVALVARCHAR2(200)用于计算下一运行时间的表达式
FAILURESNUMBER任务运行连续没有成功的次数
WHATVARCHAR2(2000)执行任务的PL/SQL块

相关操作

DBMS_JOB.RUN(40); -- 手工调用job id 为40的任务
dbms_job.remove(40); -- 删除job id  为40的任务
dbms_job.interval(job,interval); -- 修改间隔时间
dbms_job.next_date(job,next_date); -- 修改下次执行时间
dbms_job.what(jobno,'sp_fact_charge_code;');  --修改某个job名 
  • 1
  • 2
  • 3
  • 4
  • 5

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)''    
每3秒钟执行一次             'sysdate+3/(24*60*60)'   
每2分钟执行一次           'sysdate+2/(24*60)'   

1. :每分钟执行  
   Interval => TRUNC(sysdate,'mi') + 1/ (24*60) --每分钟执行  
   interval => 'sysdate+1/(24*60)'  --每分钟执行  
   interval => 'sysdate+1'    --每天  
   interval => 'sysdate+1/24'   --每小时  
   interval => 'sysdate+2/24*60' --每2分钟  
   interval => 'sysdate+30/24*60*60'  --每30秒  
2. :每天定时执行  
   Interval => TRUNC(sysdate+1)  --每天凌晨0点执行  
   Interval => TRUNC(sysdate+1)+1/24  --每天凌晨1点执行  
   Interval => TRUNC(SYSDATE+1)+(8*60+30)/(24*60)  --每天早上8点30分执行  
3. :每周定时执行  
   Interval => TRUNC(next_day(sysdate,'星期一'))+1/24  --每周一凌晨1点执行  
   Interval => TRUNC(next_day(sysdate,1))+2/24  --每周一凌晨2点执行  
4. :每月定时执行  
   Interval =>TTRUNC(LAST_DAY(SYSDATE)+1)  --每月1日凌晨0点执行  
   Interval =>TRUNC(LAST_DAY(SYSDATE))+1+1/24  --每月1日凌晨1点执行  
5. :每季度定时执行  
   Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q')  --每季度的第一天凌晨0点执行  
   Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'q') + 1/24  --每季度的第一天凌晨1点执行  
   Interval => TRUNC(ADD_MONTHS(SYSDATE+ 2/24,3),'q')-1/24  --每季度的最后一天的晚上11点执行  
6. :每半年定时执行  
   Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24  --每年7月1日和1月1日凌晨1点  
7. :每年定时执行  
   Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24  --每年1月1日凌晨1点执行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

二、dbms_scheduler 方式

dbms_scheduler创建定时器语法

  1. job_name: 任务名称
  2. job_type:定时器类型,PL/SQL Block、Stored procedure、Executable
  3. job_action:
    若job_type为存储过程,job_action为存储过程的名字;
    若job_type为PL/SQL块,job_action为完整的PL/SQL代码;
    若job_type为指定的外部程序,job_action为输入的script的名称或者操作系统的指令名
  4. start_date:开始时间
  5. repeat_interval:运行的时间间隔
  6. end_date:到期时间
  7. enabled:创建后自动激活
  8. auto_drop:默认true,即当job执行完毕都到期是否直接删除job
  9. comments:备注

repeat_interval参数实例:

FREQ:YEARLY(年) | MONTHLY(月) | WEEKLY(周) | DAILY(日) | HOURLY(时) | MINUTELY(分) | SECONDLY(秒)
BYDAY=:“MON” | “TUE” | “WED” | “THU” | “FRI” | “SAT” | “SUN”
BYMONTH: “JAN” | “FEB” | “MAR” | “APR” | “MAY” | “JUN” | “JUL” | “AUG” | “SEP” | “OCT” | “NOV” | “DEC”

以下为具体实例:

-- REPEAT_INTERVAL => 'FREQ=HOURLY; INTERVAL=1',       每小时执行一次
-- REPEAT_INTERVAL => 'FREQ=MINUTELY; INTERVAL=5',      每5分钟执行一次
-- REPEAT_INTERVAL => 'FREQ=WEEKLY; INTERVAL=1; BYDAY=MON',   每周一执行一次
-- REPEAT_INTERVAL => 'FREQ=WEEKLY; INTERVAL=1; BYDAY=MON; BYHOUR=8; BYMINUTE=00',  每周一早上8点执行一次
-- REPEAT_INTERVAL => 'FREQ=MONTHLY; INTERVAL=1; BYMONTHDAY=1; BYHOUR=8; BYMINUTE=00',  每月第一天早上8点执行一次
  • 1
  • 2
  • 3
  • 4
  • 5

将上述例子改为dbms_scheduler方式,如下:

declare
  job number;
  v_date varchar2(20) := to_char(sysdate,'yyyymmdd hh:mi:ss');
begin
  dbms_scheduler.create_job(
    job_name => 'scheduler_tmpdate',-- 定时器名字
    job_type => 'STORED_PROCEDURE',-- 类型:存储过程
    job_action => 'proc_date', -- 存储过程名称
    repeat_interval => 'FREQ=MINUTELY;interval=1', -- 定时规则,每分钟执行一次
    enabled =>false -- 创建后不激活
  );
  dbms_scheduler.enable('scheduler_tmpdate'); -- 激活
  dbms_scheduler.run_job('scheduler_tmpdate'); -- 运行job
  end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

相关操作

dbms_scheduler.run_job(jobName) – 运行job
dbms_scheduler.stop_job(jobName,force) 停止job,force默认为false
dbms_scheduler.drop_job(jobName) 删除job
dbms_scheduler.enable(jobName) 打开job
dbms_scheduler.disable(jobName,force) 禁用job,force参数用于dependencies
  • 1
  • 2
  • 3
  • 4
  • 5

相关系统视图

user_scheduler_jobs       查看所有job信息
user_scheduler_running_jobs    查看所有正在运行的job
user_scheduler_job_run_details    job运行日志
User_Scheduler_Job_Log         job job日志
  • 1
  • 2
  • 3
  • 4

!注意事项:

dbms_scheduler创建job需要创建权限,否则创建时会出错,grant create job to xxx,可以通过该命令将权限赋值给指定用户。

三、带参数的存储过程的定时任务创建

上述给的例子是没有参数传入的,但在工作中,有时候会有动态参数需要传入,这时就需要在上述两种方式中修改部分内容,主要修改内容如下。

dbms_job 带参数传入的定时任务

使用dbms_job创建定时任务时,如果存储过程有参数传入,可以将原先存储过程名称改为具体的执行sql语句块,在语句块中进行参数的传递,最终达到参数传递的效果。

declare
  job number;
BEGIN
  DBMS_JOB.SUBMIT(  
        JOB => job,  /*自动生成JOB_ID*/  
        WHAT => 'declare
  				i_date varchar2(8) := to_char(sysdate,''yyyymmdd'');
                    BEGIN
                      proc_date(i_date);
                      commit;
                    end;',  /*需要执行的存储过程名称或SQL语句*/  
        NEXT_DATE => sysdate+1/(24*60),  /*初次执行时间-下一个1分钟*/  
        INTERVAL => 'trunc(sysdate,''mi'')+1/(24*60)', /*每隔1分钟执行一次*/
        no_parse => false
      );  
  commit;
end;
/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

dbms_scheduler带参数传入的定时任务

使用dbms_scheduler创建带参数传入的定时任务时,可以利用具体语句进行参数项配置,最后运行定时任务,具体内容如下,在原来的基础上增加number_of_arguments => 1,参数个数配置,dbms_scheduler.set_job_argument_value设置参数值的配置。如果存在多个参数值,则需要配置多个dbms_scheduler.set_job_argument_value,里面的参数索引需要按照实际的位置进行改变。

declare
  job number;
  v_date varchar2(20) := to_char(sysdate,'yyyymmdd hh:mi:ss');
begin
  dbms_scheduler.create_job(
    job_name => 'job_date',
    job_type => 'STORED_PROCEDURE',
    job_action => 'proc_date',
    number_of_arguments => 1,
    repeat_interval => 'FREQ=MINUTELY;interval=1',
    enabled =>false
  );
  dbms_scheduler.set_job_argument_value(
    job_name => 'job_date',
    argument_position => 1,
    argument_value => v_date
  );
  dbms_scheduler.enable('job_date');
  dbms_scheduler.run_job('job_date');
  end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

多个参数:

declare
  job number;
  v_date varchar2(20) := to_char(sysdate,'yyyymmdd hh:mi:ss');
begin
  dbms_scheduler.create_job(
    job_name => 'job_date',
    job_type => 'STORED_PROCEDURE',
    job_action => 'proc_date',
    number_of_arguments => 1,
    repeat_interval => 'FREQ=MINUTELY;interval=1',
    enabled =>false
  );
  dbms_scheduler.set_job_argument_value(
    job_name => 'job_date',
    argument_position => 1,
    argument_value => v_date
  );
  dbms_scheduler.set_job_argument_value(
    job_name => 'job_date',
    argument_position => 2,
    argument_value => 'hcx'
  );
  dbms_scheduler.enable('job_date');
  dbms_scheduler.run_job('job_date');
  end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/203608
推荐阅读
相关标签
  

闽ICP备14008679号