oracle scheduler job 定时任务实操

本文详细介绍了Oracle数据库的schedulerJOB功能,包括定时任务的基础语法、创建存储过程创建job、查看运行状态、停止和启动操作,以及处理定时表达式和时区问题的实战与注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Oracle scheduler JOB 定时任务

定时任务

job是oracle的定时任务,又叫定时器,定时作业,作业定时地自动执行一些脚本,或作数据备份,或作数据提炼,或作数据库性能的优化,或作重建索引等等的工作,需要用到job。

Job是一种被调度执行的任务。Job可以是一个PL/SQL块、一个SQL语句、一个外部脚本或程序等。它们可以被定时调度执行,也可以被手动启动执行。

job定时任务还有另一种实现方式 scheduler,推荐后者,因为使用dbms_job提交的job在Oracle 10g及以上版本中已经被废弃,推荐使用dbms_scheduler包提交job。

基础语法

创建job

BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name        => 'job_name',           -- job的名称
    job_type        => 'PLSQL_BLOCK',        -- job的类型,可以是PLSQL_BLOCK、STORED_PROCEDURE等
    job_action      => 'begin my_proc(); end;',  -- job执行的脚本或存储过程
    start_date      => SYSTIMESTAMP,         -- job开始执行的时间
    repeat_interval => 'FREQ=DAILY; INTERVAL=1',  -- job执行的间隔时间
    enabled         => TRUE                  -- 是否启用job
  );
END;

查看Job运行情况

SELECT job_name, job_type, enabled, state, last_start_date, next_run_date
FROM dba_scheduler_jobs;


SELECT *
FROM dba_scheduler_jobs
WHERE job_name = 'JOB_NAME';

SELECT job_name, state, last_start_date, next_run_date,enabled
FROM dba_scheduler_jobs
WHERE job_name = 'JOB_NAME';
 

JOB 停止

BEGIN
  DBMS_SCHEDULER.STOP_JOB (
    job_name        => 'job_name',
    force_option    => 'IMMEDIATE',
    commit_semantics=> 'ABORT');
END;

JOB启动和删除

启动

BEGIN
  DBMS_SCHEDULER.RUN_JOB (
    job_name        => 'JOB_NAME',
    use_current_session => FALSE);
END;

删除

BEGIN
  DBMS_SCHEDULER.DROP_JOB (
    job_name        => 'CLEAN_REALTIME_ETCEXIT_DATA_JOB',           -- job的名称
    force           => FALSE                 -- 是否强制删除job
  );
END;

定时表达式

--每天运行一次
    'SYSDATE + 1'
 
--每小时运行一次
    'SYSDATE + 1/24'
 
--每10分钟运行一次                 
    'SYSDATE + 10/(60*24)'
 
--每30秒运行一次                    
    'SYSDATE + 30/(60*24*60)'
 
--每隔一星期运行一次               
    'SYSDATE + 7'
 
--每个月最后一天运行一次          
    'TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE,1))) + 23/24'
 
--每年1月1号零时                    
    'TRUNC(LAST_DAY(TO_DATE(EXTRACT(YEAR FROM SYSDATE)||'12'||'01','YYYY-MM-DD'))+1)'
 
--每天午夜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)'
 
--每个月最后一天的23点           
    'TRUNC (LAST_DAY (SYSDATE)) + 23 / 24'
 
--每个季度最后一天的晚上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)'

实战

创建存储过程

create or replace procedure REALTIME_ETCEXIT_DELETE as
begin
  DELETE FROM "REALTIME_ETCTS_EXIT";
  commit;
end;

创建 JOB

BEGIN
  DBMS_SCHEDULER.CREATE_JOB (
    job_name        => 'clean_realtime_etcexit_data_job',
    job_type        => 'STORED_PROCEDURE',
    job_action      => 'REALTIME_ETCEXIT_DELETE',
    start_date      => SYSDATE,
    repeat_interval => 'FREQ=DAILY; BYHOUR=0; BYMINUTE=0; BYSECOND=0',
    enabled         => TRUE,
    comments        => '清理过期数据');
