• 【JOB】Oracle中JOB的创建方法以及一个细节的探究


    在Oracle中可以使用JOB来实现一些任务的自动化执行,类似于UNIX操作系统crontab命令的功能。
    简单演示一下,供参考。

    1.创建表T,包含一个X字段,定义为日期类型,方便后面的定时任务测试。
    sec@
    ora10g> create table t (x date);

    Table created.

    2.创建存储过程p_insert_into_t,每次执行该存储过程都会向T表中插入一条
    系统当前时间。
    sec@
    ora10g> create or replace procedure p_insert_into_t
    2 as
    3 begin
    4 insert into t
    5 values (SYSDATE);
    6 end;
    7 /

    Procedure created.

    3.OK,准备就绪,我们来创建一个JOB,这个JOB会每分钟运行一次?需要注意一个细节!
    sec@
    ora10g> variable job_number number;
    sec@
    ora10g> begin
    2 DBMS_JOB.submit (:job_number,
    3 'P_INSERT_INTO_T;',
    4 SYSDATE,
    5 'sysdate+1/(24*60)');
    6 end;
    7 /

    PL/SQL procedure successfully completed.

    4.我们通过USER_JOBS视图查看一下创建的JOB信息。
    sec@
    ora10g> select job,
    2 log_user,
    3 to_char(last_date,'yyyy-mm-dd hh24:mi:ss') last_date,
    4 to_char(next_date,'yyyy-mm-dd hh24:mi:ss') next_date,
    5 interval,
    6 what
    7 from user_jobs
    8 /

    JOB LOG_USER LAST_DATE NEXT_DATE INTERVAL WHAT
    ------- -------- ------------------- ------------------- ----------------- ----------------
    27 SEC 2010-01-29 00:34:20 sysdate+1/(24*60) P_INSERT_INTO_T;


    细节之处在此,此处的LAST_DATE内容是空,表示此JOB没有被执行过,因此这个JOB将永远不会被自动的执行。
    这一点可以从T表没有数据来得到验证:
    sec@
    ora10g> select * from t;

    no rows selected

    那么,如何才能使它自动执行起来呢?
    很简单,只要我们手动将这个JOB执行一下即可。

    5.手工执行JOB一次,使之按照既定的
    时间间隔执行。
    sec@
    ora10g> execute dbms_job.run(27);

    PL/SQL procedure successfully completed.

    此时T表中将会被插入一条具有当前时间的数据。
    sec@
    ora10g> select * from t;

    X
    -------------------
    2010-01-29 00:37:42

    再次查看JOB的信息
    sec@
    ora10g> select job,
    2 log_user,
    3 to_char(last_date,'yyyy-mm-dd hh24:mi:ss') last_date,
    4 to_char(next_date,'yyyy-mm-dd hh24:mi:ss') next_date,
    5 interval,
    6 what
    7 from user_jobs
    8 /

    JOB LOG_USER LAST_DATE NEXT_DATE INTERVAL WHAT
    ------- -------- ------------------- ------------------- ----------------- ----------------
    27 SEC 2010-01-29 00:37:42 2010-01-29 00:38:42 sysdate+1/(24*60) P_INSERT_INTO_T;


    此时LAST_DATE显示了我们执行JOB的时间,同时NEXT_DATE显示了下次JOB将被执行的时间。此后这个JOB将会每隔一分钟被执行一次。
    自动执行一段时间后的T表内容如下:
    sec@
    ora10g> select * from t order by x;

    X
    -------------------
    2010-01-29 00:37:42
    2010-01-29 00:38:46
    2010-01-29 00:39:46
    2010-01-29 00:40:46
    2010-01-29 00:41:46
    2010-01-29 00:42:46
    2010-01-29 00:43:46
    2010-01-29 00:44:46
    2010-01-29 00:45:46
    2010-01-29 00:46:46
    2010-01-29 00:47:46
    2010-01-29 00:48:46
    2010-01-29 00:49:46
    2010-01-29 00:50:46
    2010-01-29 00:51:46
    2010-01-29 00:52:46

    16 rows selected.

    6.为什么刚刚创建后的JOB不能自动的执行呢?
    这是一个疏忽导致的!
    在创建JOB的时候,需要在结尾处指定“COMMIT;”!表示创建完成之后便执行一次。
    删除之前的JOB,重新创建一个带有“COMMIT”语句的新JOB。
    sec@
    ora10g> variable job_number number;
    sec@
    ora10g> begin
    2 DBMS_JOB.submit (:job_number,
    3 'P_INSERT_INTO_T;',
    4 SYSDATE,
    5 'sysdate+1/(24*60)');
    6 commit;
    7 end;
    8 /

    sec@ora10g> print job_number;

    JOB_NUMBER
    ----------
    29

    此次创建的JOB信息如下,可见LAST_DATE在创建完之后便有内容,表示已经被执行了一次。
    sec@
    ora10g> select job,
    2 log_user,
    3 to_char(last_date,'yyyy-mm-dd hh24:mi:ss') last_date,
    4 to_char(next_date,'yyyy-mm-dd hh24:mi:ss') next_date,
    5 interval,
    6 what
    7 from user_jobs
    8 /

    JOB LOG_USER LAST_DATE NEXT_DATE INTERVAL WHAT
    ------- -------- ------------------- ------------------- ----------------- ----------------
    29 SEC 2010-01-29 01:02:11 2010-01-29 01:03:11 sysdate+1/(24*60) P_INSERT_INTO_T;


    一分钟过后便可看到T表中已有两条记录。
    sec@
    ora10g> select * from t;

    X
    -------------------
    2010-01-29 01:02:11
    2010-01-29 01:03:11

    7.删除JOB方法
    很简单,使用“dbms_job.remove”即可。
    sec@
    ora10g> execute dbms_job.remove(29);

    PL/SQL procedure successfully completed.

    8.最后,谈一下创建JOB时用到的参数。
    1)使用desc命令查看DBMS_JOB,可以得到SUBMIT这个存储过程的参数列表。
    sec@
    ora10g> desc DBMS_JOB
    ...
    PROCEDURE SUBMIT
    Argument Name Type In/Out Default?
    ------------------------------ ----------------------- ------ --------
    JOB BINARY_INTEGER OUT
    WHAT VARCHAR2 IN
    NEXT_DATE DATE IN DEFAULT
    INTERVAL VARCHAR2 IN DEFAULT
    NO_PARSE BOOLEAN IN DEFAULT
    INSTANCE BINARY_INTEGER IN DEFAULT
    FORCE BOOLEAN IN DEFAULT
    ...

    2)如果希望对这些参数有更好的理解,可以参考Oracle的官方文档描述,细致而周到。
    http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_job.htm#sthref2936

    3)重点关注一下官方文档中关于INTERVAL参数的示例
    'sysdate + 7'表示一周执行一次;
    'next_day(sysdate,''TUESDAY'')' 表示每周二执行一次;
    'null'表示只执行一次。

    本文中我使用的是'sysdate+1/(24*60)'表示每分钟执行一次。很形象,一天的二十四分之一是一小时,一小时的六十分之一就是一分钟的意思。

    9.小结
    通过这个文章和大家分享了一点关于JOB的创建方法和使用,希望对大家有帮助。
    细节不容错过!

    Good luck.

    secooler
    10.01.28

    -- The End --

  • 相关阅读:
    Web 前端开发中一些兼容性问题及其解决办法 (持续更)
    沈逸的IT专栏---shenyisyn
    程序员该做的事
    职场需要切忌的几点——《程序员,你伤不起》
    百度天气API接口
    C#简单音乐播放器ListBox歌单列表
    CentOS7 安装java(jre 1.8)
    CentOS7 系统安装与设置
    这个可以有,记录下
    在centos 7中让网卡自启动
  • 原文地址:https://www.cnblogs.com/mengyuxin/p/5038579.html
Copyright © 2020-2023  润新知