1. 程式人生 > >oracle job:初學通過一個小例子,說說job

oracle job:初學通過一個小例子,說說job

--先看例子:每分鐘向一個表中插入一條資料,所有操作都是在pl/sql環境中,下面提到的異常也都針對pl/sql

例項:

create or replace procedure stopApplyBatch_procedure as
begin
update BIZ_PROJECT_APPLY_BATCH set state='已停止' where state='申報中' and enddate<=(select trunc(sysdate)-1 from dual);
commit;
end;

declare stopApplyBatch_job number;
begin
       dbms_job.submit(stopApplyBatch_job,'stopApplyBatch_procedure;',to_date('2012-9-6 00:00:00','yyyy-mm-dd hh24:mi:ss'),'trunc(sysdate)+1');
end;

--建立一個儲存過程,向test_table表中插入資料
create or replace procedure test_procedure as
begin
insert into test_table values(sysdate);
end;

--insert語句替換下面兩條語句,實現定時更新指定資料、刪除指定資料的操作

--更改結束時間小於當前系統時間&狀態為‘申報中’的記錄狀態為‘已停止’

--update test_table set state='已停止' where state='申報中' and enddate<=(select trunc(sysdate)-1 from dual);

--定時刪除小於當前系統時間的記錄

--delete from test_table where servertime < TO_DATE(sysdate,'YYYY-MM-DD')

--建立一個job,定時定頻率執行上面定義的儲存過程
--注意問題:
--1、在pl/sql中,用variable宣告job號名稱,會丟擲‘無效的sql語句’異常,採用declare關鍵字
--2、當採用這樣的方式:job =>:test_job,注意那個冒號,可能會丟擲‘並非所有變數都已繫結’異常,解決的方式:去掉那個冒號
declare test_job number;
begin
        dbms_job.submit(
                 job =>test_job,
                 what=>'test_procedure;',
                 next_date => sysdate,
                 interval => 'sysdate+1/1440',
                 no_parse => true);
end;

--或者
declare test_job number;
begin
        dbms_job.submit(test_job,'test_procedure;',sysdate,'sysdate+1/1440',true);
end;

--執行job,(此處有個誤區,並不是非要執行job,job才執行,執行到上面宣告和建立步,job就已經運行了,所以下面的可以不用管了,為什麼我也不知道)
--方式一:當你想採用下面這樣的方式的時候,可能同樣會丟擲‘並非所有變數都已繫結’的異常
begin
       dbms_job.run(:test_job);
end;
--方式二:你應該會去掉那個冒號,但是這樣的方式可能會丟擲‘test_job未被宣告’
begin
       dbms_job.run(test_job);
end;
--那怎麼辦呢,採用方式三吧
--首先查詢到你建立的job號,然後通過job號執行run
select * from user_jobs
begin
       dbms_job.run(1);
end;

--刪除job,同樣遵循run執行job的方式
begin
       dbms_job.remove(1);
end;

接下來詳細看看job的語法(一下內容收集與網上資料,有些未親測):

初始化相關引數job_queue_processes
alter system set job_queue_processes=50;//最大值不能超過1000 ;表示oracle能夠併發的job的數量

當job_queue_process值為0時表示全部停止oracle的job,可以通過語句ALTER SYSTEM SET job_queue_processes = 10;來調整啟動oracle的job。

job_queue_interval = 10; //排程作業重新整理頻率秒為單位

檢視job queue 後臺程序:select name,description from v$bgprocess;

job的相關檢視(相當於存在的系統表,儲存建立的每個job資訊):
dba_jobs
all_jobs
user_jobs
dba_jobs_running 包含正在執行job相關資訊

通過檢視相關檢視,檢視job號:select * from user_jobs;  select job  from all_jobs;

我通過建立的job,說一下job資訊

declare test_job number;
begin
        dbms_job.submit(
                 job =>test_job,
                 what=>'test_procedure;',
                 next_date => sysdate,
                 interval => 'sysdate+1/1440',
                 no_parse => true);
end;

一、dbms_job package 用法介紹

        Broken()過程。
  change()過程。
  Interval()過程。
  Isubmit()過程。
  Next_Date()過程。
  Remove()過程。
  Run()過程。
  Submit()過程。
  User_Export()過程。
  What()過程。

