DBMS_SCHEDULER常規操作


轉自:http://blog.163.com/felex_cheng@126/blog/static/41047005201110141121210/

參考資料1:

3.2 Schedules調度Programs執行的Jobs
  通過schedule調度program的執行的job,看到這樣的形容是不是讓你徹底暈頭了,就說明你還是沒搞明白10g中SCHEDULERS特性管理的jobs的含意,讓三思更直白地給你描述描述。10g版本中SCHEDULER將JOB分成了多個部分,program負責做什么,schedule負責啥時候做,job就簡單了,一個字:做。
  前面幾個小節,三思已經分別演示了創建管理Jobs,創建管理Programs以及創建和管理Schedules,下面我們通過實例來演示,如何創建通過schedule調度program的執行的job吧。
  首先,創建一個program,操作如下:
SQL> BEGIN
  2  DBMS_SCHEDULER.CREATE_PROGRAM (
  3     program_name           => ¨my_program1¨,
  4     program_action         => ¨/bin/date¨,
  5     program_type           => ¨EXECUTABLE¨,
  6     enabled                => TRUE);
  7  END;
  8  /
PL/SQL procedure successfully completed.
  通過上述語句,我們定義了一個program,執行操作系統命令date,並輸入到dt.log文件中。
  接下來定義一個schedule,操作如下:
SQL> begin
  2  DBMS_SCHEDULER.CREATE_SCHEDULE (
  3    schedule_name     => ¨my_first_schedule¨,
  4    start_date        => SYSDATE,
  5    repeat_interval   => ¨FREQ= DAILY ; INTERVAL=1¨,
  6    comments          => ¨Every 1 weeks¨);
  7  END;
  8  /
PL/SQL procedure successfully completed.
  定義調試為每周執行一次。此處repeat_interval可根據實現情況進行修改。
  最后,創建job,按照指定的schedule,執行program,操作如下:
SQL> BEGIN
  2  DBMS_SCHEDULER.CREATE_JOB (
  3     job_name           =>  ¨execOScmd¨,
  4     program_name       =>  ¨my_program1¨,
  5     schedule_name      =>  ¨my_first_schedule¨,
  6     enabled            =>  true);
  7  END;
  8  /
PL/SQL procedure successfully completed.
1.創建job
可以有兩種方式來定義"計划":
1) 使用DBMS_SCHDULER.CREATE_SCHEDULE 定義一個計划;
2) 調用DBMS_SCHDULER.CREATE_JOBE過程直接指定 
job_type: 目前支持三種類型:
PL/SQL塊: PLSQL_BLOCK,
存儲過程: STORED_PROCEDURE
外部程序: EXECUTABLE (外部程序可以是一個shell腳本,也可以是操作系統級別的指令).
job_action: 根據job_type的不同,job_action有不同的含義.
如果job_type指定的是存儲過程,就需要指定存儲過程的名字;
如果job_type指定的是PL/SQL塊,就需要輸入完整的PL/SQL代碼;
如果job_type指定的外部程序,就需要輸入script的名稱或者操作系統的指令名
enabled: 上面已經說過了,指定job創建完畢是否自動激活
comments: 對於job的簡單說明
2. 指定job的執行頻率
如果我們創建了一個job,並且希望它按照我們指定的日期和時間來運行,就需要定義job的重復頻度了. 例如每天運行,每周日的22:00運行, 每周一,三,五運行,每年的最后一個星期天運行等等.
(說明:10G以前的版本,與操作系統的交互方面,實現的不是很好。例如要實現一個定期的rman備份任務,就需要結合OS的命令來實現,在UNIX下可以用crontab實現,在windows下用AT命令來實現)
10G 在這方面有了很大的增強,因為創建job時可以直接指定操作系統的命令或者腳本,再合理的定義job的執行頻率,可以很輕松地完成復雜的調度任務.
10G 支持兩種模式的repeat_interval,一種是PL/SQL表達式,這也是dbms_job包中所使用的,例如SYSDATE 1, SYSDATE 30/24*60; 另一種就是日歷表達式。
例如MON表示星期一,SUN表示星期天,DAY表示每天,WEEK表示每周等等. 下面來看幾個使用日歷表達式的例子:
repeat_interval => 'FREQ=HOURLY; INTERVAL=2'
每隔2小時運行一次job
repeat_interval => 'FREQ=DAILY'
每天運行一次job
repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI"
每周的1,3,5運行job
repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=30'
每年的3,6,9,12月的30號運行job
用過crontab的人應該都有種似曾相識的感覺吧,呵呵
下面再說說使用日歷表達式的規則:
日歷表達式基本分為三部分: 第一部分是頻率,也就是"FREQ"這個關鍵字,它是必須指定的; 第二部分是時間間隔,也就是"INTERVAL"這個關鍵字,取值范圍是1-999. 它是可選的參數; 最后一部分是附加的參數,可用於精確地指定日期和時間,它也是可選的參數,例如下面這些值都是合法的:
BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY
BYHOUR,BYMINUTE,BYSECOND
詳細的參數說明請參考 dbms_scheduler的使用說明.
既然說到了repeat_interval,你可能要問:"有沒有一種簡便的方法來得出,或者說是評估出job的每次運行時間,以及下一次的運行時間呢?"
dbms_scheduler包提供了一個過程evaluate_calendar_string,可以很方便地完成這個需求. 
 
 
 
      創建job時,start_date,repeat_interval,job_action等均無須指定,因為這些參數將由program和schedule來控制。
  這樣,操作完成后,ORACLE就會自動定時(當前設置為每周執行一次)program中定義的操作。
 雖然說jobs大多都應該是自動執行,不過經過前面的示例,大家想必也認識到了,並不是說創建了jobs它就會自動執行,是否能夠真正自動執行並不是由你的主觀意願就能直接決定,而是由jobs自身的多個相關屬性決定。
  關於jobs自動執行的話題相信看完前面的內容后,應該都知道如何設置,下面主要演示,如何手動調用jobs並執行,這其中,當然少不了DBMS_SCHEDULER包。例如,手動執行前面剛剛創建的job:INSERT_TEST_TBL:
