DBMS_JOB 和 DBMS_SCHEDULER 系统包是传统 Oracle 数据库中用于实现自动化任务的两种机制。OceanBase 数据库在 V3.2 版本 Oracle 模式租户中实现了 Oracle 兼容的 DBMS_JOB 系统包,该系统包实现了基础的调度功能,用于部分客户场景的 POC。当前 DBMS_JOB 包的实现还存在诸多不足,比如可能漏调度、调度请求无法准确发送等,因此该包在发布版本之初也明确标注仅限 POC。在 OceanBase 数据库 V4.2.1 版本中,OceanBase 实现了 Oracle 兼容的 DBMS_SCHEDULER 系统包,该包基本可以替代 DBMS_JOB 包的功能,当前已经达到上线标准,且在业务系统中有上线应用。推荐使用 DBMS_SCHEDULER 包替换传统的 DBMS_JOB 包(后续可能会废弃 DBMS_JOB 包)。
本文主要介绍如何在 OceanBase 数据库 Oracle 模式租户中创建一个 JOB 以及常用的操作方式。
操作指南
示例一
-- 表和程序包和 JOB 都要创建一个用户下,不同用户之间无法调用 JOB
drop table test;
create table test (id1 number);
CREATE OR REPLACE PACKAGE PKG_TEST1 AS
PROCEDURE P_TEST(p_id NUMBER);
END PKG_TEST1;
CREATE OR REPLACE PACKAGE BODY PKG_TEST1 AS
PROCEDURE P_TEST(p_id NUMBER) AS
BEGIN
INSERT INTO TEST (id1) VALUES (p_id);
END ;
END PKG_TEST1;
-- 创建 JOB
BEGIN
DBMS_SCHEDULER.create_job(job_name => 'job_test',
job_type => 'STORED_PROCEDURE',
job_action => 'PKG_TEST1.P_TEST(1)',
-- start_date => '2025-11-14 12:00:00', -- 如果要设置具体时间需要设置 NLS_TIMESTMAP_FORMAT
start_date => SYSTIMESTAMP,
repeat_interval => 'FREQ=DAILY;INTERVAL=1;BYHOUR=23;BYMINUTE=59;BYSECOND=0', -- 这边表示每天 23:59:00 会调用一次 JOB
comments =>'test' ,
max_run_duration => 60, -- max_run_duration 指定了该作业允许运行的最长时间,单位为 s,一般在 dbms_scheduler.create_job() 时可以指定,如果不指定的话,默认值为 0(代码实现会转为 30s)
enabled => FALSE, -- 是否启用作业
auto_drop => FALSE);
END;
/
-- 运行 JOB,如果该作业已启用,Scheduler 将自动运行该作业,不必调用 RUN_JOB 来按照作业的时间表运行作业。
-- 只调用 RUN_JOB 运行在正常计划之外的作业。
BEGIN
DBMS_SCHEDULER.RUN_JOB(
JOB_NAME => 'job_test',
force => TRUE);
END;
/
-- 删除 JOB
BEGIN
DBMS_SCHEDULER.DROP_JOB(job_name => 'job_test');
END;
/
-- 业务租户查看 JOB 运行情况
SELECT JOB_NAME,enabled,NEXT_RUN_DATE,state,last_start_date FROM DBA_SCHEDULER_JOBS;
示例二
-- 创建测试表
CREATE TABLE jobtab(col timestamp);
-- 创建存储过程为作业添加步骤
CREATE OR REPLACE PACKAGE JOB_UTILS IS
PROCEDURE insert_time;
END
/
CREATE OR REPLACE PACKAGE BODY JOB_UTILS IS
PROCEDURE insert_time IS
BEGIN
INSERT INTO jobtab VALUES(systimestamp);
COMMIT;
END;
END
/
-- 创建作业
BEGIN
DBMS_SCHEDULER.CREATE_JOB(job_name => 'my_job',
job_type => 'STORED_PROCEDURE',
job_action => 'JOB_UTILS.insert_time',
number_of_argument => 0,
start_date => sysdate + 1 / 1440,
repeat_interval => 'FREQ=SECONDLY; INTERVAL=8',
end_date => sysdate + 100 / 1440,
job_class => 'DEFAULT_JOB_CLASS',
enabled => true,
auto_drop => true);
COMMIT;
END
/
-- 修改作业的属性
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE('my_job', 'MAX_RUN_DURATION', '3600');
END;
/
-- 删除作业
BEGIN
DBMS_SCHEDULER.DROP_JOB(job_name => 'my_job');
COMMIT;
END
/
适用版本
OceanBase 数据库 V4.2.1 GA(oceanbase-4.2.1.0-100000182023092722)及更高版本的 Oracle 模式租户。