文章目录
1 概述
1.1 思维导图
2 语法
2.1 核心三要素
2.1.1 program 程序
2.1.2 schedule 计划表
2.1.3 job 工作
2.2 核心属性
2.2.1 type、action
2.2.2 repeat_interval
3 示例
3.1 创建带参数的过程 job
3.2 创建无日志 job
1 概述
1. dbms_scheduler 包概念: "分而治之"
(1) 替代了之前的 dbms_job 包,功能更加强大,可以将 job 需要的 '各种资源分开再进行组合'
(2) 核心三要素:'schedule', 'program' 和 'job' 其它都是围绕它们来的
(3) 除了单个 job,还能设置 job 组
2. 主要视图
(1) 基础信息查询
select * from dba_scheduler_programs t;
select * from dba_scheduler_program_args t; -- 过程参数
select * from dba_scheduler_schedules t;
select * from dba_scheduler_jobs t;
(2) 执行信息查询
select * from dba_scheduler_running_jobs t;
select * from dba_scheduler_job_log t;
select * from dba_scheduler_job_run_details t;
3. 说明:目前仅整理自己用过的,后续有有用到再继续补充 ^_^
基础数据:记录定时任务执行结果
create table scott.dbms_scheduler_test (
message varchar2(100),
create_date date);
create or replace procedure scott.p_dbms_scheduler_test as
begin
insert into scott.dbms_scheduler_test
(message, create_date)
values
('dbms_scheduler', sysdate);
commit;
end;
1.1 思维导图
dbms_scheduler 包头中有全部的过程和方法及说明:
2 语法
2.1 核心三要素
2.1.1 program 程序
-- 项目管理程序 Program Administration Procedures
procedure create_program(
program_name in varchar2, -- 程序名称
program_type in varchar2, -- 类型,详见 "核心属性"
program_action in varchar2, -- 动作,详见 "核心属性"
number_of_arguments in pls_integer default 0, -- 参数个数
enabled in boolean default false, -- 是否立即启用
comments in varchar2 default null); -- 备注
-- 备注信息特别说明 enabled = true 立即启用,false 不立即启用 以下同理
(1) false: 如果创建的程序需要输入参数(number_of_arguments >= 1),则必须定义完参数后在激活(enabled => false)
(2) true : 如果创建的程序不需要参数,则均可
创建程序:create_program
begin
dbms_scheduler.create_program(
program_name => 'DBMS_SCHEDULER_PROGRAM_TEST',
program_type => 'STORED_PROCEDURE',
program_action => 'SCOTT.P_DBMS_SCHEDULER_TEST',
comments => '调用过程测试');
end;
删除程序:drop_program
begin
dbms_scheduler.drop_program(
program_name => 'DBMS_SCHEDULER_PROGRAM_TEST',
force => false);
-- 特别说明:false => false,当有程序还在 "过程中(dba_scheduler_programs)" 时,删除会报错:
-- ora-27479: 无法 drop 'xxx', 因为有其他对象依赖于它
end;
2.1.2 schedule 计划表
-- 计划管理程序 schedule administration procedures
procedure create_schedule(
schedule_name in varchar2,
start_date in timestamp with time zone default null,
repeat_interval in varchar2, -- 重复间隔:日历表达式
end_date in timestamp with time zone default null,
comments in varchar2 default null);
创建计划:create_schedule
begin
dbms_scheduler.create_schedule(
schedule_name => 'DBMS_SCHEDULER_SCHEDULE_TEST',
start_date => sysdate,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1', -- 日历表达式
end_date => sysdate + 5 / 1440,
comments => '每分钟执行一次,5分钟后结束');
end;
删除计划:drop_schedule
begin
dbms_scheduler.drop_schedule(
schedule_name => 'DBMS_SCHEDULER_SCHEDULE_TEST',
force => false); -- false:执行完后禁用,true:立即禁用
-- 特别说明:false => false,当有程序还在 "计划中(dba_scheduler_schedules)" 时,删除会报错:
-- ora-27479: 无法 drop 'xxx', 因为有其他对象依赖于它
end;
2.1.3 job 工作
-- 工作管理程序 Job Administration Procedures
-- create_job 的重载方法有很多,主要有以下两类
-- 1 job = program + schedule
procedure create_job(
job_name in varchar2,
program_name in varchar2,
schedule_name in varchar2,
job_class in varchar2 default 'DEFAULT_JOB_CLASS',
enabled in boolean default false,
auto_drop in boolean default true,
comments in varchar2 default null,
job_style in varchar2 default 'REGULAR',
credential_name in varchar2 default null,
destination_name in varchar2 default null);
-- 2 job 自己玩(内容都在一起)
procedure create_job(
job_name in varchar2,
job_type in varchar2,
job_action in varchar2,
number_of_arguments in pls_integer default 0,
start_date in timestamp with time zone default null,
repeat_interval in varchar2 default null,
end_date in timestamp with time zone default null,
job_class in varchar2 default 'DEFAULT_JOB_CLASS',
enabled in boolean default false,
auto_drop in boolean default true,
comments in varchar2 default null,
credential_name in varchar2 default null,
destination_name in varchar2 default null);
创建工作:create_job
begin
dbms_scheduler.create_job(
job_name => 'DBMS_SCHEDULER_JOB_TEST',
program_name => 'DBMS_SCHEDULER_PROGRAM_TEST',
schedule_name => 'DBMS_SCHEDULER_SCHEDULE_TEST',
enabled => true, -- true: 立即启用, false:不立即启用(手动启用)
comments => '常见创建 job 的方式');
end;
删除工作:drop_job
begin
dbms_scheduler.drop_job(
job_name => 'DBMS_SCHEDULER_JOB_TEST',
force => false);
-- 特别说明: force => false
-- false:job 执行完成后再删除
-- true :立即删除(job 未必执行完成哦)
end;
2.2 核心属性
2.2.1 type、action
type
(1) PLSQL_BLOCK : PL/SQL 块
(2) STORED_PROCEDURE : 存储过程
(3) EXECUTABLE : 可执行程序(包括 shell 脚本)
action -- 根据不同的 "类型",有不同的 "动作"
(1) 'PLSQL_BLOCK' : 'begin 存储过程名; end;'
(2) 'STORED_PROCEDURE' : '存储过程名'
(3) 'EXECUTABLE' : '/backup/xx/shell/xx.sh'
示例: PL/SQL 块
BEGIN
dbms_scheduler.create_job(job_name => 'JOB_PLSQL_BLCOK_TEST',
job_type => 'PLSQL_BLOCK',
job_action => 'begin scott.p_dbms_scheduler_test; end;',
number_of_arguments => 0,
start_date => SYSDATE,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1' ,
end_date => SYSDATE + 5 / 1440,
enabled => true,
auto_drop => true,
comments => '每分钟执行一次,五分钟后结束');
END;
2.2.2 repeat_interval
-- repeat_interval 支持两种格式
1. 常规日期格式
(1) 每天:sysdate + 1
2. 日历表达式('FREQ': 频率,'INTERVAL':范围 1-999,可选:BY...)
FREQ=DAILY; INTERVAL=1 每天执行一次
FREQ=WEEKLY; INTERVAL=1; BYDAY=MON 每周一执行一次
FREQ=WEEKLY; INTERVAL=1; BYDAY=MON,FRI 每周一,周五执行一次
FREQ=WEEKLY; INTERVAL=1; BYDAY=MON; BYHOUR=8 每周一早上8点执行一次
FREQ=MONTHLY; INTERVAL=1; BYMONTHDAY=1; BYHOUR=8; BYMINUTE=30 每月第一天早上8点30分执行一次
(1) FREQ
YEARLY 年
MONTHLY 月
WEEKLY 周
DAILY 天
HOURLY 时
MINUTELY 分
SECONDLY 秒
(2) INTERVAL
1 ~ 999
(3) BYMONTH
JAN 一月 -- January
FEB 二月 -- February
MAR 三月 -- March
APR 四月 -- April
MAY 五月 -- May
JUN 六月 -- June
JUL 七月 -- July
AUG 八月 -- August
SEP 九月 -- September
OCT 十月 -- October
NOV 十一月 -- February
DEC 十二月 -- December
(4) BYDAY
MON 周一 -- Monday
TUE 周二 -- Tuesday
WED 周三 -- Wednesday
THU 周四 -- Thursday
FRI 周五 -- Friday
SAT 周六 -- Saturday
SUN 周天 -- Sunday
(5) BYHOUR
(6) BYMINUTE
(7) BYSECOND
3 示例
3.1 创建带参数的过程 job
说明:
1. OUT 参数在 JOB 里没有任何意义
若场景需要 out 参数,argument_position 位置对应,argument_value = '' 即可
2. 建议 '不记录日志'
(1) dba_scheduler_job_log, dba_scheduler_job_log
(2) 不记录日志:(job_class => 'DBMS_JOB$') -- 因为日志太多,会导致上述数据字典过大
-- 也可以单独创建一个 '日志表',记录想要的信息
3. 建议 'job 执行完成后自动删除',和上述同理
create or replace procedure scott.p_dbms_scheduler_test2(i_message in varchar2,
i_create_date in date) as
begin
insert into scott.dbms_scheduler_test
(message, create_date)
values
(i_message, i_create_date);
commit;
end;
方式1:直接用 job
BEGIN
dbms_scheduler.create_job(job_name => 'JOB_01',
job_type => 'STORED_PROCEDURE',
job_action => 'SCOTT.P_DBMS_SCHEDULER_TEST2',
number_of_arguments => 2,
start_date => SYSDATE,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1',
end_date => SYSDATE + 5 / 1440,
enabled => FALSE, -- true: 立即执行,false: 不自动执行
auto_drop => TRUE,
comments => '带参数过程,直接全 job 中填写参数');
dbms_scheduler.set_job_argument_value(job_name => 'JOB_01',
argument_position => 1,
argument_value => 'O1_mesage');
dbms_scheduler.set_job_argument_value(job_name => 'JOB_01',
argument_position => 2,
argument_value => SYSDATE);
dbms_scheduler.enable(NAME => 'JOB_01'); -- 自动激活
-- dbms_scheduler.run_job(job_name => 'JOB_01'); -- 手动激活
END;
方式2:
BEGIN
-- 定义过程
dbms_scheduler.create_program(program_name => 'PROGRAM_NAME_02',
program_type => 'STORED_PROCEDURE',
program_action => 'SCOTT.P_DBMS_SCHEDULER_TEST2',
number_of_arguments => 2,
enabled => FALSE,
comments => '带参数过程');
---- 定义参数1
dbms_scheduler.define_program_argument(program_name => 'PROGRAM_NAME_02',
argument_position => 1,
argument_name => 'I_MESSAGE',
argument_type => 'VARCHAR2',
default_value => 'O2_mesage',
out_argument => FALSE);
---- 定义参数2
dbms_scheduler.define_program_argument(program_name => 'PROGRAM_NAME_02',
argument_position => 2,
argument_name => 'I_CREATE_DATE',
argument_type => 'DATE',
default_value => SYSDATE,
out_argument => FALSE);
-- 启用过程
dbms_scheduler.enable(NAME => 'PROGRAM_NAME_02');
-- 创建 job
dbms_scheduler.create_job(job_name => 'JOB_02',
program_name => 'PROGRAM_NAME_02',
start_date => SYSDATE,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1',
end_date => SYSDATE + 5 / 1440,
enabled => TRUE,
auto_drop => TRUE,
comments => '带参数 job 测试 2');
END;
3.2 创建无日志 job
-- 创建无日志 job
BEGIN
-- 等同 "DBMS_JOB$" (Oracle 自带)
-- select * from dba_scheduler_job_classes t where t.logging_level = 'OFF';
dbms_scheduler.create_job_class(job_class_name => 'NO_LOGGING_CLASS', -- 自定义
resource_consumer_group => 'DEFAULT_CONSUMER_GROUP', -- 自定义
logging_level => dbms_scheduler.logging_off);
dbms_scheduler.create_job(job_name => 'JOB_PLSQL_BLCOK_TEST',
job_type => 'PLSQL_BLOCK',
job_action => 'begin scott.p_dbms_scheduler_test; end;',
number_of_arguments => 0,
start_date => SYSDATE,
repeat_interval => 'FREQ=MINUTELY; INTERVAL=1',
end_date => SYSDATE + 5 / 1440,
job_class => 'NO_LOGGING_CLASS', -- 不记录日志 dba_scheduler_job_log
enabled => TRUE,
auto_drop => TRUE, -- 执行完成后,自动删除 dba_scheduler_jobs
comments => '每分钟执行一次,五分钟后结束,且不记录日志');
END;
验证:
-- 数据查询成功(5 条记录)
SELECT * FROM scott.dbms_scheduler_test;
-- 以下日志没有记录(上述 job 统计时间内)
SELECT * from dba_scheduler_jobs t WHERE T.job_name = 'JOB_PLSQL_BLCOK_TEST';
SELECT * from dba_scheduler_job_log t WHERE t.JOB_NAME = 'JOB_PLSQL_BLCOK_TEST';
SELECT * from dba_scheduler_job_run_details t WHERE t.JOB_NAME = 'JOB_PLSQL_BLCOK_TEST';