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)
停止job
,force
預設為false
,oracle
建議false
停止失敗情況下,使用true
,且使用true
需要有manage scheduler
許可權
3) dbms_scheduler.drop_job(jobName)
刪除job
4) dbms_scheduler.enable(jobName)
開啟job
5) dbms_scheduler.disable(jobName,force)
禁用job
,force
引數用於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