Oracle中定時任務(wù)的使用(創(chuàng)建查看刪除等)
一、了解什么是定時任務(wù)?
job是oracle的定時任務(wù),又叫定時器,定時作業(yè),作業(yè)定時地自動執(zhí)行一些腳本,或作數(shù)據(jù)備份,或作數(shù)據(jù)提煉,或作數(shù)據(jù)庫性能的優(yōu)化,或作重建索引等等的工作,需要用到j(luò)ob。
Job是一種被調(diào)度執(zhí)行的任務(wù)。Job可以是一個PL/SQL塊、一個SQL語句、一個外部腳本或程序等。它們可以被定時調(diào)度執(zhí)行,也可以被手動啟動執(zhí)行。
二、創(chuàng)建job
Ⅰ、語法一
declare v_job_id number; begin dbms_job.submit(job =>v_job_id, --job號 what =>'pro_name/DML;', --定時執(zhí)行的腳本(簡稱你要干什么) next_date=>sysdate+1, --第一次執(zhí)行的時間 interval =>'SYSDATE+1/24/60' --間隔時間 ); --commit; end;
該語法是使用dbms_job包提交一個定時任務(wù):
- 1. `declare`和`begin`是PL/SQL代碼塊的開始和結(jié)束標(biāo)志。
- 2. `v_job_id`是一個變量,用于存儲job的id號。
- 3. `dbms_job.submit`是提交一個job的過程,包括以下參數(shù):
- - `job`:job的id號,由Oracle自動生成。
- - `what`:定時執(zhí)行的腳本,可以是一個存儲過程或SQL語句。
- - `next_date`:job第一次執(zhí)行的時間,可以是一個日期類型的變量或者表達式。
- - `interval`:job的執(zhí)行間隔時間,可以是一個日期類型的變量或者表達式,例如`SYSDATE+1/24/60`表示每隔1分鐘執(zhí)行一次。
- 4. `commit`是一個事務(wù)提交語句,用于將提交的job保存到數(shù)據(jù)庫中。
注意:
使用dbms_job提交的job只能在Oracle數(shù)據(jù)庫中執(zhí)行,不能跨數(shù)據(jù)庫執(zhí)行。另外,使用dbms_job提交的job在Oracle 10g及以上版本中已經(jīng)被廢棄,推薦使用dbms_scheduler包提交job。
比如創(chuàng)建定時任務(wù),每分鐘執(zhí)行一次pkg_2.p1,向emp2表中插入員工編號為7788的員工信息:
declare v1 number; begin dbms_job.submit(job => v1, what => 'insert into emp2 select * from emp where empno=7788;', next_date => sysdate,--立即執(zhí)行 interval => 'SYSDATE+1/24/60'); commit; end;
其中emp2表為空表,查詢當(dāng)前時間,然后我們執(zhí)行這個定時任務(wù)
select sysdate from dual;
等待一段時間后,我們查看表emp2內(nèi)的數(shù)據(jù):
經(jīng)過四分鐘后,從表中可以發(fā)現(xiàn)有四條數(shù)據(jù)。
Ⅱ、語法二:
使用DBMS_SCHEDULER包來創(chuàng)建和管理job,具體語法如下:
BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'job_name', -- job的名稱 job_type => 'PLSQL_BLOCK', -- job的類型,可以是PLSQL_BLOCK、STORED_PROCEDURE等 job_action => 'begin my_proc(); end;', -- job執(zhí)行的腳本或存儲過程 start_date => SYSTIMESTAMP, -- job開始執(zhí)行的時間 repeat_interval => 'FREQ=DAILY; INTERVAL=1', -- job執(zhí)行的間隔時間 enabled => TRUE -- 是否啟用job ); END; /
DBMS_SCHEDULER包提供了豐富的job管理功能,可以設(shè)置job的執(zhí)行時間、執(zhí)行間隔、執(zhí)行次數(shù)、執(zhí)行優(yōu)先級、并發(fā)控制等屬性,實際應(yīng)用中可以根據(jù)具體需求靈活配置。
三、查看job
select * from user_jobs;
結(jié)果如下:
從運行結(jié)果中可以知道定時任務(wù)的JOB編號為23,登錄用戶為SCOTT等信息。
其中user_jobs是一個視圖,是 Oracle 數(shù)據(jù)庫中的一個系統(tǒng)表,它用于存儲由 DBMS_JOB.SUBMIT 提交的作業(yè)(job)的信息。該表包含了提交的作業(yè)的 ID 號、作業(yè)的描述、作業(yè)的下一次執(zhí)行時間、作業(yè)的執(zhí)行間隔時間、作業(yè)的狀態(tài)等信息。用戶可以查詢該表來獲取作業(yè)的信息,也可以使用該表來管理作業(yè)的狀態(tài)、修改作業(yè)的執(zhí)行時間等。
注意:
該表只能查看和管理由當(dāng)前用戶提交的作業(yè),不能查看和管理其他用戶提交的作業(yè)。
其實在Oracle中,可以使用以下SQL語句來查看定時任務(wù)Job的信息:
SELECT job_name, job_type, enabled, state, last_start_date, next_run_date FROM dba_scheduler_jobs;
該語句會列出所有的Job,包括Job的名稱、類型、是否啟用、狀態(tài)、上次執(zhí)行時間和下次執(zhí)行時間等信息。其中,dba_scheduler_jobs是一個系統(tǒng)視圖,可以查看所有的Job信息。如果只需要查看當(dāng)前用戶的Job,可以使用USER_SCHEDULER_JOBS視圖。
另外,也可以使用以下SQL語句來查看某個Job的詳細信息:
SELECT * FROM dba_scheduler_jobs WHERE job_name = 'job_name';
該語句會列出指定Job的所有信息,包括Job的類型、執(zhí)行時間、重復(fù)間隔、執(zhí)行程序等。
查看定時任務(wù)Job的信息只需要使用一些系統(tǒng)視圖或者SQL語句就可以輕松實現(xiàn)。這些信息可以幫助管理員了解定時任務(wù)的執(zhí)行情況,及時發(fā)現(xiàn)和解決問題。
四、刪除Job
Ⅰ、調(diào)用dbms_job.remove實現(xiàn):
call dbms_job.remove(23); commit;
從上面查看job信息知道編號是23!然后調(diào)用存過 dbms_job.remove
其中dbms_job.remove是一個包名,是Oracle 數(shù)據(jù)庫中的一個過程,用于刪除一個已經(jīng)存在的作業(yè)(job)。它的語法如下:
DBMS_JOB.REMOVE ( job IN BINARY_INTEGER);
其中,job 參數(shù)表示要刪除的作業(yè)的 ID 號。調(diào)用該過程后,指定 ID 號的作業(yè)將被從數(shù)據(jù)庫中刪除。
注意:
該過程只能刪除由 DBMS_JOB.SUBMIT 提交的作業(yè),不能刪除由 DBMS_SCHEDULER.SUBMIT 創(chuàng)建的作業(yè)。
Ⅱ、使用下面語句完成job刪除:
BEGIN DBMS_SCHEDULER.DROP_JOB ( job_name => 'job_name', -- job的名稱 force => FALSE -- 是否強制刪除job ); END; /
其中,job_name是要刪除的Job的名稱,force參數(shù)表示是否強制刪除Job。如果force參數(shù)為TRUE,則會強制刪除Job及其關(guān)聯(lián)的所有對象(例如,程序、鏈、計劃等)。如果force參數(shù)為FALSE,則只會刪除Job本身。
五、停止Job
begin dbms_job.broken(23,true); commit; end;
上述命令即可停止job的執(zhí)行。
其中dbms_job.broken 是 Oracle 數(shù)據(jù)庫中的一個過程,用于標(biāo)記一個作業(yè)(job)為失效狀態(tài)。它的語法如下:
DBMS_JOB.BROKEN ( job IN BINARY_INTEGER, broken IN BOOLEAN, next_date IN DATE DEFAULT NULL, interval IN VARCHAR2 DEFAULT NULL);
其中,job 參數(shù)表示要標(biāo)記為失效的作業(yè)的 ID 號;broken 參數(shù)表示是否將作業(yè)標(biāo)記為失效狀態(tài),true 表示失效,false 表示恢復(fù);next_date 參數(shù)表示作業(yè)下一次執(zhí)行的時間;interval 參數(shù)表示作業(yè)執(zhí)行的間隔時間。
調(diào)用該過程后,指定 ID 號的作業(yè)將被標(biāo)記為失效狀態(tài)。如果 broken 參數(shù)為 true,則該作業(yè)將被標(biāo)記為失效,不再執(zhí)行;如果為 false,則該作業(yè)將被恢復(fù)為正常狀態(tài)。如果指定了 next_date 和 interval 參數(shù),則會更新作業(yè)的下一次執(zhí)行時間和執(zhí)行間隔時間。
或者使用下面命令也可以實現(xiàn)停止job:
BEGIN DBMS_SCHEDULER.STOP_JOB ( job_name => 'job_name', force_option => 'IMMEDIATE', commit_semantics=> 'ABORT'); END;
其中,job_name是要停止的Job的名稱,force_option參數(shù)表示停止Job的方式,可以為IMMEDIATE或CASCADE。如果force_option為IMMEDIATE,則會立即停止Job的執(zhí)行。如果force_option為CASCADE,則會將Job及其關(guān)聯(lián)的所有對象都停止。commit_semantics參數(shù)表示停止Job的提交語義,可以為COMMIT或ABORT。如果commit_semantics為COMMIT,則會提交Job的事務(wù),并將Job狀態(tài)設(shè)置為STOPPED。如果commit_semantics為ABORT,則會回滾Job的事務(wù),并將Job狀態(tài)設(shè)置為BROKEN。
六、立即執(zhí)行job
call dbms_job.run(23);
dbms_job.run 是 Oracle 數(shù)據(jù)庫中的一個過程,用于立即執(zhí)行一個作業(yè)(job)。它的語法如下:
DBMS_JOB.RUN ( job IN BINARY_INTEGER);
其中,job 參數(shù)表示要執(zhí)行的作業(yè)的 ID 號。調(diào)用該過程后,指定 ID 號的作業(yè)將被立即執(zhí)行一次。如果該作業(yè)正在執(zhí)行中,則該過程不會產(chǎn)生任何效果,直到該作業(yè)執(zhí)行完畢后再執(zhí)行一次。
注意:
該過程也是只能執(zhí)行由 DBMS_JOB.SUBMIT 提交的作業(yè),不能執(zhí)行由 DBMS_SCHEDULER.SUBMIT 創(chuàng)建的作業(yè)。
七、修改job
BEGIN DBMS_SCHEDULER.SET_ATTRIBUTE ( name => 'job_name', -- job的名稱 attribute => 'start_date', -- 要修改的屬性名稱 value => SYSTIMESTAMP + INTERVAL '1' DAY -- 修改后的屬性值 ); END; /
該語法是使用DBMS_SCHEDULER包修改job的開始時間:
- 1. `BEGIN`和`END`是PL/SQL代碼塊的開始和結(jié)束標(biāo)志。
- 2. `DBMS_SCHEDULER.SET_ATTRIBUTE`是修改job屬性的過程,包括以下參數(shù):
- - `name`:job的名稱。
- - `attribute`:要修改的屬性名稱,可以是start_date、repeat_interval、end_date等。
- - `value`:修改后的屬性值,可以是一個日期類型的變量或者表達式。
- 3. `job_name`是要修改的job的名稱。
- 4. `SYSTIMESTAMP + INTERVAL '1' DAY`表示將job的開始時間修改為當(dāng)前時間加上1天后的時間。
- 5. `/`是PL/SQL代碼塊的結(jié)束標(biāo)志。
注意:
使用DBMS_SCHEDULER包修改job的屬性時,需要保證job已經(jīng)存在。如果job不存在,則需要先使用CREATE_JOB過程創(chuàng)建job,然后再使用SET_ATTRIBUTE過程修改job的屬性。
八、job執(zhí)行失敗
job 執(zhí)行失敗可能有多種原因,例如作業(yè)的執(zhí)行時間沖突、作業(yè)依賴的對象不存在或無效、作業(yè)執(zhí)行時發(fā)生錯誤等。以下是一些常見的解決方法:
- 1. 檢查作業(yè)的執(zhí)行時間是否與其他作業(yè)沖突,如果沖突則需要調(diào)整作業(yè)的執(zhí)行時間。
- 2. 檢查作業(yè)依賴的對象是否存在或有效,如果不存在或無效則需要修復(fù)或重新創(chuàng)建這些對象。
- 3. 檢查作業(yè)執(zhí)行時是否發(fā)生了錯誤,如果發(fā)生了錯誤則需要查看錯誤日志或調(diào)試信息,修復(fù)錯誤并重新執(zhí)行作業(yè)。
- 4. 檢查作業(yè)的執(zhí)行權(quán)限是否正確,如果權(quán)限不足則需要授權(quán)或修改作業(yè)的執(zhí)行用戶。
- 5. 檢查作業(yè)的定時器是否正確,如果定時器不正確則需要修改作業(yè)的執(zhí)行時間或執(zhí)行間隔。
- 6. 檢查作業(yè)的運行環(huán)境是否正確,例如作業(yè)依賴的環(huán)境變量、路徑、配置文件等是否正確設(shè)置。
- 7. 如果以上方法都無法解決問題,則需要進一步分析作業(yè)執(zhí)行的情況,例如查看作業(yè)的日志、調(diào)試信息、執(zhí)行計劃等,找出問題并修復(fù)。
總結(jié):
解決 job 執(zhí)行失敗問題需要綜合考慮多個因素,需要對作業(yè)的執(zhí)行情況進行全面分析和細致調(diào)試,才能找到問題并解決。同時,為了避免作業(yè)執(zhí)行失敗,需要在設(shè)計作業(yè)時考慮各種可能的情況,并采取相應(yīng)的措施來保證作業(yè)的正確執(zhí)行。
如果一個作業(yè)(job)執(zhí)行失敗,Oracle 數(shù)據(jù)庫會根據(jù)作業(yè)的重試次數(shù)和重試間隔時間來進行重試。默認情況下,Oracle 數(shù)據(jù)庫會在作業(yè)執(zhí)行失敗后立即進行重試,最多重試 16 次,每次重試的間隔時間為 5 分鐘。也就是說,如果一個作業(yè)執(zhí)行失敗,Oracle 數(shù)據(jù)庫會在 5 分鐘后再次嘗試執(zhí)行該作業(yè),如果該次執(zhí)行仍然失敗,則會繼續(xù)重試,直到達到最大重試次數(shù)為止。
注意:
作業(yè)的重試次數(shù)和重試間隔時間可以通過 DBMS_JOB.CHANGE 或 DBMS_SCHEDULER.SET_ATTRIBUTE 進行修改。用戶可以根據(jù)實際情況來設(shè)置作業(yè)的重試次數(shù)和重試間隔時間,以便更好地管理作業(yè)的執(zhí)行。同時,如果作業(yè)的重試次數(shù)和重試間隔時間設(shè)置不當(dāng),可能會導(dǎo)致作業(yè)長時間無法執(zhí)行或頻繁重試,影響系統(tǒng)的穩(wěn)定性和性能。因此,在設(shè)置作業(yè)的重試次數(shù)和重試間隔時間時需要慎重考慮。
通常情況下:
- 1、每次重試時間都是遞增的,第一次1分鐘,2分鐘,4分鐘,8分鐘 ... 依此類推。
- 2、當(dāng)超過1440分鐘,也就是24小時的時候,固定的重試時間為1天。
- 3、超過16次重試后,job就會被標(biāo)記為broken,next_date為4000-1-1,也就是不再進行job重試。16次重試的時間大概是7天半。
其中前兩條這樣設(shè)計的目的是為了避免在短時間內(nèi)頻繁地重試,降低系統(tǒng)的負載,同時也能夠保證任務(wù)能夠在合理的時間內(nèi)得到處理。
而第三條是因為在 Oracle 中,如果一個作業(yè)(job)執(zhí)行失敗達到最大重試次數(shù)后,該作業(yè)會被標(biāo)記為 "broken" 狀態(tài),同時下一次執(zhí)行時間會被設(shè)置為 4000-01-01,即不再對該作業(yè)進行重試。這是 Oracle 數(shù)據(jù)庫的默認行為,旨在防止無限制地重試失敗的作業(yè),避免對系統(tǒng)造成過大的負擔(dān)和風(fēng)險。
當(dāng)作業(yè)被標(biāo)記為 "broken" 狀態(tài)后,用戶可以通過調(diào)用 DBMS_JOB.BROKEN 過程來修改作業(yè)的狀態(tài),例如將作業(yè)恢復(fù)為正常狀態(tài)、更新作業(yè)的下一次執(zhí)行時間和執(zhí)行間隔時間等。同時,用戶也可以通過修改作業(yè)的重試次數(shù)和重試間隔時間來避免作業(yè)被標(biāo)記為 "broken" 狀態(tài),以便更好地管理作業(yè)的執(zhí)行。
注意:
對于那些不需要重試的作業(yè),用戶可以將其重試次數(shù)設(shè)置為 0,以避免對系統(tǒng)造成不必要的負擔(dān)和風(fēng)險。
如果Oracle中出現(xiàn)job重復(fù)調(diào)用16次的情況,可能是由于job的重試機制導(dǎo)致的。為了避免這種情況,可以考慮以下幾種解決辦法:
- 1. 修改job的重試次數(shù)和重試時間:可以通過修改job的重試次數(shù)和重試時間來避免job出現(xiàn)過多的重試??梢詫⒅卦嚧螖?shù)設(shè)置為一個較小的值,例如3次或5次,同時將重試時間設(shè)置為一個適當(dāng)?shù)闹担缑看沃卦囍g間隔5分鐘或10分鐘。
- 2. 使用唯一的標(biāo)識符:可以在job中使用唯一的標(biāo)識符來避免重復(fù)調(diào)用。例如,可以在job中設(shè)置一個唯一的ID,每次調(diào)用時檢查該ID是否已經(jīng)存在,如果存在則不繼續(xù)執(zhí)行,否則執(zhí)行任務(wù)。
- 3. 使用分布式鎖:可以使用分布式鎖來避免job重復(fù)調(diào)用。例如,可以使用Redis等分布式緩存工具來實現(xiàn)分布式鎖,每次調(diào)用job時先獲取鎖,執(zhí)行任務(wù)完畢后釋放鎖,這樣可以保證同一時間只有一個job在執(zhí)行。
- 4. 使用數(shù)據(jù)庫事務(wù):可以使用數(shù)據(jù)庫事務(wù)來避免job重復(fù)調(diào)用。例如,在job執(zhí)行前先檢查數(shù)據(jù)庫中是否已經(jīng)存在相同的記錄,如果存在則回滾事務(wù),否則執(zhí)行任務(wù)并提交事務(wù)。
我們也可以創(chuàng)建一張空表,用來接收數(shù)據(jù) create table t_k(id number(1)),然后創(chuàng)建一個存過,里面包含真實的存儲過程。如下所示:
create or replace pro_寫到j(luò)ob中 is v_cnt number; begin insert into t_k(id) values(1); commit; select count(1) into v_cnt from t_k; if v_cnt=1 then pro_真實(); 正確處理; else 錯誤處理(比如向報錯表中插入一條數(shù)據(jù);打印錯誤;raise_application_error報錯;發(fā)郵件) end if; end; declare v_jobid number; begin dbms_job.submit(job => v_jobid, what => 'pro_寫到j(luò)ob中', next_date => trunc(sysdate,'dd')+3/24,--第一次執(zhí)行的時間,夜里三點 interval => 'trunc(sysdate,''dd'')+1');--間隔時間,每天執(zhí)行 commit; end;
九、job用法
接下來展示一個完整的job用例?。。?/p>
假設(shè)我們需要定期清理一個名為CUSTOMER的表中的過期數(shù)據(jù),使用Job來實現(xiàn)。
1. 創(chuàng)建一個PL/SQL塊,用于清理過期數(shù)據(jù):
CREATE OR REPLACE PROCEDURE clean_customer_data AS BEGIN DELETE FROM customer WHERE expiration_date < SYSDATE; COMMIT; END;
2. 創(chuàng)建一個Job,用于定期執(zhí)行clean_customer_data存儲過程:
BEGIN DBMS_SCHEDULER.CREATE_JOB ( job_name => 'clean_customer_data_job', job_type => 'STORED_PROCEDURE', job_action => 'clean_customer_data', start_date => SYSDATE, repeat_interval => 'FREQ=DAILY; INTERVAL=1', enabled => TRUE, comments => '清理過期數(shù)據(jù)'); END;
其中,job_name是Job的名稱,job_type表示Job的類型,可以為STORED_PROCEDURE、PLSQL_BLOCK、EXECUTABLE等。job_action是要執(zhí)行的任務(wù),可以是存儲過程、PL/SQL塊、外部程序等。start_date是Job的開始時間,repeat_interval表示Job的重復(fù)執(zhí)行間隔,可以使用各種時間間隔語法。enabled表示Job是否啟用,comments是Job的注釋。
3. 檢查Job是否正常運行:
SELECT job_name, state, last_start_date, next_run_date FROM dba_scheduler_jobs WHERE job_name = 'clean_customer_data_job';
該語句可以查看Job的狀態(tài)、上次執(zhí)行時間和下次執(zhí)行時間等信息。
4. 如果需要停止或刪除Job,可以使用以下語句:
停止Job:
BEGIN DBMS_SCHEDULER.STOP_JOB ( job_name => 'clean_customer_data_job', force_option => 'IMMEDIATE', commit_semantics=> 'ABORT'); END;
刪除Job:
BEGIN DBMS_SCHEDULER.DROP_JOB ( job_name => 'clean_customer_data_job', force => TRUE); END;
以上就是一個簡單的Job的使用示例,通過Job可以實現(xiàn)各種定時任務(wù),提高數(shù)據(jù)庫的自動化管理能力。
到此這篇關(guān)于Oracle中定時任務(wù)的使用(創(chuàng)建查看刪除等)的文章就介紹到這了,更多相關(guān)Oracle 定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于sql腳本導(dǎo)入Oracle時重復(fù)生成check約束的問題解決
這篇文章主要給大家介紹了關(guān)于sql腳本導(dǎo)入Oracle時重復(fù)生成check約束的問題解決方法,文中給出了詳細的檢查步驟,對大家理解和解決這個問題具有很好的幫助,需要的朋友們下面來一起看看吧。2017-05-05從Oracle數(shù)據(jù)庫中讀取數(shù)據(jù)自動生成INSERT語句的方法
今天小編就為大家分享一篇關(guān)于從Oracle數(shù)據(jù)庫中讀取數(shù)據(jù)自動生成INSERT語句的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04Oracle?數(shù)據(jù)庫中的全文搜索整體流程分析
Oracle 是一種功能強大的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),它提供了各種功能來處理和管理大量的數(shù)據(jù),這篇文章主要介紹了Oracle?數(shù)據(jù)庫中的全文搜索功能,需要的朋友可以參考下2024-04-04oracle 數(shù)據(jù)庫閃回相關(guān)語句介紹
本文將詳細介紹oracle 數(shù)據(jù)庫閃回相關(guān)語句,需要了解跟多的朋友可以參考下2012-11-11Oracle實現(xiàn)動態(tài)SQL的拼裝要領(lǐng)
這篇文章主要介紹了Oracle實現(xiàn)動態(tài)SQL的拼裝要領(lǐng),對于Oracle的進一步學(xué)習(xí)來說非常重要,需要的朋友可以參考下2014-07-07oracle中對JSON數(shù)據(jù)處理的詳細指南
很多人對JSON不陌生,JSON(JavaScript Object Notation)是一種輕量級的數(shù)據(jù)交換格式,下面這篇文章主要給大家介紹了關(guān)于oracle中對JSON數(shù)據(jù)處理的詳細指南,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-05-05