SQL> exec dbms_scheduler.run_job(¨INSERT_TEST_TBL¨);
PL/SQL procedure successfully completed
  Jobs 每執行一次,無論成功或失敗,均會在*_SCHEDULER_JOB_LOG中生成一條對應的記錄(前提是LOGGING_LEVEL屬性值未設置為DBMS_SCHEDULER.LOGGING_OFF),同時,用戶也可以通過*_SCHEDULER_JOB_RUN_DETAILS視圖查詢job執行的詳細信息。
 
 停止job可以使用DMBS_SCHEDULER.STOP_JOB過程,例如:
SQL> exec dbms_scheduler.stop_job(¨INSERT_TEST_TBL¨);
PL/SQL procedure successfully completed
  注意,STOP_JOB過程不僅僅是更新job的狀態,而是停止當前正在執行的任務,如果你處理的任務當前未在運行的話,那么執行STOP_JOB過程,會觸發ORA-27366錯誤。
  停止Jobs也會觸發一條任務的日志信息,對於執行停止操作的job,其*_SCHEDULER_JOB_LOG視圖的OPERATION會記錄為¨STOPPED¨,ADDITIONAL_INFO列中記錄的信息類似¨REASON="Stop job called by user: username"¨。
 
  要查看當前的執行情況,通過*_scheduler_job_run_details即可查詢(*_scheduler_job_log也可以,不過該視圖中信息不如detail中全面)。例如,查看剛剛創建的"EXECOSCMD"任務的執行情況,執行命令如下:
SQL> select log_id, log_date, status, additional_info
  2    from user_scheduler_job_run_details
  3   where job_name = ¨EXECOSCMD¨
  4  ;
    LOG_ID LOG_DATE             STATUS     ADDITIONAL_INFO
---------- -------------------- ---------- ------------------------------
     13760 17-AUG-09 02.47.53.7 SUCCEEDED
           34050 PM 08:00
  看完這個示例之后,你是否對10g中的SCHEDULER特性多了些了解呢?千萬表自滿,SCHEDULER特性的功能還多着哪,接着往下看吧。
 
============================================================================================
 
只用DBMS_SCHDULER.CREATE_JOB來創建job:
 
grant exexcute on dbms_scheduler to u1;
grant create job,create externale job to u1;
 
begin
       dbms_scheduler.create_job
      (
        job_name => 'job1',
        job_type => 'EXECUTABLE',
        repeat_interval => 'freq=daily;interval=1',
        job_action => '/home/dbtools/move_arcs.sh',
        enabled => true,
        comments => 'Move Archived Logs to a Different Directory'
      );
end;
/
手動執行一次: exec dbms_scheduler.run_job('job1');
                      exec dbms_scheduler.stop_job('job1');
刪除job       : exec dbms_scheduler.drop_job('job1');
查看相關表   : select * from dbms_sheduler_jobs;
                      select * from dbms_scheduler_job_run_details;
 參考資料2:

