赞
踩
在工作中,有时候会需要定时执行存储过程或者一段sql,如果每次都人为执行,会很费力费时。所以需要使用数据库定时任务来按时执行对应sql,这样做有效的节约了时间和人力。
下面以oracle为基础,分别从oracle自带的dbms_job和dbms_scheduler两种方式来介绍定时任务的创建和执行。
以下介绍定时执行存储过程,存储过程的作用是向临时表中插入每次定时执行时的日期。
tmp_date
,创建语句如下:create table tmp_date(test_date varchar2(20));
pro_date
,创建语句如下:create or replace procedure proc_date as
begin
insert into tmp_date values (to_char(sysdate, 'yyyymmdd hh:mi:ss'));/*向测试表插入数据*/
commit;
end;
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;
列名 | 数据类型 | 解释 |
---|---|---|
JOB | NUMBER | 任务的唯一标示号 |
LOG_USER | VARCHAR2(30) | 提交任务的用户 |
PRIV_USER | VARCHAR2(30) | 赋予任务权限的用户 |
SCHEMA_USER | VARCHAR2(30) | 对任务作语法分析的用户模式 |
LAST_DATE | DATE | 最后一次成功运行任务的时间 |
LAST_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的last_date日期的小时,分钟和秒 |
THIS_DATE | DATE | 正在运行任务的开始时间,如果没有运行任务则为null |
THIS_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的this_date日期的小时,分钟和秒 |
NEXT_DATE | DATE | 下一次定时运行任务的时间 |
NEXT_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的next_date日期的小时,分钟和秒 |
TOTAL_TIME | NUMBER | 该任务运行所需要的总时间,单位为秒 |
BROKEN | VARCHAR2(1) | 标志参数,Y标示任务中断,以后不会运行 |
INTERVAL | VARCHAR2(200) | 用于计算下一运行时间的表达式 |
FAILURES | NUMBER | 任务运行连续没有成功的次数 |
WHAT | VARCHAR2(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名
每天午夜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点执行
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点执行一次
将上述例子改为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;
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
user_scheduler_jobs 查看所有job信息
user_scheduler_running_jobs 查看所有正在运行的job
user_scheduler_job_run_details job运行日志
User_Scheduler_Job_Log job job日志
dbms_scheduler创建job需要创建权限,否则创建时会出错,grant create job to xxx
,可以通过该命令将权限赋值给指定用户。
上述给的例子是没有参数传入的,但在工作中,有时候会有动态参数需要传入,这时就需要在上述两种方式中修改部分内容,主要修改内容如下。
使用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; /
使用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;
多个参数:
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;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。