Oracle dbms_job管理

0、參考資料&注意事項

Oracle Database Administrator’s Guide -> Support for DBMS_JOB in Release 11gR2

注意事項:

修改完dbms_job的屬性後記着要commit

dbms_job說明:

dbms_job是個pl/sql包,可以讓你創建oracle job,oracle 10g以後被scheduler取代,10g以上版本中保留dbms_job功能僅僅是爲了向前兼容,就像exp/imp一樣。

1、dbms_jobs相關視圖和參數

相關視圖:

dba_jobs_running
dba_jobs

相關參數:

初始化相關的參數:job_queue_process
建議最大job進程數不要超過1000,oracle11g默認job隊列進程數爲1000.

查看所有的 JOB &查詢正在運行的JOB

select * from dba_jobs;
select job,what,to_char(last_date,'yyyy-mm-dd HH24:mi:ss'),to_char(next_date,'yyyy-mm-dd HH24:mi:ss'),interval from dba_jobs ;
select * from dba_jobs_running;

字段說明:

job : job
what : 執行的存儲過程或SQL語句
failures : 失敗次數
broken : 狀態

2、dbms_job管理

dbms_job停止啓動案例

--A層庫查詢出dbms_job的停止腳本
select 'exec dbms_ijob.broken('||job||',true);' from dba_jobs  where broken='N';
--A層庫查詢出dbms_job的啓動腳本
select 'exec dbms_ijob.broken('||job||',false);' from dba_jobs  where broken='N';

2.1、創建 DBMS_JOB

使用以下語句:

VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno, --job號,ORACLE自動分配
    'your_procedure;',  --執行的存儲過程或SQL語句,';'不能省略
    next_date, --下次執行時間
    'interval' --每次間隔時間,以天爲單位
  );    
commit;
end;

創建dbms_job案例:
爲了示範,先創建一張簡單的表:

CREATE TABLE T_TIME(JOB_TIME DATE not null);
  1. 每分種爲 T_TIME 表插入一條數據:
VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno,
    'insert into T_TIME values (sysdate);',
    Sysdate,
    'sysdate+1/24/60'
  );    
commit;
end;
  1. 每天刪除前一天的數據:
VARIABLE jobno number;
begin
  DBMS_JOB.SUBMIT(
    :jobno,
    'delete T_TIME where JOB_TIME < sysdate-1;',
    Sysdate,
    'sysdate+1/24'
  );    
commit;
end;
  1. 特殊情況(sql語句中包含單引號)
declare   
      job_id   pls_integer; 
begin
sys.dbms_job.submit(job => job_id,
                    what => 'insert into  sess_lgwr SELECT sysdate check_time,SECONDS_IN_WAIT,BLOCKING_SESSION, PROGRAM FROM GV$SESSION@TEST_CAS1 WHERE PROGRAM LIKE ''%LGWR%'';',
                    next_date =>sysdate,
                    interval => 'sysdate+3/24/60/60'
                    );
commit;
end;

2.2、啓停\修改dbms_job

停止 JOB

BEGIN DBMS_JOB.BROKEN(jobno, TRUE); END;
參數 jobno 爲對應的JOB號,如 BEGIN DBMS_JOB.BROKEN(2, TRUE); END;

啓動 JOB

BEGIN DBMS_JOB.run(jobno); END;
或者
exec dbms_job.broken(1,false);
commit; 

刪除 JOB

BEGIN DBMS_JOB.remove(jobno); END;

修改 JOB

修改運行的內容

BEGIN DBMS_JOB.what(
    jobno,   --對應的job號
    'your_procedure;'  --執行的存儲過程或SQL語句,';'不能省略
); 
END;

修改時間間隔

BEGIN DBMS_JOB.interval(
    jobno,   --對應的job號
    'interval' --每次間隔時間,以天爲單位
); END;

修改下一次執行時間

exec dbms_ijob.next_date(22,to_date('2019-09-15 04:00:00','yyyy-mm-dd hh24:mi:ss'));
BEGIN DBMS_JOB.next_date(
    jobno,   --對應的job號
    next_date, --下次執行時間
); END;

2.3、非job owner用戶管理job

不是job的owner的用戶delete,remove,broken 一個job時,會報錯:ORA-23421: job number XXXX is not a job in the job queue

只有job的owner才能夠對job進行修改變更,比如下面的腳本所示:

sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
       JOB WHAT                                     LOG_USER   PRIV_USER  B
---------- ---------------------------------------- ---------- ---------- -
       275 WEB_SMS.cleanAppBuffer;                  SYSTEM     SYSTEM     N
system@im1>exec DBMS_JOB.broken(295,false);
PL/SQL procedure successfully completed.
system@im1>exec DBMS_JOB.broken(295,true);
PL/SQL procedure successfully completed.
system@im1>commit;
Commit complete.
system@im1>select job, log_user, priv_user,broken from dba_jobs where job in (295);
       JOB LOG_USER   PRIV_USER  B
---------- ---------- ---------- -
       295 SYSTEM     SYSTEM     Y

如果登錄的用戶不是job的owner,比如sys用戶:

sys@im1>exec DBMS_IJOB.broken(275,true);
PL/SQL procedure successfully completed.
sys@im1>select job, what, log_user, priv_user,broken from dba_jobs where job=275;
       JOB WHAT                                     LOG_USER   PRIV_USER  B
---------- ---------------------------------------- ---------- ---------- -
       275 WEB_SMS.cleanAppBuffer;                  SYSTEM     SYSTEM     Y
sys@im1>exec DBMS_IJOB.broken(275,false);
PL/SQL procedure successfully completed.

3、關於 interval 的一些設置技巧

關於job運行時間

1:每分鐘執行
'sysdate+1/24/60'
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

job的運行頻率設置

1.每天固定時間運行,比如早上8:10分鐘:Trunc(Sysdate+1) + (8*60+10)/24*60
2.Toad中提供的:
每天:trunc(sysdate+1)
每週:trunc(sysdate+7)
每月:trunc(sysdate+30)
每個星期日:next_day(trunc(sysdate),'星期日')
每天6點:trunc(sysdate+1)+6/24
半個小時:sysdate+30/(24*60)
3.每個小時的第15分鐘運行,比如:8:15,9:15,10:15…:trunc(sysdate,'hh')+(60+15)/(24*60)。

描述 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)'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章