Oracle定時任務dbms_scheduler

風靈使發表於2018-08-20

1. 簡介

Oracle 10g之前,我們通過DBMS_JOB來管理定時任務;
10g之後,則推薦使用DBMS_SCHEDULER來管理定時任務,因為它提供了更強大的功能和靈活的機制。

2. 需要的許可權

  CREATE JOB          -- (必須, 要執行DBMS_SCHEDULER, 需要有create job許可權)
  CREATE EXTERNAL JOB -- (可選, 建立執行作業系統命令的job時需要)  
  # 查詢使用者所擁有的角色以及角色所包含的許可權
  select * from role_sys_privs where role in (
    select granted_role from dba_role_privs where grantee='SCOTT'
  ) order by role;
  # 查詢直接授予使用者的許可權
  select * from dba_sys_privs where grantee='SCOTT'; 

3. 一個簡單的Demo

3.1 建立JOB

create table test_t1(id int, create_date date);
create or replace procedure test_p1
is
  v_maxId test_t1.id%type := 1;
begin
  select nvl(max(id), 0) into v_maxId from test_t1;
  insert into test_t1 values(v_maxId + 1, sysdate);
  commit;
end test_p1;
/
declare
  v_count int := 0;
begin
  select count(*) into v_count from user_scheduler_jobs where job_name='TEST_JOB1';
  if v_count > 0 then
    dbms_scheduler.drop_job('TEST_JOB1');
  end if;
  dbms_scheduler.create_job (
    job_name        => 'test_job1',
    job_type        => 'STORED_PROCEDURE',
    job_action      => 'TEST_P1',
    start_date      => sysdate,
    repeat_interval => 'FREQ=MINUTELY;INTERVAL=1',
    enabled         => true
  );
end;
/

引數說明

job_name        : 必選, 任務名稱
job_type        : 必選, 任務型別(
                    PLSQL_BLOCK,      -- 執行一個PL/SQL匿名快
                    STORED_PROCEDURE, -- 執行一個儲存過程
                    EXECUTABLE,       -- 執行一個外部程式
                    CHAIN             -- 執行一個CHAIN
                  )
job_action      : 必選, 任務內容, 與job_type配合使用
start_date      : 可選, 首次執行時間, 為空時表示立即執行
repeat_interval : 可選, 執行頻率, 為空時表示只執行一次(
                    FREQ=MINUTELY; -- 表示間隔單位, 可選值有YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY
                    INTERVAL=1     -- 表示間隔週期
                  )
enabled         : 可選, 是否啟用任務

詳細引數可參考: http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_sched.htm#ARPLS72960

3.2 檢視JOB執行情況

-- 檢視已建立的JOB
select job_name, job_type, enabled, state from user_scheduler_jobs;
-- 檢視JOB執行日誌
select log_id, log_date, status from user_scheduler_job_run_details where job_name='TEST_JOB1';

3.3 刪除JOB

exec dbms_scheduler.drop_job('TEST_JOB1');