END;

踩坑

oracle系统时间,会话时间,可能和你的本地时间不一样

实战发现影响定时任务时间的是会话时区,如果你使用的是 DataGrip 连接数据库,你可以在配置连接属性时设置 时区

image-20231103165926425

查看数据库系统时区

SELECT DBTIMEZONE FROM DUAL;

查看会话时区

select sessiontimezone from dual;

修改数据库时区

alter database set time_zone='+8:00';

然后重启数据库

修改会话时区

ALTER SESSION SET TIME_ZONE='+08:00';

重启数据库

  1. 登陆服务器
  2. 切换 oracle 用户
su - root
  1. 进入 sqlplus 控制台
sqlplus /nolog
  1. 以管理员身份登录
conn / as sysdba
  1. 关闭数据库
shutdown immediate
  1. 重启数据库
startup
  1. 退出控制台
exit

如果执行完上面操作后还是连接不上数据库(ORA-01109: database not open)

  • 进入sqlplus控制台
SQL> select con_id,name,open_mode from V$pdbs;

    CON_ID NAME                           OPEN_MODE
---------- ------------------------------ ----------
         3 ORCLPDB1                       MOUNTED

  • 将这个 mounted 的容器open
SQL> alter pluggable database ORCLPDB1 open;

Pluggable database altered.


这样就可以连接到数据库了


参考

Oracle 定时作业Job详解

Oracle中的定时任务–very good

Oracle12报错:ERROR at line 1: ORA-01109: database not open

### 创建和配置Oracle存储过程定时任务 #### 定义存储过程 为了现特定业务逻辑的作,首先需要定义一个存储过程。下面是一个简单的例子: ```sql CREATE OR REPLACE PROCEDURE test_procedure(in_num NUMBER) IS BEGIN DBMS_OUTPUT.PUT_LINE(in_num); -- 打印输入参数in_num的值[^3] END; / ``` 此段代码创建了一个名为`test_procedure`的过程,接受一个数值类型的参数并将其打印出来。 #### 声明和提交定时任务 接下来,在Oracle中可以通过DBMS_JOB包来安排这个存储过程按计划执行。这里展示如何设定一个每分钟触发的任务例: ```sql DECLARE job_number NUMBER; BEGIN DBMS_JOB.SUBMIT( job => job_number, what => 'test_procedure(19);', -- 调用之前创建好的存储过程,并传递参数19给它 next_date => TO_DATE('20240305 02:00','YYYYMMDD HH24:MI'), -- 设置首次启动时间为2024年3月5日早上两点整 interval => 'SYSDATE + 1/(24*60)' -- 表达式表示每隔一分钟重复一次该作业 ); COMMIT; -- 提交更改使新加入的工作生效 END; / ``` 这段脚本利用了`DBMS_JOB.SUBMIT()`函数向调度程序注册一个新的工作项。注意这里的`interval`字段指定了循环间隔为每一分钟;如果希望调整频率,则需修改此处的时间表达式。 对于更复杂的场景或更高版本的Oracle数据库(如12c及以上),推荐使用更为先进的`DBMS_SCHEDULER`组件代替传统的`DBMS_JOB`接口,因为前者提供了更加丰富的特性和更好的性能表现[^2]。 例如,采用`DBMS_SCHEDULER.CREATE_JOB`方法同样能完成上述功能: ```sql BEGIN SYS.DBMS_SCHEDULER.create_job ( job_name => 'MY_TEST_PROCEDURE_JOB', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN TEST_PROCEDURE(19); END;', start_date => TO_TIMESTAMP_TZ('2024-03-05 02:00:00 Asia/Shanghai'), repeat_interval => 'FREQ=MINUTELY;', -- 使用标准的日历表达式语法指定频次 enabled => TRUE ); END; / ``` 这种方法不仅支持跨时区的时间戳处理,还允许通过直观的日历模式字符串(`repeat_interval`)精确控制执行规律。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值