oracle定時任務dbms_job與dbms_scheduler使用方法

風靈使發表於2018-08-20

工作中需要一個定時任務來抽取資料,之前採用的是dbms_job包下的過程來建立job,遇到了一些問題。找了下資料,得知oracle10g以後就推薦採用dbms_scheduler包來取代dbms_job來建立定時任務。下面簡單介紹下兩者的使用方法及使用過程中的一些體會。

1.先建立日誌表,用於記錄儲存過程執行時間及結果

    create table bak_job_test(date_time date,mark varchar2(200));

2.建立一個儲存過程,用於建立表

     create or replace procedure my_test authid current_user is
       v_count number := 0;
       v_mess varchar2(200) := '';
     begin
      select count(1) into v_count from user_tables t where t.TABLE_NAME = 'BAK_JOB_TABLES';
       if  v_count > 0 then
          execute immediate 'drop table bak_job_tables purge';
       end if;
      execute immediate 'create table bak_job_tables as select * from user_tables where 1=2';
      insert into bak_job_test(date_time,mark) values(sysdate,'success');
exception
when others then
v_mess := substr(SQLERRM,0,200);
insert into bak_job_test(date_time,mark) values(sysdate,v_mess);
      end;

3.使用dbms_job包建立定時任務

      declare
          myjob number; 
       begin 
dbms_job.submit(myjob,'begin my_test; end;',sysdate,'TRUNC(sysdate,''mi'') + 1 / (24*60)');
commit;
        end;

定時器1分鐘執行一次,呼叫儲存過程建立表,結果報錯:許可權不足。之前瞭解過,定義儲存過程時加上authid current_user就可以在儲存過程裡面使用當前使用者所角色的許可權,出現這種問題 讓人很費解,手動授權grant create table to user之後,確實可以解決這個問題,但是這種方式不通用,特別是儲存過程裡面用到其他的許可權的時候就不方便了。所以決定試試dbms_scheduler包來建立定時任務。

先簡單介紹下dbms_job包下常見的過程:

1) dbms_job.remove(jobId) 刪除job定時任務,可以從user_jobs檢視中檢視job的詳細情況

2) dbms_job.run(jobid) 執行定時任務

3) dbms_job.broken(jobid,true) 終止定時任務

4) dbms_job.interval(jobid,'interval') 修改定時任務的執行時間

4.使用dbms_scheduler建立定時任務

使用dbms_scheduler需要具有create job許可權,對定時任務一些操作需要具有MANAGE SCHEDULER許可權,如:dbms_scheduler.stop_job('my_job_test',true);

     BEGIN
     dbms_scheduler.create_job(job_name        => 'my_job_test',
                             job_type        => 'STORED_PROCEDURE',
                             job_action      => 'my_test',
                              start_date      => sysdate,
                             repeat_interval => 'sysdate + 1/1440',
                             enabled         => TRUE,
                             comments        => 'test');
     end;

定時器執行,呼叫儲存過程建立表成功了,不需要顯示的授權grant create table to user,只需要存錯過程定義為authid current_user即可。個人覺得dbms_job在呼叫authid current_user的儲存過程的時候,未能呼叫到使用者具有的角色的許可權,這或許是dbms_job的一個bug

簡單介紹下dbms_scheduler關於定時任務的一些常用過程:

1) dbms_scheduler.run(jobName) 執行job

2) dbms_scheduler.stop_job(jobName,force) 停止jobforce預設為falseoracle建議false停止失敗情況下,使用true,且使用true需要有manage scheduler許可權

3) dbms_scheduler.drop_job(jobName) 刪除job

4) dbms_scheduler.enable(jobName) 開啟job

5) dbms_scheduler.disable(jobName,force) 禁用jobforce引數用於dependencies,如果TRUE,即使其他物件依賴於它,操作也能成功

相關檢視

1) user_scheduler_jobs 檢視job資訊

2) User_Scheduler_Job_Log job job日誌

3) user_scheduler_job_run_details job執行日誌

4) user_scheduler_running_jobs 正在執行的job

總結:

oracle定時任務,dbms_job呼叫儲存過程建立表,需要顯示授權,儲存過程定義為authid current_user也不行,而dbms_scheduler是不需要顯示授權的,這點來說後者更方便使用。另外,dbms_scheduler提供了job執行日誌記錄檢視,可以檢視具體的執行日誌,比較實用。而且,oracle10g以後也推薦使用dbms_scheduler

相關文章