DBMS_SCHEDULER是Oracle 10G中新增的一個包,與老版本的dbms_job包相比,dbms_scheduler有很多新特性,我將通過一系列的文章來介紹一下如何使用這個包.
1. 創建job
job是什么呢? 簡單的說就是計划(schedule)加上任務說明. 另外還有一些必須的參數.
這里提到的"任務"可以是數據庫內部的存儲過程,匿名的PL/SQL塊,也可以是操作系統級別的腳本.
可以有兩種方式來定義"計划":
1) 使用DBMS_SCHDULER.CREATE_SCHEDULE 定義一個計划;
2) 調用DBMS_SCHDULER.CREATE_JOBE過程直接指定 (下面會詳細說明)
在創建一個計划時,你至少需要指定下面的屬性,它們是job運行所必須的:
開始時間 (start_time);
重復頻率 (repeat_interval);
結束時間 (end_time)
另外,對於一個job而言,還有很多的附加參數:
job_class
job_priority
auto_drop
restartable
max_runs
max_failures
schedule_limit
logging_level
下面,我以問答的形式來具體解釋.
Q1:怎么從數據庫中查詢job的屬性 ?
A1: 有兩種方法:
1) 查詢(DBA|ALL|USER)_SCHEDULER_JOBS 視圖
(提示: 根據用戶權限的不同,選擇性的查詢 DBA|ALL|USER視圖)
2) 調用DBMS_SCHEDULER包中的GET_ATTRIBUTE 過程
Q2: 怎么設置這些屬性呢?
A2: 也是有兩種方法
1) 在創建job時直接指定
2) 調用DBMS_SCHEDULER包中的SET_ATTRIBUTE 過程
Q3: "我需要什么權限才能創建job" ?
它可以創建屬主為任何用戶(SYS用戶除外)的job.
缺省情況下,job會被創建在當前的schema下,並且是沒有激活的; 如果要使job一創建
就自動激活,需要顯式的設置enabled 屬性為true, 來看一個例子:
begin
dbms_scheduler.create_job
(
job_name => 'ARC_MOVE',
schedule_name => 'EVERY_60_MINS',
job_type => 'EXECUTABLE',
job_action => '/home/dbtools/move_arcs.sh',
enabled => true,
comments => 'Move Archived Logs to a Different Directory'
);
end;
/
Q4: 能不能詳細地講述一下上面這個過程用到的各個參數?
A4:
job_name: 顧名思義,每個job都必須有一個的名稱
schedule_name: 如果定義了計划,在這里指定計划的名稱
job_type: 目前支持三種類型:
PL/SQL塊: PLSQL_BLOCK,
存儲過程: STORED_PROCEDURE
外部程序: EXECUTABLE (外部程序可以是一個shell腳本,也可以是操作系統級別的指令).
job_action: 根據job_type的不同,job_action有不同的含義.
如果job_type指定的是存儲過程,就需要指定存儲過程的名字;
如果job_type指定的是PL/SQL塊,就需要輸入完整的PL/SQL代碼;
如果job_type指定的外部程序,就需要輸入script的名稱或者操作系統的指令名
enabled: 上面已經說過了,指定job創建完畢是否自動激活
comments: 對於job的簡單說明
2. 指定job的執行頻率
如果我們創建了一個job,並且希望它按照我們指定的日期和時間來運行,就需要定義job的重復頻度了. 例如每天運行,每周日的22:00運行, 每周一,三,五運行,每年的最后一個星期天運行等等.
(說明:10G以前的版本,與操作系統的交互方面,實現的不是很好。例如要實現一個定期的rman備份任務,就需要結合OS的命令來實現,在UNIX下可以用crontab實現,在windows下用AT命令來實現)
10G 在這方面有了很大的增強,因為創建job時可以直接指定操作系統的命令或者腳本,再合理的定義job的執行頻率,可以很輕松地完成復雜的調度任務.
10G 支持兩種模式的repeat_interval,一種是PL/SQL表達式,這也是dbms_job包中所使用的,例如SYSDATE 1, SYSDATE 30/24*60; 另一種就是日歷表達式。
例如MON表示星期一,SUN表示星期天,DAY表示每天,WEEK表示每周等等. 下面來看幾個使用日歷表達式的例子:
repeat_interval => 'FREQ=HOURLY; INTERVAL=2'
每隔2小時運行一次job
repeat_interval => 'FREQ=DAILY'
每天運行一次job
repeat_interval => 'FREQ=WEEKLY; BYDAY=MON,WED,FRI"
每周的1,3,5運行job
repeat_interval => 'FREQ=YEARLY; BYMONTH=MAR,JUN,SEP,DEC; BYMONTHDAY=30'
每年的3,6,9,12月的30號運行job
用過crontab的人應該都有種似曾相識的感覺吧,呵呵
下面再說說使用日歷表達式的規則:
日歷表達式基本分為三部分: 第一部分是頻率,也就是"FREQ"這個關鍵字,它是必須指定的; 第二部分是時間間隔,也就是"INTERVAL"這個關鍵字,取值范圍是1-999. 它是可選的參數; 最后一部分是附加的參數,可用於精確地指定日期和時間,它也是可選的參數,例如下面這些值都是合法的:
BYMONTH,BYWEEKNO,BYYEARDAY,BYMONTHDAY,BYDAY
BYHOUR,BYMINUTE,BYSECOND
詳細的參數說明請參考 dbms_scheduler的使用說明.

