1. 程式人生 > >Oracle 定時任務 作業排程計劃 DBMS_JOB DBMS_SCHEDULE使用方法

Oracle 定時任務 作業排程計劃 DBMS_JOB DBMS_SCHEDULE使用方法

 

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

2018年08月20日 13:18:20 風靈使 閱讀數:111

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

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

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

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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

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
  • 2
  • 3
  • 4
  • 5
  • 6

定時器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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

定時器執行,呼叫儲存過程建立表成功了,不需要顯示的授權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

https://blog.csdn.net/lldustc_blog/article/details/52944927

 

 

 

 

Oracle Job 定時呼叫儲存過程

2011年11月03日 13:22:32 webajax 閱讀數:702

--建立測試表名
create table job_table(run_date date);
--建立儲存過程
create or replace procedure job_proc as
begin
     insert into job_table (run_date) values (sysdate);
end;

--建立job並指定一分鐘執行一次
declare
       job number;
begin
     dbms_job.submit(job,'job_proc;',sysdate,'TRUNC(sysdate,''mi'')+1/(24*60)');
end;

commit;

 

--暫停任務

--select job from user_jobs 
找出job的id值,然後使用下面的放語句停止任務。

begin
dbms_job.broken(584,true);
end;

 

--重啟任務

begin
dbms_job.run(584);
end;

 

--刪除任務
delete user_jobs where job=584;
drop procedure job_proc;
drop table job_table;

 

建立job後。系統即會在指定時間裡自動呼叫該儲存過程。

 

關於時間間隔的相關知識:

1.TRUNC(for dates)  

TRUNC函式為指定元素而截去的日期值。  

其具體的語法格式如下:  

TRUNC(date[,fmt])  

其中:  date 一個日期值  fmt 日期格式,該日期將由指定的元素格式所截去。忽略它則由最近的日期截去  

下面是該函式的使用情況:  

TRUNC(TO_DATE('24-Nov-1999 08:00 pm'),'dd-mon-yyyy hh:mi am')  ='24-Nov-1999 12:00:00 am'  

TRUNC(TO_DATE('24-Nov-1999 08:37 pm','dd-mon-yyyy hh:mi am'),'hh') ='24-Nov-1999 08:00:00 am'  

trunc(sysdate,'yyyy') --返回當年第一天.  

trunc(sysdate,'mm') --返回當月第一天.  

trunc(sysdate,'d') --返回當前星期的第一天.  

trunc(sysdate,'dd')--返回當前年月日

 

trunc函式後面加的數字的單位是天。  

 

每天凌晨0點0分:trunc(sysdate+1)

每天早上8點 trunc(sysdate+1)+1/3

每天早上8點30分 trunc(sysdate+1)+(8.5*60)/(24*60)

每天早上8點30分 trunc(sysdate+1)+8.5/24

每天早上8點30分 trunc(sysdate+1)+(8*60+30)/(24*60)

https://blog.csdn.net/webajax/article/details/6931770

 

 

 

 

oracle使用DBMS_SCHEDULER排程作業

置頂 2016年10月27日 13:24:14 lldustc 閱讀數:9522 標籤: oracle 更多

個人分類: oracle

dbms_scheduler包的功能比dbms_job包強大很多,但是很多初學者直接被它的複雜性嚇跑了,跟著我,只需幾分鐘就會用了。

三個概念

大多數人看到這個包裡的函式和函式裡眾多的引數,就開始暈菜了,不要被這些表象迷惑了,其實這些東西都是圍繞著三個基本概念,schedule,program和job。oracle是為了複用的目的,提煉出了排程的這三個要素,弄懂這三個要素,立刻豁然開朗。

schedule

