oracle定时任务(dbms_job)
author:skate
time:2007-09-12
http://publish.it168.com/2006/0311/20060311017002.shtml
今天總結(jié)下Oracle的任務(wù)隊(duì)列管理器(job queue ),以后也方便查詢.
?我們要做定時(shí)任務(wù)時(shí),有兩種辦法
一種是:?操作系統(tǒng)的定時(shí),win的定時(shí)任務(wù),unix的crontab
一種是:?數(shù)據(jù)庫級(jí)的定時(shí),她的效率更高,
再有大量的表級(jí)操作時(shí),建議用數(shù)據(jù)庫本身的job queue,這樣方便,效率高;如果用系統(tǒng)級(jí)定時(shí),
會(huì)增加很多編程工作,成本增加了,還很容易出錯(cuò),事情越簡單出錯(cuò)的幾率越小.
再使用job queue之前,我們還要簡單配置下,oracle定時(shí)執(zhí)行job queue 的后臺(tái)進(jìn)程是SNP,要啟動(dòng)
snp,首先看系統(tǒng)模式是否支持
sql> alter system enable restricted session;
或
sql> alter system disenable restricted session;
利用上面的命令更改系統(tǒng)的會(huì)話方式為disenable restricted,為snp的啟動(dòng)創(chuàng)建條件.
再有就是配置job queue的啟動(dòng)參數(shù),snp的啟動(dòng)參數(shù)位于oracle的初始化文件中,
job_queue_processes=10?? (oracle10gde 默認(rèn)值)
job_queue_interval=N
第一行定義snp進(jìn)程的啟動(dòng)個(gè)數(shù)為10,正常得女冠一范圍是0-36,根據(jù)任務(wù)的多少,可以配置
不同的數(shù)值.
第二行定義系統(tǒng)每隔幾秒喚醒該進(jìn)程一次.缺省是60,正常范圍是1-3600秒.事實(shí)上,該進(jìn)程執(zhí)行完
當(dāng)前任務(wù)后,就進(jìn)入睡眠狀態(tài),睡眠一段時(shí)間后,由系統(tǒng)的總控負(fù)責(zé)將其喚醒。??
如果該文件中沒有上面兩行,請按照如上配置添加。配置完成后,需要重新啟動(dòng)數(shù)據(jù)庫,使其生效
。注意:如果任務(wù)要求執(zhí)行的間隔很短的話,N的配置也要相應(yīng)地小一點(diǎn)。
查看job queue的詳細(xì)信息,查詢數(shù)據(jù)庫字典 user_jobs
eg:
?sql> select job,next_date,next_sec,broken from user_jobs;
包含以下子過程:?
Broken()過程。?
change()過程。?
Interval()過程。?
Isubmit()過程。?
Next_Date()過程。?
Remove()過程。?
Run()過程。?
Submit()過程。?
User_Export()過程。?
What()過程。
1、?
Broken()過程更新一個(gè)已提交的工作的狀態(tài),典型地是用來把一個(gè)已破工作標(biāo)記為未破工作。?
這個(gè)過程有三個(gè)參數(shù):job 、broken與next_date。
PROCEDURE Broken (job?????? IN binary_integer,?
????????????????? Broken??? IN boolean,?
????????????????? next_date IN date :=SYSDATE)
job參數(shù)是工作號(hào),它在問題中唯一標(biāo)識(shí)工作。?
broken參數(shù)指示此工作是否將標(biāo)記為破——TRUE說明此工作將標(biāo)記為破,而FLASE說明此工作將標(biāo)記為未破。?
next_date參數(shù)指示在什么時(shí)候此工作將再次運(yùn)行。此參數(shù)缺省值為當(dāng)前日期和時(shí)間。
2、?
Change()過程用來改變指定工作的設(shè)置。?
這個(gè)過程有四個(gè)參數(shù):job、what 、next_date與interval。
PROCEDURE Change (job??????? IN binary_integer,?
????????????????? What?????? IN varchar2,?
????????????????? next_date? IN date,?
????????????????? interval?? IN varchar2)
此job參數(shù)是一個(gè)整數(shù)值,它唯一標(biāo)識(shí)此工作。?
What參數(shù)是由此工作運(yùn)行的一塊PL/SQL代碼塊。?
next_date參數(shù)指示何時(shí)此工作將被執(zhí)行。?
interval參數(shù)指示一個(gè)工作重執(zhí)行的頻度。
3、?
Interval()過程用來顯式地設(shè)置重執(zhí)行一個(gè)工作之間的時(shí)間間隔數(shù)。?
這個(gè)過程有兩個(gè)參數(shù):job與interval。
PROCEDURE Interval (job????? IN binary_integer,?
??????????????????? Interval IN varchar2)
job參數(shù)標(biāo)識(shí)一個(gè)特定的工作。interval參數(shù)指示一個(gè)工作重執(zhí)行的頻度。
4、?
ISubmit()過程用來用特定的工作號(hào)提交一個(gè)工作。?
這個(gè)過程有五個(gè)參數(shù):job、what、next_date、interval與no_parse。
PROCEDURE ISubmit (job?????? IN binary_ineger,?
?????????????????? What????? IN varchar2,?
?????????????????? next_date IN date,?
?????????????????? interval? IN varchar2,?
?????????????????? no_parse? IN booean:=FALSE)
這個(gè)過程與Submit()過程的唯一區(qū)別在于此job參數(shù)作為IN型參數(shù)傳遞且包括一個(gè)?
由開發(fā)者提供的工作號(hào)。如果提供的工作號(hào)已被使用,將產(chǎn)生一個(gè)錯(cuò)誤。
5、?
Next_Date()過程用來顯式地設(shè)定一個(gè)工作的執(zhí)行時(shí)間。這個(gè)過程接收兩個(gè)參數(shù):job與next_date。
PROCEDURE Next_Date(job???????? IN binary_ineger,?
??????????????????? next_date?? IN date)
job標(biāo)識(shí)一個(gè)已存在的工作。next_date參數(shù)指示了此工作應(yīng)被執(zhí)行的日期與時(shí)間。
6、?
Remove()過程來刪除一個(gè)已計(jì)劃運(yùn)行的工作。這個(gè)過程接收一個(gè)參數(shù):
PROCEDURE Remove(job IN? binary_ineger);
job參數(shù)唯一地標(biāo)識(shí)一個(gè)工作。這個(gè)參數(shù)的值是由為此工作調(diào)用Submit()過程返回的job參數(shù)的值。?
已正在運(yùn)行的工作不能由調(diào)用過程序刪除。
7、?
Run()過程用來立即執(zhí)行一個(gè)指定的工作。這個(gè)過程只接收一個(gè)參數(shù):
PROCEDURE Run(job IN binary_ineger)?
job參數(shù)標(biāo)識(shí)將被立即執(zhí)行的工作。
8、?
使用Submit()過程,工作被正常地計(jì)劃好。?
這個(gè)過程有五個(gè)參數(shù):job、what、next_date、interval與no_parse。
PROCEDURE Submit ( job?????? OUT binary_ineger,?
?????????????????? What????? IN? varchar2,?
?????????????????? next_date IN? date,?
?????????????????? interval? IN? varchar2,?
?????????????????? no_parse? IN? booean:=FALSE)
job參數(shù)是由Submit()過程返回的binary_ineger。這個(gè)值用來唯一標(biāo)識(shí)一個(gè)工作。?
what參數(shù)是將被執(zhí)行的PL/SQL代碼塊。?
next_date參數(shù)指識(shí)何時(shí)將運(yùn)行這個(gè)工作。?
interval參數(shù)何時(shí)這個(gè)工作將被重執(zhí)行。?
no_parse參數(shù)指示此工作在提交時(shí)或執(zhí)行時(shí)是否應(yīng)進(jìn)行語法分析——TRUE?
指示此PL/SQL代碼在它第一次執(zhí)行時(shí)應(yīng)進(jìn)行語法分析,?
而FALSE指示本PL/SQL代碼應(yīng)立即進(jìn)行語法分析。
9、?
User_Export()過程返回一個(gè)命令,此命令用來安排一個(gè)存在的工作以便此工作能重新提交。?
此程序有兩個(gè)參數(shù):job與my_call。
PROCEDURE User_Export(job??????? IN binary_ineger,?
????????????????????? my_call??? IN OUT varchar2)
job參數(shù)標(biāo)識(shí)一個(gè)安排了的工作。my_call參數(shù)包含在它的當(dāng)前狀態(tài)重新提交此工作所需要?
的正文。
10、?
What()過程應(yīng)許在工作執(zhí)行時(shí)重新設(shè)置此正在運(yùn)行的命令。這個(gè)過程接收兩個(gè)參數(shù):job與what。
PROCEDURE What (job? IN binary_ineger,?
??????????????? What IN OUT varchar2)
job參數(shù)標(biāo)識(shí)一個(gè)存在的工作。what參數(shù)指示將被執(zhí)行的新的PL/SQL代碼。
一個(gè)簡單例子:?
創(chuàng)建測試表?
SQL> create table a(a date);
表已創(chuàng)建。
創(chuàng)建一個(gè)自定義過程?
SQL> create or replace procedure test as?
? 2? begin?
? 3? insert into a values(sysdate);?
? 4? end;?
? 5? /
過程已創(chuàng)建。
創(chuàng)建JOB?
SQL> variable job1 number;?
SQL>??
SQL> begin?
? 2? dbms_job.submit(:job1,'test;',sysdate,'sysdate+1/1440');  --每天1440分鐘,即一分鐘運(yùn)行test過程一次?
? 3? end;?
? 4? /
PL/SQL 過程已成功完成。
運(yùn)行JOB?
SQL> begin?
? 2? dbms_job.run(:job1);?
? 3? end;?
? 4? /
PL/SQL 過程已成功完成。
SQL> select to_char(a,'yyyy/mm/dd hh24:mi:ss') 時(shí)間 from a;
時(shí)間?
-------------------?
2001/01/07 23:51:21?
2001/01/07 23:52:22?
2001/01/07 23:53:24
刪除JOB?
SQL> begin?
? 2? dbms_job.remove(:job1);?
? 3? end;?
? 4? /
PL/SQL 過程已成功完成。
下面說下常用的視圖與參數(shù):
任務(wù)隊(duì)列中關(guān)于任務(wù)的數(shù)據(jù)字典視圖
| 視圖名 | 描述 | 
| DBA_JOBS | 本數(shù)據(jù)庫中定義到任務(wù)隊(duì)列中的任務(wù) | 
| DBA_JOBS_RUNNING | 目前正在運(yùn)行的任務(wù) | 
| USER_JOBS | 當(dāng)前用戶擁有的任務(wù) | 
JOB_QUEUE_PROCESSES??>= 1 (如果系統(tǒng)在同一時(shí)間會(huì)運(yùn)行很多的job, 或者還有大量需要自動(dòng)refresh的snapshot, 適當(dāng)加大)
JOB_QUEUE_INTERVAL : 秒數(shù)(缺省為60秒), 根據(jù)你的job的調(diào)度頻度而定, 對于一般的一天運(yùn)行一次的job, 設(shè)為缺省值或者幾分鐘都可以. (不要設(shè)置過小, 以免影響性能)
JOB_QUEUE_KEEP_CONNECTION (系統(tǒng)默認(rèn)就可以,我沒發(fā)現(xiàn)他的作用)
DBA_JOBS 和 USER_JOBS.字典視圖的字段含義
| 字段(列) | 類型 | 描述 | 
| JOB | NUMBER | 任務(wù)的唯一標(biāo)示號(hào) | 
| LOG_USER | VARCHAR2(30) | 提交任務(wù)的用戶 | 
| PRIV_USER | VARCHAR2(30) | 賦予任務(wù)權(quán)限的用戶 | 
| SCHEMA_USER | VARCHAR2(30) | 對任務(wù)作語法分析的用戶模式 | 
| LAST_DATE | DATE | 最后一次成功運(yùn)行任務(wù)的時(shí)間 | 
| LAST_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的last_date日期的小時(shí),分鐘和秒 | 
| THIS_DATE | DATE | 正在運(yùn)行任務(wù)的開始時(shí)間,如果沒有運(yùn)行任務(wù)則為null | 
| THIS_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的this_date日期的小時(shí),分鐘和秒 | 
| NEXT_DATE | DATE | 下一次定時(shí)運(yùn)行任務(wù)的時(shí)間 | 
| NEXT_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的next_date日期的小時(shí),分鐘和秒 | 
| TOTAL_TIME | NUMBER | 該任務(wù)運(yùn)行所需要的總時(shí)間,單位為秒 | 
| BROKEN | VARCHAR2(1) | 標(biāo)志參數(shù),Y標(biāo)示任務(wù)中斷,以后不會(huì)運(yùn)行 | 
| INTERVAL | VARCHAR2(200) | 用于計(jì)算下一運(yùn)行時(shí)間的表達(dá)式 | 
| FAILURES | NUMBER | 任務(wù)運(yùn)行連續(xù)沒有成功的次數(shù) | 
| WHAT | VARCHAR2(2000) | 執(zhí)行任務(wù)的PL/SQL塊 | 
| CURRENT_SESSION_LABEL | RAW MLSLABEL | 該任務(wù)的信任Oracle會(huì)話符 | 
| CLEARANCE_HI | RAW MLSLABEL | 該任務(wù)可信任的Oracle最大間隙 | 
| CLEARANCE_LO | RAW MLSLABEL | 該任務(wù)可信任的Oracle最小間隙 | 
| NLS_ENV | VARCHAR2(2000) | 任務(wù)運(yùn)行的NLS會(huì)話設(shè)置 | 
| MISC_ENV | RAW(32) | 任務(wù)運(yùn)行的其他一些會(huì)話參數(shù) | 
????? 視圖DBA_JOBS_RUNNING的字段含義
| 列 | 數(shù)據(jù)類型 | 描述 | 
| SID | NUMBER | 目前正在運(yùn)行任務(wù)的會(huì)話ID | 
| JOB | NUMBER | 任務(wù)的唯一標(biāo)示符 | 
| FAILURES | NUMBER | 連續(xù)不成功執(zhí)行的累計(jì)次數(shù) | 
| LAST_DATE | DATE | 最后一次成功執(zhí)行的日期 | 
| LAST_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的last_date日期的小時(shí),分鐘和秒 | 
| THIS_DATE | DATE | 目前正在運(yùn)行任務(wù)的開始日期 | 
| THIS_SEC | VARCHAR2(8) | 如HH24:MM:SS格式的this_date日期的小時(shí),分鐘和秒 | 
任務(wù)重復(fù)運(yùn)行間隔和間隔設(shè)計(jì)算法任務(wù)重復(fù)運(yùn)行的時(shí)間間隔取決于interval參數(shù)中設(shè)置的日期表達(dá)式。下面就來詳細(xì)談?wù)勗撊绾卧O(shè)置interval參數(shù)才能準(zhǔn)確滿足我們的任務(wù)需求。一般來講,對于一個(gè)任務(wù)的定時(shí)執(zhí)行,有三種定時(shí)要求。
??? 在一個(gè)特定的時(shí)間間隔后,重復(fù)運(yùn)行該任務(wù)。
??? 在特定的日期和時(shí)間運(yùn)行任務(wù)。
??? 任務(wù)成功完成后,下一次執(zhí)行應(yīng)該在一個(gè)特定的時(shí)間間隔之后。
??? 第一種調(diào)度任務(wù)需求的日期算法比較簡單,即'SYSDATE+n',這里n是一個(gè)以天為單位的時(shí)間間隔。表6給出了一些這種時(shí)間間隔設(shè)置的例子。
??? 表6 一些簡單的interval參數(shù)設(shè)置例子
| 描述 | Interval參數(shù)值 | 
| 每天運(yùn)行一次 | 'SYSDATE + 1' | 
| 每小時(shí)運(yùn)行一次 | 'SYSDATE + 1/24' | 
| 每10分鐘運(yùn)行一次 | 'SYSDATE + 10/(60*24)' | 
| 每30秒運(yùn)行一次 | 'SYSDATE + 30/(60*24*60)' | 
| 每隔一星期運(yùn)行一次 | 'SYSDATE + 7' | 
| 不再運(yùn)行該任務(wù)并刪除它 | NULL | 
???? 表6所示的任務(wù)間隔表達(dá)式不能保證任務(wù)的下一次運(yùn)行時(shí)間在一個(gè)特定的日期或者時(shí)間,僅僅能夠指定一個(gè)任務(wù)兩次運(yùn)行之間的時(shí)間間隔。例如,如果一個(gè)任務(wù)第一次運(yùn)行是在凌晨12點(diǎn),interval指定為'SYSDATE + 1',則該任務(wù)將被計(jì)劃在第二天的凌晨12點(diǎn)執(zhí)行。但是,如果某用戶在下午4點(diǎn)手工(DBMS_JOB.RUN)執(zhí)行了該任務(wù),那么該任務(wù)將被重新定時(shí)到第二天的下午4點(diǎn)。還有一個(gè)可能的原因是如果數(shù)據(jù)庫關(guān)閉或者說任務(wù)隊(duì)列非常的忙以至于任務(wù)不能在計(jì)劃的那個(gè)時(shí)間點(diǎn)準(zhǔn)時(shí)執(zhí)行。在這種情況下,任務(wù)將試圖盡快運(yùn)行,也就是說只要數(shù)據(jù)庫一打開或者是任務(wù)隊(duì)列不忙就開始執(zhí)行,但是這時(shí),運(yùn)行時(shí)間已經(jīng)從原來的提交時(shí)間漂移到了后來真正的運(yùn)行時(shí)間。這種下一次運(yùn)行時(shí)間的不斷“漂移”是采用簡單時(shí)間間隔表達(dá)式的典型特征。
??? 第二種調(diào)度任務(wù)需求相對于第一種就需要更復(fù)雜的時(shí)間間隔(interval)表達(dá)式,表7是一些要求在特定的時(shí)間運(yùn)行任務(wù)的interval設(shè)置例子。
??? 表 7. 定時(shí)到特定日期或時(shí)間的任務(wù)例子
| 描述 | INTERVAL參數(shù)值 | 
| 每天午夜12點(diǎn) | 'TRUNC(SYSDATE + 1)' | 
| 每天早上8點(diǎn)30分 | 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)' | 
| 每星期二中午12點(diǎn) | 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24' | 
| 每個(gè)月第一天的午夜12點(diǎn) | 'TRUNC(LAST_DAY(SYSDATE ) + 1)' | 
| 每個(gè)季度最后一天的晚上11點(diǎn) | 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24' | 
| 每星期六和日早上6點(diǎn)10分 | 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)' | 
????? 第三種調(diào)度任務(wù)需求無論通過怎樣設(shè)置interval日期表達(dá)式也不能滿足要求。這時(shí)因?yàn)橐粋€(gè)任務(wù)的下一次運(yùn)行時(shí)間在任務(wù)開始時(shí)才計(jì)算,而在此時(shí)是不知道任務(wù)在何時(shí)結(jié)束的。遇到這種情況怎么辦呢?當(dāng)然辦法肯定是有的,我們可以通過為任務(wù)隊(duì)列寫過程的辦法來實(shí)現(xiàn)。這里我只是簡單介紹以下,可以在前一個(gè)任務(wù)隊(duì)列執(zhí)行的過程中,取得任務(wù)完成的系統(tǒng)時(shí)間,然后加上指定的時(shí)間間隔,拿這個(gè)時(shí)間來控制下一個(gè)要執(zhí)行的任務(wù)。這里有一個(gè)前提條件,就是目前運(yùn)行的任務(wù)本身必須要嚴(yán)格遵守自己的時(shí)間計(jì)劃。
總結(jié)
以上是生活随笔為你收集整理的oracle定时任务(dbms_job)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 如何培养孩子自主阅读(如何培养孩子的阅读
- 下一篇: x-requested-with 请求头