1、Broken()過程更新一個已提交的工作的狀態,典型地是用來把一個已破(已停止)工作標記為未破(執行)工作。
  這個過程有三個引數:job 、broken與next_date。
  
  PROCEDURE Broken (job    IN binary_integer,
           Broken  IN boolean,
           next_date IN date :=SYSDATE)
  
  job引數是工作號,它在問題中唯一標識工作。
  broken引數指示此工作是否將標記為破——TRUE說明此工作將標記為破(停止),而FLASE說明此工作將標記為未破(執行)。
  next_date引數指示在什麼時候此工作(此broken過程)將再次執行。此引數預設值為當前日期和時間。
  job如果由於某種原因未能成功之行,oracle將重試16次後,還未能成功執行,將被標記為broken,重新啟動狀態為broken的job,有如下兩種方式;
  a、利用dbms_job.run()立即執行該job
    sql>begin
    sql>dbms_job.run(:jobno) 該jobno為submit過程提交時返回的job number
    sql>end;
    sql>/
  b、利用dbms_job.broken()重新將broken標記為false
    sql>begin
    sql>dbms_job.broken (:job,false,next_date)
    sql>end;
    sql>/
  2、Change()過程用來改變指定工作的設定。
  這個過程有四個引數:job、what 、next_date與interval。
  
  PROCEDURE Change (job    IN binary_integer,
           What    IN varchar2,
           next_date IN date,
           interval  IN varchar2)
  
  此job引數是一個整數值,它唯一標識此工作。
  What引數是由此工作執行的一塊PL/SQL程式碼塊。
  next_date引數指示何時此工作將被執行。
  interval引數指示一個工作重執行的頻度。
  
  3、Interval()過程用來顯式地設定重執行一個工作之間的時間間隔數。這個過程有兩個引數:job與interval。
  
  PROCEDURE Interval (job   IN binary_integer,
            Interval IN varchar2)
  
  job引數標識一個特定的工作。

        interval引數指示一個工作重執行的頻度。
  
  4、ISubmit()過程用來用特定的工作號提交一個工作。這個過程有五個引數: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)
  
  這個過程與Submit()過程的唯一區別在於此job引數作為IN型引數傳遞且包括一個由開發者提供的工作號。如果提供的工作號已被使用,將產生一個錯誤。
  
  5、Next_Date()過程用來顯式地設定一個工作的執行時間。這個過程接收兩個引數:job與next_date。
  
  PROCEDURE Next_Date(job     IN binary_ineger,
            next_date  IN date)
  job標識一個已存在的工作。

       next_date引數指示了此工作應被執行的日期與時間。
  
  6、Remove()過程來刪除一個已計劃執行的工作。這個過程接收一個引數:
  
  PROCEDURE Remove(job IN binary_ineger);
  
  job引數唯一地標識一個工作。這個引數的值是由為此工作呼叫Submit()過程返回的job引數的值。已正在執行的工作不能由呼叫過程式刪除。
  
  7、Run()過程用來立即執行一個指定的工作。這個過程只接收一個引數:
  
  PROCEDURE Run(job IN binary_ineger)
  
  job引數標識將被立即執行的工作。
  
  8、使用Submit()過程,工作被正常地計劃好。
  這個過程有五個引數: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引數是由Submit()過程返回的binary_ineger。這個值用來唯一標識一個工作。
  what引數是將被執行的PL/SQL程式碼塊。
  next_date引數指識何時將執行這個工作。
  interval引數何時這個工作將被重執行。
  no_parse引數指示此工作在提交時或執行時是否應進行語法分析——TRUE指示此PL/SQL程式碼在它第一次執行時應進行語法分析,而FALSE指示本PL/SQL程式碼應立即進行語法分析。
  
  9、User_Export()過程返回一個命令,此命令用來安排一個存在的工作以便此工作能重新提交。
  此程式有兩個引數:job與my_call。
  
  PROCEDURE User_Export(job    IN binary_ineger,
             my_call  IN OUT varchar2)
  
  job引數標識一個安排了的工作。my_call引數包含在它的當前狀態重新提交此工作所需要的正文。
  
  10、What()過程應許在工作執行時重新設定此正在執行的命令。這個過程接收兩個引數:job與what。
  
  PROCEDURE What (job IN binary_ineger,
          What IN OUT varchar2)

       job引數標識一個存在的工作。

       what引數指示將被執行的新的PL/SQL程式碼。