schedule表示排程計劃表。排程從什麼時間開始被排程,什麼時候結束,以什麼頻度排程。使用DBMS_SCHEDULER.CREATE_SCHEDULE過程建立schedule。

 begin
    DBMS_SCHEDULER.CREATE_SCHEDULE (
      schedule_name     => ¨daily_schedule¨,
      start_date        => SYSDATE,
      repeat_interval   => ¨FREQ=DAILY ; INTERVAL=1¨,
      comments          => ¨every one day¨);
    END;
    /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其中repeat_interval引數,支援兩種格式: 
- dbms_job裡的interval格式,建議讓這種晦澀語法見鬼去吧 
- 日曆表達式(linux系統的crontab使用的格式)

日曆表達式分為三部分: 第一部分是頻率,也就是”FREQ”這個關鍵字,它是必須指定的; 第二部分是時間間隔,也就是”INTERVAL”這個關鍵字,取值範圍是1-999. 它是可選的引數; 第三部分是附加的引數,可用於精確地指定日期和時間,它也是可選的引數,下面這些值都是合法的: 
BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY 
BYHOUR,BYMINUTE,BYSECOND

看幾個例子就會用了

每隔2小時執行一次
repeat_interval => 'FREQ=HOURLY; INTERVAL=2'

每天執行一次
repeat_interval => 'FREQ=DAILY'

每週的1,3,5執行
repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI"

每年的3,6,9,12月的18號執行
repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=18'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

另外使用dbms_scheduler.evaluate_calendar_string可以方便的計算出什麼時候執行該排程。

program

program表示排程應該做什麼事情,是對程式的抽象。使用DBMS_SCHEDULER.CREATE_PROGRAM建立program

 BEGIN
    DBMS_SCHEDULER.CREATE_PROGRAM (
       program_name           => ¨time_synchronization¨,
       program_action         => ¨/sbin/ntpdate 128.59.67.100¨,
       program_type           => ¨EXECUTABLE¨,
       enabled                => TRUE);
 END;
    /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

排程現在可以支援呼叫外部程式了,這點很強大。 
目前程式支援三種類型: 
- PL/SQL塊: PLSQL_BLOCK, 
- 儲存過程: STORED_PROCEDURE 
- 外部程式: EXECUTABLE, 外部程式可以是一個shell指令碼,也可以是作業系統級別的命令。

program_action: 根據program_type的不同,program_action有不同的含義。 
- program_type是儲存過程,就需要指定儲存過程的名字; 
- program_type是PL/SQL塊,就需要輸入完整的PL/SQL程式碼; 
- program_type是外部程式,就需要輸入script的名稱或者作業系統的指令名

job

job表示按照指定的schedule,執行指定program,完成使用者指定的工作。使用DBMS_SCHEDULER.CREATE_JOB建立job。

SQL> BEGIN
  2  DBMS_SCHEDULER.CREATE_JOB (
  3     job_name           =>  ¨time_synchron¨,
  4     program_name       =>  ¨time_synchronization¨,
  5     schedule_name      =>  ¨daily_schedule¨,
  6     enabled            =>  true);
  7  END;
  8  /
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

排程的相關操作

作業相關操作

一般情況下是如果你設定了job的enable是true的話,oracle會按照你的計劃,定時呼叫你的job,不需要手動執行。如果臨時需要馬上排程job也是可以的。

exec dbms_scheduler.run_job(¨time_synchron¨);
  • 1

如果覺得沒有必要繼續執行這個job了,可以停止該job,讓oracle以後不要再繼續排程了。

exec dbms_scheduler.stop_job(¨time_synchron¨);
  • 1

檢視作業相關情況

Job 每執行一次,無論成功或失敗,均會[DBA|ALL|USER]_SCHEDULER_JOB_LOG中生成一條對應的記錄(前提是LOGGING_LEVEL屬性值未設定為DBMS_SCHEDULER.LOGGING_OFF),job的詳細資訊可以通過 
[DBA|ALL|USER]_SCHEDULER_JOB_RUN_DETAILS檢視檢視。

https://blog.csdn.net/lldustc_blog/article/details/52944927