文章目录
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';

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