二、欄位(列) 型別 描述
JOB NUMBER 任務的唯一標示號
LOG_USER VARCHAR2(30) 提交任務的使用者
PRIV_USER VARCHAR2(30) 賦予任務許可權的使用者
SCHEMA_USER VARCHAR2(30) 對任務作語法分析的使用者模式
LAST_DATE DATE 最後一次成功執行任務的時間
LAST_SEC VARCHAR2(8) 如HH24:MM:SS格式的last_date日期的小時,分鐘和秒
THIS_DATE DATE 正在執行任務的開始時間,如果沒有執行任務則為null
THIS_SEC VARCHAR2(8) 如HH24:MM:SS格式的this_date日期的小時,分鐘和秒
NEXT_DATE DATE 下一次定時執行任務的時間
NEXT_SEC VARCHAR2(8) 如HH24:MM:SS格式的next_date日期的小時,分鐘和秒
TOTAL_TIME NUMBER 該任務執行所需要的總時間,單位為秒
BROKEN VARCHAR2(1) 標誌引數,Y標示任務中斷,以後不會執行
INTERVAL VARCHAR2(200) 用於計算下一執行時間的表示式
FAILURES NUMBER 任務執行連續沒有成功的次數
WHAT VARCHAR2(2000) 執行任務的PL/SQL塊
CURRENT_SESSION_LABEL RAW MLSLABEL 該任務的信任Oracle會話符
CLEARANCE_HI RAW MLSLABEL 該任務可信任的Oracle最大間隙
CLEARANCE_LO RAW MLSLABEL 該任務可信任的Oracle最小間隙
NLS_ENV VARCHAR2(2000) 任務執行的NLS會話設定
MISC_ENV RAW(32) 任務執行的其他一些會話引數

三、描述 INTERVAL引數值,定義job的執行頻率(有些有待驗證)
每天午夜12點 'TRUNC(SYSDATE + 1)'
每天早上8點30分 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)'
每星期二中午12點 'NEXT_DAY(TRUNC(SYSDATE ), ''TUESDAY'' ) + 12/24'
每個月第一天的午夜12點 'TRUNC(LAST_DAY(SYSDATE ) + 1)'
每個季度最後一天的晚上11點 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3 ), 'Q' ) -1/24'
每星期六和日早上6點10分 'TRUNC(LEAST(NEXT_DAY(SYSDATE, ''SATURDAY"), NEXT_DAY(SYSDATE, "SUNDAY"))) + (6×60+10)/(24×60)'

每分鐘執行 'TRUNC(sysdate,'mi') + 1/ (24*60)'或 'sysdate+1/1440'

每天的凌晨1點執行'TRUNC(sysdate) + 1 +1/ (24)'

每週定時執行:每週一凌晨1點執行'TRUNC(next_day(sysdate,'星期一'))+1/24'

每月定時執行:每月1日凌晨1點執行'TRUNC(LAST_DAY(SYSDATE))+1+1/24'

每季度定時執行:每季度的第一天凌晨1點執行'TRUNC(ADD_MONTHS(SYSDATE,3),'Q') + 1/24'

每半年定時執行:每年7月1日和1月1日凌晨1點'ADD_MONTHS(trunc(sysdate,'yyyy'),6)+1/24'

每年定時執行:每年1月1日凌晨1點執行'ADD_MONTHS(trunc(sysdate,'yyyy'),12)+1/24'

四、隨後說一下,job中trunc的用法以及時間分數的含義

job中trunc 函式去掉日期裡的時間,也就是得到的是某天的00:00,

例如:select trunc(to_date('2012-9-6 11:18:49','yyyy-mm-dd hh24:mi:ss')) from dual

結果為:2012-9-6 00:00:00

分數:因為時間是以天為單位的,所以要得到某某點某某分,就需要下面這樣的形式:

1/1=1   一天

1/24    一小時;
1/1440    一分;
1/3600   一秒;