Oracle job的那些事

本文介绍如何使用Oracle内置的dbms_job包来实现定时任务,包括创建、修改和删除任务的方法,并详细解释了关键参数的作用。

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

 

      如果你想每天定时在Oracle里执行一个任务,比如统计表空间增长了多少, 并且把增长状况写入另一个统计表,应该怎么来做呢?

       用编程语言?如Java的Timer和TimerTask来执行定时任务。这种选择太麻烦,你还要单独去运行一个JVM让你的程序执行。能不能在Oracle内部来完成,而不需借助其他程序呢?当然可以。

      Oracle提供了dbms_job这个自带package来完成定时任务的创建(提交), 修改,运行等功能。你可以把你要做的工作写在一个PL/SQL (procedure,function等)里,然后创建一个job来执行这个PL/SQL块,并给出执行初始和间隔等参数:

     (1)

create or replace procedure  test_pro
as
begin
insert into test_table values(sysdate);
end;

     (2)

 

DECLARE
  X NUMBER;
BEGIN
  SYS.DBMS_JOB.SUBMIT
  ( job       => X
   ,what      => 'begin practice.test_pro;  end;'
   ,next_date => to_date('12-03-2011 23:58:00','dd/mm/yyyy hh24:mi:ss')
   ,interval  => 'TRUNC(SYSDATE) +1+ 23/24 + 58/1440'
   ,no_parse  => FALSE
  );

COMMIT;
END;
    可以了。

  其实第二步就是创建了一个匿名块,在这个块里调用了dbms_job这个package里procedure来提交任务. 后面来介绍这些参数的意义.

 

  首先,一个job能正常运行, 对Oracle环境的配置是有要求的:

(1) 保证Oracle不在受限会话状态(restricted session)运行,

     

select instance_name,logins from v$instance;
 

  如果 logins=RESTRICTED, 说明需要修改回话状态:

  

alter system disable restricted session;
 

(2) 系统参数JOB_QUEUE_PROCESSES必须大于0(不能超过1000):

   

   查看这个参数:

 

 

 

 

show parameter job_queue_processes
 

   修改:

  

alter system set job_queue_processes=20
  (3) 系统参数必须为true,保证系统的触发功能可以运行:

 

alter system set _SYSTEM_TRIG_ENABLED=true
   

 

以下是这个package所包含的主要procedure:

  submit:

   PROCEDURE Submit ( job   OUT binary_ineger,
            What   IN varchar2,
            next_date IN date,
            interval IN varchar2,
            no_parse IN booean:=FALSE)
  
  job,输出参数,由submit产生,它是job的标识号码。
  what,需要被执行的PL/SQL代码块。
  next_date,这个任务的下一次执行时间,是通过interval计算出来的。
  interval,日期表达式,如果为null,则任务只执行一次。
  no_parse,此工作在提交时或执行时是否应进行语法分析——TRUE指示此PL/SQL代码在它第一次执行时再进行语法分析,而FALSE指示本PL/SQL代码应立即进行语法分析。

   

     在第一次设置任务执行时间的时候,我把任务的固定时间执行和固定间隔执行搞混了,我想这是一个容易出错的地方。如,我想我的任务在每天晚上23点50分运行,来统计当天的数据。于是next_date我给的to_date('12-03-2011 23:58:00','dd/mm/yyyy hh24:mi:ss'),而interval给的trunc(sysdate) + 1,理所当然的以为 第一次执行后时间加一天嘛,第二天照样这个时候运行. 其实不是这样的, 任务的下一次运行时间(next_date)是在任务开始时计算出来, 它的值其实是interval表达式的值,而不是通过(上一次执行时间+interval)这样的方式得出来。按照我给定的值,第一次执行的时间是正确的,但是第一次执行是算出来的第二次执行时间是 trunc(sysdate)+ 1 即第二天的零点。所以后面的时间都是错的。正确的interval值应该是'TRUNC(SYSDATE) +1+ 23/24 + 58/1440',这样算出来才是第二天的晚上23点58分。关于任务的时间,可以参看:http://blog.youkuaiyun.com/li_guang/archive/2008/06/04/2510846.aspx

   

    remove
   PROCEDURE Remove(job IN binary_ineger);


    将一个job从任务队列里删除,参数:job的标识

 

     next_date

     PROCEDURE Next_Date(job     IN binary_ineger,
            next_date  IN date)

    手动设置任务的下一次运行时间

 

    Interval

     PROCEDURE Interval (job   IN binary_integer,


    设置任务执行时间的计算方法.

 

      Change

   PROCEDURE Change (job    IN binary_integer,
           What    IN varchar2,
           next_date IN date,
           interval  IN varchar2)

     修改一个任务

 

    Broken

    PROCEDURE Broken (job    IN binary_integer,
           Broken  IN boolean,
           next_date IN date :=SYSDATE)

    修改任务的状态,  true为可运行,false不可.

     run

     PROCEDURE run(job IN binary_ineger);

    立即运行一个任务

javaeye的这个文章编辑器太让人蛋疼了, 插入的代码格式全没了,我曰,辛辛苦苦写了这么久

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值