一.技術基礎
由于本文是使用pl/sql作為開發平臺來提供解決方案,所以首先了解相關的背景知識。
pl/sql本身只是作為sql語句的一個補充,通過引入過程化的概念來增強數據庫處理能力。然而,相對于c,c++,java等過程化語言來說,pl/sql的處理功能依然不夠強大。為此,oracle數據庫提供了大量的應用程序開發包,來增強應用程序開發能力。根據本文的主題,介紹如下兩個開發包:dbms_flashback和dbms_job。
1. dbms_flashback包主要是用來進行倒敘查詢使用的,即通過設置查詢時間來確定該時刻下的查詢結果。一般情況下,我們平時使用的查詢是查詢當前時間(sysdate)下的數據。使用dbms_flashback包就可以查詢以前數據的狀態,這一功能對于誤處理的情形而言就顯得極為重要。下面是該包中的兩個主要函數介紹:
·enable與disable:分別是啟動和關閉倒敘查詢功能。應該注意的是,每次啟動倒敘查詢之前應首先關閉倒敘模式。
·enable_at_time:設置查詢的時間點,它是以當前時間為起點進行設置的。
2. dbms_job包是用來對pl/sql塊進行調度的實用包,它允許pl/sql塊在指定的時間內自動運行,類似于vc中的settimer這樣的定時器。為便于該包的運行,需要首先設置兩個init.ora參數:
·job_queue_process指定啟動的后臺處理數。如果它是0或沒有被設置,將沒有后臺處理進入作業,它們也就不會運行。
·job_queue_interval以秒為單位,指定每一個過程在檢查新的作業前等待的時間。在job_queue_interva所指定的時間內,一個作業最多只能運行一次。
設置好這兩個參數后,就可對程序進行調度了,該包主要使用submit函數進行調度,該函數的原型為:
submit(返回的作業號,程序過程名,sysdate,下次運行的時間);
二.數據恢復
數據恢復是數據庫本身一個極其重要的功能,通常重要的數據可以通過其系統的數據備份功能來實現,所以在實際的開發中,重要的數據往往容易恢復,反而是一些平常的數據因為誤操作而引起一些麻煩。
對于有經驗的開發人員來說,往往會對那些開發需要的基表(基表就是提供數據源的數據表)做一些備份。這樣,即使以后出現一些數據誤操作也不會導致重大的事故。
更為實用而又很少為開發人員所使用的方法就是采用倒敘查詢,鑒于前面已經有了一定的技術鋪墊,現在就可以使用dbms_flashback包來對數據進行恢復了。為方便講述,假定一個基表emp_table,其表記錄如下: emp_no emp_name emp_salary 001 jacky 5000 002 rose 6000 003 john 7000
即此表僅有3條記錄,那么由于對數據庫的誤操作,導致第一條記錄被刪除,那么執行下面的sql語句:select * from emp_table;
其執行結果為:emp_no emp_name emp_salary
002 rose 6000
003 john 7000
由于已經執行了提交操作(commit),所以無法進行回滾(rollback),這樣原來的數據就無法用正常方法進行恢復。不過,由于誤操作的時候在不久以前(假設是5分鐘之前),在這種情況下,可以使用dbms_flashback包來恢復數據,可以在sql*plus里鍵入如下代碼:
execute dbms_flashback.enable_at_time(sysdate-5/1440);
此時,將數據庫調整到5分鐘之前的狀態,如果再執行查詢表的命令就會為如下結果:emp_no emp_name emp_salary
001 jacky 5000
002 rose 6000
003 john 7000
那么就可以在此時將其數據備份到emp_table_bk,即:create table emp_table_bk
as
select * from emp_table;
這樣,就把以前誤操作的數據給恢復回來了。
從上面的結果看的出,調用dbms_flashback包的enable_at_time函數,可以將數據庫的當前查詢時間調整到以前,這樣給數據恢復提供了幫助。
在使用dbms_flashback包的時候還應該注意以下幾點:
·倒敘查詢是有前提的,即該數據庫必須具有撤消管理功能。具體做法是,dba應該建立一個撤消表空間,并啟動自動撤消管理,并建立一個撤消保留時間窗。這樣,oracle將在撤消表空間中維護足夠的撤消信息以便在保留時間內支持倒敘查詢。
·由于撤消表空間的大小直接決定了倒敘查詢執行的成敗。即撤消表空間越大,那么可以查詢的時間可以越早,那么對于一般的撤消表空間的大小,為了保證倒敘查詢的成功,盡量查詢5天以內的數據,這樣成功的可能性更高一些。
三.任務調度
在unix系統中,任務與進程的概念是等同的,即當系統執行一段程序代碼時會自動給其分配一個進程號和任務號,這樣使用進程號和任務號就可以對該任務進行操作(如掛起,停止,啟動等)。而oracle數據庫內部也存在任務調度,比如,需要對某一操作進行周期性的執行,或者是在某事件發生的時候才執行。一般性的做法是使用觸發器,即將所有操作封裝在觸發器里,然后通過指定觸發事件即可將該操作等待執行。另外,還可以直接利用操作系統來實現,比如在windows平臺就可以編寫windows腳本并結合"任務計劃"來實施;如果在unix平臺,就可以寫shell來實現任務的周期性的執行操作。
而這里主要是采用oracle數據庫的dbms_job包來實現的。
例如,由于每個月都需要對員工進行考評以進行薪水的調整,那么就需要對emp_table表進行更新處理。更新處理代碼如下:create or replace procedure salary_upt(v_emp_no varchar2,v_salary number)
as
begin
update emp_table
set emp_salary=v_salary
where emp_no=v_emp_no;
commit;
end ;
/
為了定期每個月都運行上面的程序,可以執行如下代碼:variable v_jobnum number;
begin
dbms_job.submit(:v_jobnum,'salary_upt',sysdate,'sysdate+30');
commit;
end;
/
submit執行后將使得salary_upt過程馬上執行。在上面的代碼中,v_jobnum是該作業返回的作業號(任務號),后面兩個時間分別為開始時間和結束時間,所以salary_upt過程將每隔30天執行一次salary_upt程序,以此達到了定期更新的目的。
如果要禁止該作業的繼續執行,可以執行下面的命令:dbms_job.remove(:v_jobnum);
使用dbms_job包來實現任務的調度便于跟應用程序集成,有時候這樣處理更為的便捷。
四.小結
很多時候,數據庫的功能可以通過應用程序來進行擴展,對于進行后臺數據庫開發操作的用戶而言,除了對數據庫整體架構熟悉以外,掌握一定的應用程序開發能力是很有必要的。系統通過本文能夠給讀者一定的啟發。
本文的開發環境為:
服務器端:unix+oracle9.2
客戶端:windows2000 pro+toad(或者sql*plus)
本文中的代碼
新聞熱點
疑難解答