轉自:http://www.xifenfei.com/2230.html

1.create job

BEGIN
   DBMS_SCHEDULER.CREATE_JOB(
   job_name => 'xifenfei_job' ,
   job_type => 'STORED_PROCEDURE' ,
   job_action => 'p_schedule' ,
   repeat_interval => 'FREQ=DAILY; BYHOUR=18,20,22' ,
   enabled => true ,
   comments => 'XIFENFEI' );
END
--每天18/20/22點執行p_schedule過程

2.disable job
BEGIN
DBMS_SCHEDULER.DISABLE(name => 'xifenfei_job');
END;
3.enable job
BEGIN
DBMS_SCHEDULER.ENABLE(name => 'xifenfei_job');
END;
4.select job
select * from USER_SCHEDULER_JOBS;
5.query logs
SELECT * FROM USER_SCHEDULER_JOB_RUN_DETAILS
WHERE job_name='XIFENFEI_JOB';
6.delete logs
--ALL_SCHEDULER_JOB_RUN_DETAILS視圖
CREATE OR REPLACE VIEW ALL_SCHEDULER_JOB_RUN_DETAILS
(log_id, log_date, owner, job_name, job_subname, status, error#,
req_start_date, actual_start_date, run_duration, instance_id,
session_id, slave_pid, cpu_used, credential_owner, credential_name,
destination_owner, destination, additional_info)
AS
(SELECT
j.LOG_ID, j.LOG_DATE, e.OWNER,
DECODE(instr(e.NAME,'"'),0, e.NAME,substr(e.NAME,1,instr(e.NAME,'"')-1)),
DECODE(instr(e.NAME,'"'),0,NULL,substr(e.NAME,instr(e.NAME,'"')+1)),
e.STATUS, j.ERROR#, j.REQ_START_DATE, j.START_DATE, j.RUN_DURATION,
j.INSTANCE_ID, j.SESSION_ID, j.SLAVE_PID, j.CPU_USED,
decode(e.credential, NULL, NULL,
substr(e.credential, 1, instr(e.credential, '"')-1)),
decode(e.credential, NULL, NULL,
substr(e.credential, instr(e.credential, '"')+1,
length(e.credential) - instr(e.credential, '"'))),
decode(bitand(e.flags, 1), 0, NULL,
substr(e.destination, 1, instr(e.destination, '"')-1)),
decode(bitand(e.flags, 1), 0, e.destination,
substr(e.destination, instr(e.destination, '"')+1,
length(e.destination) - instr(e.destination, '"'))),
j.ADDITIONAL_INFO
FROM scheduler$_job_run_details j, scheduler$_event_log e
WHERE j.log_id = e.log_id
AND e.type# = 66 and e.dbid is null
AND ( e.owner = SYS_CONTEXT('USERENV','CURRENT_SCHEMA')
or /* user has object privileges */
( select jo.obj# from obj$ jo, user$ ju where
DECODE(instr(e.NAME,'"'),0, e.NAME,substr(e.NAME,1,instr(e.NAME,'"')-1))
= jo.name and e.owner = ju.name and jo.owner# = ju.user#
and jo.subname is null and jo.type# = 66
) in
( select oa.obj#
from sys.objauth$ oa
where grantee# in ( select kzsrorol from x$kzsro )
)
or /* user has system privileges */
(exists ( select null from v$enabledprivs
where priv_number = -265 /* CREATE ANY JOB */
)
and e.owner!='SYS')
)
);
--從這個視圖中可以發現,日志有存在SCHEDULER$_JOB_RUN_DETAILS和
--SCHEDULER$_EVENT_LOG兩張表中,所以要刪除日志,就需要處理這兩張表

######################刪除日志操作#################
--刪除SYS.SCHEDULER$_JOB_RUN_DETAILS中數據
DELETE FROM SYS.SCHEDULER$_JOB_RUN_DETAILS A
WHERE EXISTS (SELECT 1
FROM SYS.SCHEDULER$_EVENT_LOG B
WHERE B.NAME = 'XIFENFEI_JOB'
AND A.LOG_ID = B.LOG_ID);
--刪除SYS.SCHEDULER$_EVENT_LOG中數據
DELETE FROM SYS.SCHEDULER$_EVENT_LOG B
WHERE B.NAME = 'XIFENFEI_JOB';
--提交
COMMIT;
#####################################################
7.delete jobs
BEGIN
DBMS_SCHEDULER.DROP_JOB(job_name => 'xifenfei_job');
END;

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM