Oracle Job 使用心得體會

lnwxzyp發表於2009-03-13

        有一個地市的oracle主機非常奇怪,客戶端連線後經常莫名其妙的斷網,而且在command 並不會提示錯誤,具體的表現是command視窗裡面一直顯示在執行,但很可能該過程在資料庫當中都已經停止執行,實際上執行時間稍微長一些的儲存過程往往都要對執行的結果進行檢查,對於沒有執行的部分 還需要重新執行,非常麻煩,但是一時又找不到發生這種情況的原因,於是想到用oracle的job來執行。 
declare n number;
 begin
dbms_job.submit(:n,'proc_name;',trunc(sysdate)+1/24,'trunc(sysdate)+1+1/24');
end;
執行之後 報錯:ORA-01008:並非所有變數都關聯
取掉變數:n前面的冒號,再次執行,
declare n number;
 begin
dbms_job.submit(n,'proc_name;',trunc(sysdate)+1+1/24,'trunc(sysdate)+1+1/24');
end;
成功。

另外在cmd當中執行
variable n number;
 begin
dbms_job.submit(:n,'proc_name;',trunc(sysdate)+1/24,'trunc(sysdate)+1+1/24');
end;
也是一樣的 而且還能直接顯示job number。 需要仔細看兩段語句的不同 declare和variable 以及n 和:n

這裡n是job number,
'proc_name;'是需要執行的儲存過程名稱,
trunc(sysdate)+1+1/24 首次執行時間
'trunc(sysdate)+1+1/24') 是下一次執行時間
由於執行之後不能馬上看出效果,於是對日期進行修改,
declare n number;
 begin
dbms_job.submit(n,'proc_name;',to_date('2009-3-11 14:00:00‘,'yyyy-mm-dd hh24:mi:ss'),'trunc(sysdate)+1+1/24');
end;
執行之後 檢視執行記錄 select * from user_jobs 發現並沒有 執行。
google之後發現需要檢視job的引數job_queue_processes 是否為0
SQL>show parameter job
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
job_queue_processes                  integer     0
SQL>
由於value=0 表示job不會自動執行,因此需要改為不為0的值,其他值的含義比如5 就表示並行度,可以同時執行5個job,其餘job等待執行完成後再接著執行,但是這裡有出現了一個問題,假如有4個job正在執行,這個時候又有兩個job的執行時間到了,那麼這個時候這兩個job就只會執行其中一個,而另外一個則會等待。
因此告訴地市相關人員 他們的job_queue_processes需要設定 可能需要重啟,由於是報表資料庫,因此只能選擇在晚上下班之後進行操作。
由於以前有過亂改引數造成資料庫無法啟動的錯誤,因此首先在自己的機器上進行測試,由於自己的主機是10g,而地市的主機是9i,因此不敢盲目的將10g的修改方法套用在9i上面,於是在itpub論壇發帖求助,可能是由於發錯了版面,沒有人回覆帖子,最後還是google確認了9i的修改方法 那就是
在管理員許可權下執行
SQL>alter  system  set  job_queue_processes=10  scope=spfile; 
在這裡scope 有三個可選值 MEMORY ,SPFILE , BOTH 意思分別是:
MEMORY:只改變當前例項執行
SPFILE:只改變SPFILE的檔案
BOTH:改變spfile和當前的例項
然後找空閒的時間重啟就可以了,在重啟了機器之後,我以為之前建的job就不會啟用,由於job啟用的儲存過程都有日誌記錄,不料在檢視日誌的時候發現 有重複執行的情況,原來我又重新建立了job,而之前建立的job在資料庫重啟之後 沒有在user_jobs裡面發現,但是oracle還是執行了,正如我們剛才討論的並行度的問題一樣,job是等待執行,即便過了計劃執行時間,還是會執行的。 在這裡可能也有人有疑問 為什麼job會不存在了呢? 因為我建的是執行一次的job,原因前面也說過了 是因為客戶端執行斷網的緣故才啟用job。
在這裡要說明的是 執行一次的job在執行完畢之後 在user_jobs裡面就找不到相關的記錄了。
那也有人要問執行一次應該怎麼寫語句?聰明的你一定想到了 那就是把下一次執行那地方空起來。
declare n number;
 begin
dbms_job.submit(n,'proc_name;',to_date('2009-3-11 14:00:00‘,'yyyy-mm-dd hh24:mi:ss'),'');
end;
這樣就只會執行一次了 啟用了job之後 地市的問題暫時得到了解決,但是這並不是根治的方法 那個奇怪的斷網錯誤還是需要解決才行啊。

另外如果想讓一個job立刻執行的話,比如當前日期是2009-3-13 15:39:00
那麼只需要將日期指定比它還早的任何一個時間 比如2009-3-13 15:38:00
job就會在建立後呼叫儲存過程。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12216142/viewspace-567157/,如需轉載,請註明出處,否則將追究法律責任。

相關文章