天天看點

Oracle JOB兩種作業建立及比較

存儲過程準備 

create table job_test (a date);

create or replace procedure test123 as

begin

    insert into JOB_TEST values(sysdate);

    commit;

end;

第一種,使用dbms_job存儲過程建立作業

variable aaa number

begin

 dbms_job.submit(:aaa,'test123;',sysdate,'sysdate+1/1440',true);

end;

/

begin

 dbms_job.run(:aaa);

end;

/

此處注意,執行job必須在其所屬使用者下執行,否則會報該jobid不存在。

begin

 dbms_job.remove(:aaa);

end;

資料字典

select * from dba_jobs;

第二種 使用schedule_job建立作業

begin

  dbms_scheduler.create_job(job_name        => 'testjob',

                            job_type        => 'stored_procedure',

                            job_action      => 'person.test123',

                            start_date      => to_date('201708251001','yyyymmddhh24mi'),

                            repeat_interval => 'freq=minutely;interval=1');

end;

/

begin

 dbms_scheduler.enable('testjob');

end;

begin

 dbms_scheduler.run_job('testjob');

end;

?????此處注意,執行job必須在其所屬使用者下執行,否則會報該jobid不存在。

begin

 dbms_scheduler.drop_job('testjob');

end;

/

資料字典:

select *from dba_scheduler_job_log where job_name='TESTJOB';

select *from dba_scheduler_jobs where job_name='TESTJOB';

注意:建立job的時候請注意資料庫的參數job_queue_processes參數不能是0,如果是0的話資料庫程序無法啟動。修改參數後需重新開機

ps -ef | grep ora_j | grep -v grep 可通過此指令檢視和job相關的排程程序是否啟動,如果未啟動則job一定不會執行。

job執行的由于執行需要依賴上一次執行,是以start_date最好設定為目前時間向後一點點,或者用固定時間來代替

比較:dbms_job和schedule_job的優劣,dbms_job沒有job執行日志,schedule_job有日志,是以建議使用shcedule_job

dbms_job 時間間隔設定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)'

每月25号00:00執行: 'TRUNC(LAST_DAY(SYSDATE ) + 25)'

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

1:每分鐘執行

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

Interval => sysdate+1/1440

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

schedule_job時間間隔interval設定:

例如:設定任務僅在周5的時候運作:  

REPEAT_INTERVAL => 'FREQ=DAILY; BYDAY=FRI';  

REPEAT_INTERVAL => 'FREQ=WEEKLY; BYDAY=FRI';  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=FRI';   

  上述三條語句雖然指定的關鍵字小有差異,不過功能相同。  

  設定任務隔一周運作一次,并且僅在周5運作:  

REPEAT_INTERVAL => 'FREQ=WEEKLY; INTERVAL=2; BYDAY=FRI';   

  設定任務在當月最後一天運作:  

REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=-1';   

  設定任務在3月10日運作:  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYMONTH=MAR; BYMONTHDAY=10'; REPEAT_INTERVAL => 'FREQ=YEARLY; BYDATE=0310';   

  上述兩條語句功能相同。  

  設定任務每10隔天運作:  

REPEAT_INTERVAL => 'FREQ=DAILY; INTERVAL=10';   

  設定任務在每天的下午4、5、6點時運作:  

REPEAT_INTERVAL => 'FREQ=DAILY; BYHOUR=16,17,18';   

  設定任務在每月29日運作:  

REPEAT_INTERVAL => 'FREQ=MONTHLY; BYMONTHDAY=29';   

  設定任務在每年的最後一個周5運作:  

REPEAT_INTERVAL => 'FREQ=YEARLY; BYDAY=-1FRI';   

  設定任務每隔50個小時運作:  

REPEAT_INTERVAL => 'FREQ=HOURLY; INTERVAL=50';   

  另外,你是否在懷念正常job中設定interval的簡便,雖然功能較弱,但是設定操作非常簡單,無須懊惱,其實SCHEDULER中的REPEAT_INTERVAL也完全可以按照那種方式設定,前面都說了,REPEAT_INTERVAL實際上是指定周期,直接指定一個時間值,當然也是周期喽。   

或者也可以類似dbms_job寫法:

REPEAT_INTERVAL => 'trunc(sysdate)+1'   

  又比如設定任務每周執行一次:  

REPEAT_INTERVAL => 'trunc(sysdate)+7'