Oracle 定时任务详解(dbms_scheduler)

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 每月第一天早上830分执行一次
   
   (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';
DBMS_SCHEDULEROracle数据库中的一个内置程序包,用于管理和调度作业、程序和链。它是Oracle Scheduler的主要接口,可以通过它来创建、修改和删除作业、程序和链,以及控制它们的执行时间和执行方式。 下面是一些DBMS_SCHEDULER的常见用法: 1. 创建作业 使用DBMS_SCHEDULER.CREATE_JOB过程可以创建作业。在创建作业时,需要指定作业名称、作业类型、作业所属的程序等信息。 2. 修改作业 使用DBMS_SCHEDULER.SET_ATTRIBUTE过程可以修改作业的属性,如作业的状态、开始时间、结束时间等。 3. 删除作业 使用DBMS_SCHEDULER.DROP_JOB过程可以删除作业。 4. 运行作业 使用DBMS_SCHEDULER.RUN_JOB过程可以手动运行作业。 5. 暂停作业 使用DBMS_SCHEDULER.DISABLE过程可以暂停作业的执行。 6. 恢复作业 使用DBMS_SCHEDULER.ENABLE过程可以恢复暂停的作业。 7. 创建程序 使用DBMS_SCHEDULER.CREATE_PROGRAM过程可以创建程序。在创建程序时,需要指定程序名称、程序类型、程序所属的语言等信息。 8. 修改程序 使用DBMS_SCHEDULER.SET_PROGRAM_ARGUMENT_VALUE过程可以修改程序的参数值。 9. 删除程序 使用DBMS_SCHEDULER.DROP_PROGRAM过程可以删除程序。 10. 创建链 使用DBMS_SCHEDULER.CREATE_CHAIN过程可以创建链。在创建链时,需要指定链名称、链包含的步骤等信息。 11. 修改链 使用DBMS_SCHEDULER.SET_CHAIN_STEP_ATTRIBUTE过程可以修改链的步骤属性,如步骤名称、步骤类型、步骤所属的程序等。 12. 删除链 使用DBMS_SCHEDULER.DROP_CHAIN过程可以删除链。 以上是一些DBMS_SCHEDULER的常见用法,具体使用方法可参考Oracle官方文档。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼丸丶粗面

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值