zoukankan      html  css  js  c++  java
  • Oracle中job的实例

    一、Oracle定时器(Job)各时间段写法汇总

    对于DBA来说,数据库Job再熟悉不过了,因为经常要数据库定时的自动执行一些脚本,或做数据库备份,或做数据的提炼,或做数据库的性能优化,包括重建索引等等的工作。但是,Oracle定时器Job时间的处理上,千变万化,今天我把比较常用写法汇总如下:

    在总结之前,先把Job的参数一一说明一下:

    job参数是由Submit()过程返回的binary_ineger。这个值用来唯一标识一个工作;

    what参数是将被执行的PL/SQL代码块;

    next_date参数指识何时将运行这个工作。写Job的时候可以不指定该值;

    interval参数何时这个工作将被重执行。

    其中Interval这个值是决定Job何时,被重新执行的关键。

    例如:有存储过程 p_dosomethings,需要被不同的时间间隔执行。

    1declare   
    2   jobno number;   
    3begin   
    4   dbms_job.submit(
    5     jobno,
    6    'p_dosomething;',  --what
    7     to_date('20090101020000','yyyy-mm-dd hh24:mi:ss'),--next_date,可以不填
    8    'Interval时间字符串'--interval,关键设置
    9   );   
    10   commit;   
    11end;
    12

    1、 每分钟执行

    Interval => TRUNC(sysdate,’mi’)+ 1 / (24*60)

    2、 每天定时执行

    例如:每天的凌晨2点执行

    Interval => TRUNC(sysdate) + 1 +2 / 24

    3、 每周定时执行

    例如:每周一凌晨2点执行

    Interval => TRUNC(next_day(sysdate,'星期一'))+2/24

    4、 每月定时执行

    例如:每月1日凌晨2点执行

    Interval =>TRUNC(LAST_DAY(SYSDATE))+1+2/24

    5、 每季度定时执行

    例如每季度的第一天凌晨2点执行

    Interval => TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 2/24

    6、 每半年定时执行

    例如:每年7月1日和1月1日凌晨2点

    Interval => ADD_MONTHS(trunc(sysdate,'yyyy'),6)+2/24

    7、 每年定时执行

    例如:每年1月1日凌晨2点执行

    Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),6)+2/24

    一、  oracle job

    下午mumu问我,如何终止一个正在执行的job,我当时也没有想起来(或者说,以前都是run,而没有romove过),所以就上网找了一下,感觉下面写的还不错,就收了起来,呵呵~~~~

    ORACLE中JOB的应用
    1、创建存储过程
    create or replace procedure *pro_name
    as
    begin
    insert into agri_exhibition_basecur (messid,title,type,pub_date)

    select id,title,sort,pub_date

    from agri_message

    where (trunc(sysdate-pub_date)=0 and rownum<6) and sort='供' ;
    insert into agri_exhibition_basecur (messid,title,type,pub_date)

     select id,title,sort,pub_date

    from agri_message where (trunc(sysdate-pub_date)=0 and rownum<6) andsort='求' ;
    end;
    /
    2、创建JOB
    variable jobdxm number;
    begin
    dbms_job.submit(:jobdxm,'exhi_pro_dxm;',sysdate,'trunc(sysdate,''dd'')+32.5/24');
    end;

    一个简单的JOB实列
    1、创建测试表
    SQL> create table a(a date);

    表已创建。

    2、创建一个自定义过程
    SQL> create or replace procedure test as
    2 begin
    3 insert into a values(sysdate);
    4 end;
    5 /

    过程已创建。

    3、创建JOB
    SQL> variable job1 number;
    SQL>
    SQL> begin
    2 dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');  --每天1440分钟,即一分钟运行test过程一次
    3 end;
    4 /

    PL/SQL 过程已成功完成。

    4、运行JOB
    SQL> begin
    2 dbms_job.run(:job1);
    3 end;
    4 /

    PL/SQL 过程已成功完成。

    SQL> select  to_char(a,'yyyy/mm/ddhh24:mi:ss') 时间  froma;

    时间
    -------------------
    2001/01/07 23:51:21
    2001/01/07 23:52:22
    2001/01/07 23:53:24

    5、删除JOB
    SQL> begin
    2 dbms_job.remove(:job1);
    3 end;
    4 /

    PL/SQL 过程已成功完成。
    6、一些必要的参数
    修改initsid.ora参数
    job_queue_processes = 4
    job_queue_interval = 10
    job_queue_keep_connections=true

    修改可执行作业个数为20个
    ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 20

    修改取消限制模式
    ALTER SYSTEM DISABLE RESTRICTED SESSION;

    7、两个必要的表
    user_jobs及dba_jobs_running

    8、相关的几个JOB操作
    删除job:dbms_job.remove(jobno);
    修改要执行的操作:job:dbms_job.what(jobno,what);
    修改下次执行时间:dbms_job.next_date(job,next_date);
    修改间隔时间:dbms_job.interval(job,interval);
    停止job:dbms.broken(job,broken,nextdate);
    启动job:dbms_job.run(jobno);

    二、OracleJOB 用法小结

    (一)、设置初始化参数 job_queue_processes
      sql> alter system set job_queue_processes=n;(n>0)
      job_queue_processes最大值为1000
      
      查看job queue 后台进程
      sql>select name,description from v$bgprocess;
      
      (二),dbms_job package 用法介绍
      包含以下子过程:
      
      Broken()过程。
      change()过程。
      Interval()过程。
      Isubmit()过程。
      Next_Date()过程。
      Remove()过程。
      Run()过程。
      Submit()过程。
      User_Export()过程。
      What()过程。
      
      1、Broken()过程更新一个已提交的工作的状态,典型地是用来把一个已破工作标记为未破工作。
      这个过程有三个参数:job 、broken与next_date。
      
      PROCEDURE Broken ( job    INbinary_integer,
                 Broken  IN boolean,
                 next_date   IN date :=SYSDATE)
      
      job参数是工作号,它在问题中唯一标识工作。
      broken参数指示此工作是否将标记为破——TRUE说明此工作将标记为破,而FLASE说明此工作将标记为未破。
      next_date参数指示在什么时候此工作将再次运行。此参数缺省值为当前日期和时间。
      job如果由于某种原因未能成功之行,oracle将重试16次后,还未能成功执行,将被标记为broken重新启动状态为broken的job,

    有如下两种方式;
      a、利用dbms_job.run()立即执行该job
        sql>begin
        sql>dbms_job.run(:jobno) 该jobno为submit过程提交时返回的job number
        sql>end;
        sql>/
      b、利用dbms_job.broken()重新将broken标记为false
        sql>begin
        sql>dbms_job.broken (:job,false,next_date)
        sql>end;
        sql>/
      2、Change()过程用来改变指定工作的设置。
      这个过程有四个参数:job、what 、next_date与interval。
      
      PROCEDURE Change ( job    INbinary_integer,
                 What    IN varchar2,
                 next_date  IN date,
                 interval    IN varchar2)
      
      此job参数是一个整数值,它唯一标识此工作。
      What参数是由此工作运行的一块PL/SQL代码块。
      next_date参数指示何时此工作将被执行。
      interval参数指示一个工作重执行的频度。
      
      3、Interval()过程用来显式地设置重执行一个工作之间的时间间隔数。这个过程有两个参数:job与interval。
      
      PROCEDURE Interval ( job   INbinary_integer,
                Interval   IN varchar2)
      
      job参数标识一个特定的工作。interval参数指示一个工作重执行的频度。
      
      4、ISubmit()过程用来用特定的工作号提交一个工作。这个过程有五个参数:job、what、next_date、interval与no_parse。
      
      PROCEDURE ISubmit ( job    INbinary_ineger,
                 What   IN varchar2,
                 next_date IN date,
                 interval   IN varchar2,
                 no_parse  IN booean:=FALSE)
      
      这个过程与Submit()过程的唯一区别在于此job参数作为IN型参数传递且包括一个由开发者提供的工作号。如果提供的工作号已被使用,将产生一个错误。
      
      5、Next_Date()过程用来显式地设定一个工作的执行时间。这个过程接收两个参数:job与next_date。
      
      PROCEDURE Next_Date( job     INbinary_ineger,
                   next_date  IN date)
      job标识一个已存在的工作。next_date参数指示了此工作应被执行的日期与时间。
      
      6、Remove()过程来删除一个已计划运行的工作。这个过程接收一个参数:
      
      PROCEDURE Remove( job IN binary_ineger);
      
      job参数唯一地标识一个工作。这个参数的值是由为此工作调用Submit()过程返回的job参数的值。

    已正在运行的工作不能由调用过程序删除。
      
      7、Run()过程用来立即执行一个指定的工作。这个过程只接收一个参数:
      
      PROCEDURE Run(job IN binary_ineger)
      
      job参数标识将被立即执行的工作。
      
      8、使用Submit()过程,工作被正常地计划好。
      这个过程有五个参数:job、what、next_date、interval与no_parse。
      
      PROCEDURE Submit (  job    OUT  binary_ineger,
                  What   IN   varchar2,
                  next_date IN   date,
                  interval   IN   varchar2,
                  no_parse  IN  booean:=FALSE)
      
      job参数是由Submit()过程返回的binary_ineger。这个值用来唯一标识一个工作。
      what参数是将被执行的PL/SQL代码块。
      next_date参数指识何时将运行这个工作。
      interval参数何时这个工作将被重执行。
      no_parse参数指示此工作在提交时或执行时是否应进行语法分析——TRUE指示此PL/SQL代码在它第一次执行时

    应进行语法分析,而FALSE指示本PL/SQL代码应立即进行语法分析。
      
      9、User_Export()过程返回一个命令,此命令用来安排一个存在的工作以便此工作能重新提交。
      此程序有两个参数:job与my_call。
      
      PROCEDURE User_Export( job    IN binary_ineger,
                   my_call  IN  OUT  varchar2)
      
      job参数标识一个安排了的工作。my_call参数包含在它的当前状态重新提交此工作所需要的正文。
      
      10、What()过程应许在工作执行时重新设置此正在运行的命令。这个过程接收两个参数:job与what。
      
      PROCEDURE What ( job  IN  binary_ineger,
                What  IN  OUTvarchar2)
      job参数标识一个存在的工作。what参数指示将被执行的新的PL/SQL代码。
      
      三、查看相关job信息
      1、相关视图
      dba_jobs
      all_jobs
      user_jobs
      dba_jobs_running 包含正在运行job相关信息
      
      2、查看相关信息
      
      SQL>SELECT JOB, NEXT_DATE, NEXT_SEC, FAILURES,BROKEN
      SQL>FROM DBA_JOBS;
      
      JOB NEXT_DATE NEXT_SEC FAILURES B
      ------- --------- -------- -------- -
      9125 01-JUN-01 00:00:00 4 N
      14144 24-OCT-01 16:35:35 0 N
      9127 01-JUN-01 00:00:00 16 Y
      3 rows selected.
      
      正在运行的JOB相关信息
      
      SELECT SID, r.JOB, LOG_USER, r.THIS_DATE, r.THIS_SEC
      FROM DBA_JOBS_RUNNING r, DBA_JOBS j
      WHERE r.JOB = j.JOB;
      
      SID JOB LOG_USER THIS_DATE THIS_SEC
      ----- ---------- ------------- --------- --------
      12 14144 HR 24-OCT-94 17:21:24
      25 8536 QS 24-OCT-94 16:45:12
      2 rows selected.
      
      JOB QUEUE LOCK相关信息
      
      SELECT SID, TYPE, ID1, ID2
      FROM V$LOCK
      WHERE TYPE = 'JQ';
      
      SID TY ID1 ID2
      --------- -- --------- ---------
      12 JQ 0 14144
      1 row selected.
      
      四、简单例子
      一个简单例子:
      
      创建测试表
      SQL> create table TEST(a date);
      
      表已创建。
      
      创建一个自定义过程
      SQL> create or replace procedure MYPROC as
       2 begin
       3 insert into TEST values(sysdate);
       4 end;
       5 /
      
      过程已创建。
      
      创建JOB
      SQL> variable job1 number;
      SQL>
      SQL> begin
       2dbms_job.submit(:job1,'MYPROC;',sysdate,'sysdate 1/1440');  

    --每天1440分钟,即一分钟运行test过程一次
       3 end;
       4 /
      
      PL/SQL 过程已成功完成。
      
      运行JOB
      SQL> begin
       2 dbms_job.run(:job1);
       3 end;
       4 /
      
      PL/SQL 过程已成功完成。
      
      SQL> select to_char(a,'yyyy/mm/dd hh24:mi:ss') 时间 from TEST;
      
      时间
      -------------------
      2001/01/07 23:51:21
      2001/01/07 23:52:22
      2001/01/07 23:53:24
      
      删除JOB
      SQL> begin
       2 dbms_job.remove(:job1);
       3 end;
       4 / 网管bitscn_com
      
      PL/SQL 过程已成功完成。

       

    三、   JOB——手工指定Oracle中job执行的时间间隔

    (一)、JOB时间间隔的问题

    我们MIS系统中需要建立一些JOB,比如客户会要求在月底自动生成一些报表统计信息。

    在指定JOB的执行时间时,一般我们会选择在每月月底的午夜来执行(或者有多个JOB,应该分散在不同的时间段来执行)。

    此时不能直接用sysdate来确定时间,因为每次执行后,oracle自动生成的下一次的执行时间,会有几秒的延迟。

    比如,我指定第一次执行时间为:2008-03-27 10:58:01,时间间隔的方式为:last_day(add_months(sysdate, 1))。

    那么,JOB执行后我会发现,第一次的执行时间是2008-03-2710:58:05,而下一次的执行时间被更新

    为2008-04-30 10:58:05;而下次执行后,发现它的执行时间是2008-04-3010:58:07,而它再次执行的时间

    变为2008-05-31 10:58:07;……

    (二)、可能原因

    (1)JOB的调用有时间延迟。我指定在10:58:01执行,可是由于延迟,真正执行的时间是10:58:05;

    (2)根据实际的执行时间来自动计算下一次的执行时间。我指定下一次的时间计算方法

    是last_day(add_months(sysdate, 1))。但它是根据10:58:05来计算的,而不是10:58:01。

    (三)、解决办法

    这种延迟累计起来,就可能导致执行时间错误!为避免这种延迟,我们应该手工指定执行时间中的“时分秒”。比如,

    每月月底的午夜:

    last_day( add_months(to_date( to_char( sysdate, 'yyyy-mm-dd' ), 'yyyy-mm-dd' ), 1 ) )

    每月的任意指定时间:

    last_day( add_months(to_date( to_char( sysdate, 'yyyy-mm-dd')||' 11:24:31', 'yyyy-mm-dd hh24:mi:ss' ),1 ) )

    ……

    这样,每次执行的时间大概会比指定的时间延迟2-5秒,但oracle自动计算出来的下一次执行时间是没有问题的,

    所以不会累计这个延迟。

    (四)、相关测试

    下面是一个小测试:

    SQL> conn tianyc/test
    已连接。

    SQL>select * from v$version;

    BANNER
    -----------------------------------------------------------
    Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
    PL/SQL Release 9.2.0.1.0 - Production
    CORE    9.2.0.1.0       Production
    TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
    NLSRTL Version 9.2.0.1.0 - Production

    --1. 创建初始环境

    --1.1 创建表test_job,存放执行日期

    SQL>create table test_job ( a date );

    表已创建。

    --1.2 创建过程,向表test_job中插入执行时的日期

    SQL>CREATE  OR  REPLACE  PROCEDURE

    PRC_TEST_JOB(PRM_A          IN   DATE,
    2                   PRM_APPCODE   OUT  NUMBER,
    3                   PRM_ERRORMSG OUT  VARCHAR2)
    4  IS
    5  BEGIN
    6    PRM_APPCODE := 1;
    7    PRM_ERRORMSG := 'succeed';
    8    INSERT INTO test_job VALUES(prm_a);
    9    COMMIT;
    10  END PRC_TEST_JOB;
    11
    12 /

    过程已创建。

    --2. 创建任务

    --2.1 查看当前时间,用来确定创建的任务的执行时间

    SQL>select  to_char( sysdate, 'yyyy-mm-ddhh24:mi:ss' )  from  dual;

    TO_CHAR(SYSDATE,'YY
    -------------------
    2008-03-27 10:52:20

    --2.2 创建任务,调用步骤1.2中创建的过程。在10:58:01时执行。
    SQL> variable  x  number;
    SQL> begin
    2    sys.dbms_job.submit(job => :x,
    3                       what=> 'DECLARE
    4                                n_appcodeNUMBER(10);
    5                                v_errormsgVARCHAR2(4000);
    6                                BEGIN
    7                                   prc_test_job(SYSDATE, n_appcode, v_errormsg);
    8                                END;',
    9                        next_date  =>  to_date('27-03-2008 10:58:01', 'dd-mm-yyyyhh24:mi:ss'),
    10                       interval  =>  'last_day( add_months( sysdate, 1 ) )' );
    11    commit;
    12 end;
    13 /

    PL/SQL 过程已成功完成。

    --3. 验证数据

    --3.1 在该执行时间之前没有数据

    SQL>select * from test_job;

    未选定行

    SQL>select  to_char( sysdate, 'yyyy-mm-ddhh24:mi:ss' )  from  dual;

    TO_CHAR(SYSDATE,'YY
    -------------------
    2008-03-27 10:57:46

    --3.2 过了该时间后,可以查询到数据

    SQL>select  to_char( sysdate, 'yyyy-mm-ddhh24:mi:ss' )  from  dual;

    TO_CHAR(SYSDATE,'YY
    -------------------
    2008-03-27 10:58:18

    SQL>select  to_char( a, 'yyyy-mm-ddhh24:mi:ss' )  from  test_job;

    TO_CHAR(A,'YYYY-MM-
    -------------------
    2008-03-27 10:58:05

    --3.3 任务执行完毕后,自动根据条件(INTERVAL)更新下次的执行时间(NEXT_DATE)

    SQL>select  PRIV_USER, LAST_DATE, NEXT_DATE,INTERVAL  from  user_jobs;

    PRIV_USER                     LAST_DATE NEXT_DATE INTERVAL
    ------------------------------ ---------- --------------------------------------------
    TIANYC                        27-3月 -08 30-4月 -08last_day(add_months(sysdate, 1))

    SQL>select  what  from  user_jobs;

    WHAT
    -------------------------------------------------------------------------------
    DECLARE
                      n_appcode NUMBER(10);
                      v_errormsg VARCHAR2(4000);
                      BEGIN
                         prc_test_job(SYSDATE, n_appcode,v_errormsg);
                      END;

    SQL>
    -- 4. 存在问题:

    --4.1 test_job里的执行时间不是10:58:01, 而是10:58:05:

    SQL> select  to_char( a,'yyyy-mm-dd hh24:mi:ss' )  from  test_job;

    TO_CHAR(A,'YYYY-MM-
    -------------------
    2008-03-27 10:58:05

    --4.2 在视图user_jobs里也是如此。把这两个时间精确到秒,看看效果:

    SQL>select  PRIV_USER,  to_char( LAST_DATE, 'yyyy-mm-dd hh24:mi:ss' ),
    2   to_char( NEXT_DATE, 'yyyy-mm-dd hh24:mi:ss' ), INTERVAL  from  user_jobs;

    PRIV_USERTO_CHAR(LAST_DATE,' TO_CHAR(NEXT_DATE,' INTERVAL
    ---------- ------------------- ---------------------------------------------------
    TIANYC     2008-03-27 10:58:052008-04-30 10:58:05  last_day(add_months(sysdate,1))
              
    SQL>

    --4.3 经过多次测试,每次执行时并不是按照上次指定的秒执行的,而是滞后几秒。

    这样累计起来,就可能导致执行日期的错误。

    --    所以要想每次都精确地按照秒来执行job,应该手工来指定时间。比如:

    --4.3.1 在每个月的月底的午夜执行

    SQL>select  to_char( last_day( add_months( to_date(to_char( sysdate, 'yyyy-mm-dd' ), 'yyyy-mm-dd' ), 1 ) )

    , 'yyyy-mm-dd hh24:mi:ss' ) fromdual;

    TO_CHAR(LAST_DAY(AD
    -------------------
    2008-04-30 00:00:00

    --4.3.2 在每个月的月底的任意指定时间执行(这里我指定时间为11:24:31)

    SQL>select  to_char( last_day( add_months( to_date(to_char( sysdate, 'yyyy-mm-dd')||' 11:24:31',

    'yyyy-mm-dd hh24:mi:ss' ), 1 ) ),'yyyy-mm-dd hh24:mi:ss' )  from  dual;

    TO_CHAR(LAST_DAY(AD
    -------------------
    2008-04-30 11:24:31

    SQL>

     

    四、  关于OracleJob 语法和时间间隔的设定

    sys.dbms_job.submit(job=> :job,
    what => 'P_CLEAR_PACKBAL;',
    next_date => to_date('24-04-2008 05:44:09', 'dd-mm-yyyy hh24:mi:ss'),
    interval => 'sysdate+ 1/360');
    commit;
    end;
    /

    1:每分钟执行

    Interval =>TRUNC(sysdate,'mi') + 1/ (24*60)

    2:每天定时执行

    例如:每天的凌晨1点执行

    Interval =>TRUNC(sysdate) + 1 +1/ (24)

    3:每周定时执行

    例如:每周一凌晨1点执行

    Interval =>TRUNC(next_day(sysdate,'星期一'))+1/24

    4:每月定时执行

    例如:每月1日凌晨1点执行

    Interval=>TRUNC(LAST_DAY(SYSDATE))+1+1/24

    5:每季度定时执行

    例如每季度的第一天凌晨1点执行

    Interval =>TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24

    6:每半年定时执行

    例如:每年7月1日和1月1日凌晨1点

    Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24

    7:每年定时执行

    例如:每年1月1日凌晨1点执行

    Interval=>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24

    五、  Oracle Job 语法和时间间隔的设定(转)

    初始化相关参数job_queue_processes
    alter  system  set  job_queue_processes=39 scope=spfile;

    //最大值不能超过1000;job_queue_interval = 10 //调度作业刷新频率秒为单位

    job_queue_process 表示Oracle能够并发的job的数量,可以通过语句  

    show  parameter  job_queue_process;

    来查看oracle中job_queue_process的值。当job_queue_process值为0时表示全部停止oracle的job,可以通过语句

    ALTER  SYSTEM  SET job_queue_processes = 10;

    来调整启动oracle的job。

    相关视图:
    dba_jobs
    all_jobs
    user_jobs
    dba_jobs_running 包含正在运行job相关信息

    -------------------------

    提交job语法:

    begin
    sys.dbms_job.submit(job => :job,
                         what => 'P_CLEAR_PACKBAL;',
                         next_date => to_date('04-08-2008 05:44:09', 'dd-mm-yyyy hh24:mi:ss'),
                         interval => 'sysdate+ 1/360');
    commit;
    end;
    /

    -------------------------
    创建JOB
    variable jobno number;
    begin
    dbms_job.submit(:jobno, 'P_CRED_PLAN;',SYSDATE,'SYSDATE+1/2880',TRUE);
    commit;

    运行JOB
    SQL> begin
             dbms_job.run(:job1);
             end;
             /

    删除JOB
    SQL> begin
            dbms_job.remove(:job1);
            end;
            /

    DBA_JOBS
    ===========================================
    字段(列)         类型                描述
    JOB               NUMBER          任务的唯一标示号
    LOG_USER          VARCHAR2(30)   提交任务的用户
    PRIV_USER         VARCHAR2(30)    赋予任务权限的用户
    SCHEMA_USER      VARCHAR2(30)    对任务作语法分析的用户模式
    LAST_DATE         DATE           最后一次成功运行任务的时间
    LAST_SEC          VARCHAR2(8)     如HH24:MM:SS格式的last_date日期的小时,分钟和秒
    THIS_DATE         DATE           正在运行任务的开始时间,如果没有运行任务则为null
    THIS_SEC           VARCHAR2(8)    如HH24:MM:SS格式的this_date日期的小时,分钟和秒
    NEXT_DATE        DATE            下一次定时运行任务的时间
    NEXT_SEC          VARCHAR2(8)    如HH24:MM:SS格式的next_date日期的小时,分钟和秒
    TOTAL_TIME       NUMBER         该任务运行所需要的总时间,单位为秒
    BROKEN           VARCHAR2(1)     标志参数,Y标示任务中断,以后不会运行
    INTERVAL          VARCHAR2(200)  用于计算下一运行时间的表达式
    FAILURES           NUMBER         任务运行连续没有成功的次数
    WHAT             VARCHAR2(2000)  执行任务的PL/SQL块
    CURRENT_SESSION_LABEL RAW         MLSLABEL 该任务的信任Oracle会话符
    CLEARANCE_HI      RAW MLSLABEL    该任务可信任的Oracle最大间隙
    CLEARANCE_LO     RAW             MLSLABEL 该任务可信任的Oracle最小间隙
    NLS_ENV           VARCHAR2(2000)   任务运行的NLS会话设置
    MISC_ENV           RAW(32)          任务运行的其他一些会话参数

    --------------------------
    描述                       INTERVAL参数值
    每天午夜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)'
    每个季度最后一天的晚上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)'

    --------------------------

    1:每分钟执行

    Interval =>TRUNC(sysdate,'mi') + 1/ (24*60)

    2:每天定时执行

    例如:每天的凌晨1点执行

    Interval =>TRUNC(sysdate) + 1 +1/ (24)

    3:每周定时执行

    例如:每周一凌晨1点执行

    Interval =>TRUNC(next_day(sysdate,'星期一'))+1/24

    4:每月定时执行

    例如:每月1日凌晨1点执行

    Interval=>TRUNC(LAST_DAY(SYSDATE))+1+1/24

    5:每季度定时执行

    例如每季度的第一天凌晨1点执行

    Interval =>TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24

    6:每半年定时执行

    例如:每年7月1日和1月1日凌晨1点

    Interval =>ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24

    7:每年定时执行

    例如:每年1月1日凌晨1点执行

    Interval=>ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24

    六、  oracle中建立job定期运行存储过程总结

    1 首先查看
    SQL> show parameter job
    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    job_queue_processes integer 10
    如果值是 0 需要修改(如果为0则无法运行job,此值为允许同时运行的job数量)
    alter system set job_queue_processes =10; --或者其他值
    2 一个简单例子:
      创建测试表
      SQL> create table TEST(a date);
      表已创建。
      创建一个自定义过程
      SQL> create or replace procedure MYPROC as
       2 begin
       3 insert into TESTvalues(sysdate);
       4 end;
       5 /
      
      过程已创建。
      
      创建JOB
      SQL> variable job1 number;
      SQL>
      SQL> begin
       2 dbms_job.submit(:job1,'MYPROC;',sysdate,'sysdate+1/1440');  

    --每天1440分钟,即一分钟运行test过程一次
       3 end;
       4 /
      
      PL/SQL 过程已成功完成。
      
      运行JOB
      SQL> begin
       2 dbms_job.run(:job1);
       3 end;
       4 /
      
      PL/SQL 过程已成功完成。
      
      SQL> select to_char(a,'yyyy/mm/dd hh24:mi:ss') 时间 from TEST;
      时间
      -------------------
      2001/01/07 23:51:21
      2001/01/07 23:52:22
      2001/01/07 23:53:24
      
      删除JOB
      SQL> begin
       2 dbms_job.remove(:job1);
       3 end;
       4 /
      PL/SQL 过程已成功完成。
    Sql> print :n;
    系统打印此任务的编号,例如结果为300。
    如上,我们创建了一个每隔1分钟执行一次的任务号为300的任务。可以通过Oracle提供的数据字典user_jobs察看该任务的执行情况:
    sql> select  job, next_date, next_sec,failures, broken  from  user_jobs;
    执行结果如下:
    job next_date next_sec failures broken
    300 2000/10/10 11:45:15 0 N
    这表示任务号为300的任务,下一次将在2000/10/1011:45:15执行,此任务的执行失败记录为0次。

    注意:当执行job出现错误时,Oracle将其记录在日志里,失败次数每次自动加1。当执行失败次 数达到16时,

    Oracle就将该job标志为broken。此后,Oracle不再继续执行它,直到用户调用过程dbms_job.broken,重新

    设置为notbroken,或强制调用dbms_job.run来重新执行它。
    除了以上我们讨论的submit存储过程之外,Oracle还提供了其他许多存储过程来操作任务。例如:dbms_job.change 、dbms_job.what、dbms_job.interval可以用来修改提交的任务。要想删除该任务,只需运行dbms_job.remove(n)即可,

    其中n为任务号。
    3 上面的例子没有涉及到存储过程带参数的问题,如果带参数假设为
    MYPROC( ina IN VARCHAR2,
    ------------------以下为必须输出参数组---------------------------------
    outa OUT NUMBER,
    outb OUT VARCHAR2)

    则 在建立job的代码中
    创建JOB
      begin
    sys.dbms_job.submit(job => :job,
    what => '
    declare

    outa number; --定义输出变量
    outb varchar2(40);
    begin
    MYPROC(''输入'',outa =>outa ,outb =>outb );
    end;',
    next_date => to_date('10-10-2006 08:48:34', 'dd-mm-yyyy hh24:mi:ss'),
    interval => 'sysdate+1');
    commit;
    end;
    /

    七、  oracle中job的用法

    一个简单例子:
         创建测试表
         SQL>      create     table      a(a      date);
        
         表已创建。
        
         创建一个自定义过程
         SQL>     create      or     replace      procedure     test      as
            2        begin
            3       insert      into     a      values(sysdate);
            4        end;
            5        /
        
         过程已创建。
        
         创建JOB
         SQL>     variable      job1     number;
         SQL>     
         SQL>      begin
            2       dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');

    --每天1440分钟,即一分钟运行test过程一次   
            3        end;
            4        /
        
         PL/SQL      过程已成功完成。
        
         运行JOB
         SQL>      begin
            2        dbms_job.run(:job1);
            3        end;
            4        /
        
         PL/SQL      过程已成功完成。
        
         SQL>     select      to_char(a,'yyyy/mm/dd     hh24:mi:ss')   时间     from      a;
        
         时间
         -------------------
         2001/01/07     23:51:21
         2001/01/07     23:52:22
         2001/01/07     23:53:24
        
         删除JOB
         SQL>      begin
            2        dbms_job.remove(:job1);
            3        end;
            4        /
        
         PL/SQL      过程已成功完成。
        
        
         select     job,to_char(next_date,'yyyy-mm-dd     hh24:mi:ss')      from     all_jobs;
        
        
         ----------job的使用:
        
         DBMS_JOB.SUBMIT(:jobno,//job号
                            'your_procedure;',//要执行的过程
                            trunc(sysdate)+1/24,//下次执行时间
                            'trunc(sysdate)+1/24+1'//每次间隔时间
                            );
         删除job:dbms_job.remove(jobno);
         修改要执行的操作:job:dbms_job.what(jobno,what);
         修改下次执行时间:dbms_job.next_date(job,next_date);
         修改间隔时间:dbms_job.interval(job,interval);
         停止job:dbms.broken(job,broken,nextdate);
         启动job:dbms_job.run(jobno);

    附:调用语句和参数说明:

    dbms_job.submit( job out binary_integer,
    what      in   archar2,
    next_date     in   date,
    interval     in   varchar2,
    no_parse     in   boolean)
    其中:
    ●job:输出变量,是此任务在任务队列中的编号;
    ●what:执行的任务的名称及其输入参数;
    ●next_date:任务执行的时间;
    ●interval:任务执行的时间间隔。

    要建一个触发器,在每天15:30的时候把wzcs.ckjl的表里面的cksj(出库时间)字段为当天的记录

    插入到rjck.rkjl里面!

    请问如何实现?

    declare
                   jobid     number;
                   v_sql     varchar2(2000);
        begin
                   v_sql:='begin
                                         if     to_char(sysdate,''HH24:MI'')=''15:30''    then
                                               insert     into     rjck.rkjl(cksj)

    select    cksj     from     wzcs.ckjl;
                                               dbms_output.put_line(''inserted  success'');
                                         end     if;
                                         commit;
                                   exception
                                         when     others     then
                                         rollback;
                                         dbms_output.put_line(SQLERRM);
                                   end;
                                 ';
                   dbms_job.submit( jobid, v_sql, sysdate, 'sysdate+1/1440' );
                   dbms_job.run(jobid);
                   dbms_output.put_line('job'||to_char(jobid)||'is running');
        end;

    THS; 

  • 相关阅读:
    MongoDB 创建数据库
    MongoDB
    MongoDB 概念解析
    window平台安装 MongoDB(二)
    MongoDB入门学习(1)
    解决DevExpress10.2.4版本在VS2012工具箱控件不显示的问题
    Aspose.Word 输出表格后空格字符丢失的解决方法
    ArcEngine 创建空间参考设置默认域
    SPATIALITE 各版本数据库差异
    WGS84投影的WKID说明
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299187.html
Copyright © 2011-2022 走看看