摘 要:介紹了Oracle
8 PL/SQL程序設(shè)計中,提高系統(tǒng)性能的編程風格的幾種方法,和存儲過程及觸發(fā)器的使用、錯誤處理等。
關(guān)鍵詞:Oracle;SQL;存儲過程;觸發(fā)器;錯誤處理
中圖分類號:TP311.11 文獻標識碼:B
文章編號:1001-9081(2000)02-0073-02
Oracle是C/S(Client/Server)結(jié)構(gòu)的大型數(shù)據(jù)庫,主要語言是4GLSQL語言,具有功能強大而簡單易學的優(yōu)點。C/S結(jié)構(gòu)的工作過程是:當客戶端(C端)輸入并發(fā)送一條SQL語句后,便通過網(wǎng)絡(luò)送到服務(wù)器端(S端),在那里被分析執(zhí)行然后再將結(jié)果通過網(wǎng)絡(luò)返回到客戶端,此時客戶端可以再發(fā)下一條SQL語句??梢?,客戶端是一條語句一條語句的發(fā)送,服務(wù)器端是一條一條的分析執(zhí)行,結(jié)果再一次次的返回。但是,這樣單個的SQL語句引起了頻繁的網(wǎng)絡(luò)通信,大大降低了系統(tǒng)性能。PL/SQL是擴展SQL后的語言,PL/SQL塊作為一個單位發(fā)送,使用了較少的網(wǎng)絡(luò)通信,而且在運行中能根據(jù)條件,決定執(zhí)行或重復(fù)執(zhí)行什么語句,既保留了SQL的強大性,又彌補了不足。
1 提高程序的運行速度
1.1 使用存儲過程
存儲過程是Oracle數(shù)據(jù)庫的一種對象,是一種帶名的PL/SQL過程程序塊,它在創(chuàng)建后,被數(shù)據(jù)庫服務(wù)器進行語法和句法分析,以編譯了的形式存儲在數(shù)據(jù)庫中,可以被有權(quán)用戶在任何需要的地方調(diào)用。當客戶端應(yīng)用程序調(diào)用時,只需發(fā)送一條調(diào)用命令,數(shù)據(jù)庫服務(wù)器就會執(zhí)行該過程。與一般的PL/SQL塊主要的不同是:無需在網(wǎng)上傳送大量的源程序代碼,只傳送一條調(diào)用命令,這就大大降低了網(wǎng)絡(luò)通信的負擔;而且只在剛創(chuàng)建時分析編譯一次,每次調(diào)用直接執(zhí)行編譯了的代碼,因此運行速度較快。
在實際開發(fā)時,對于具有共同特性的功能模塊最好使用存儲過程,調(diào)用時通過使用不同的實際參數(shù)值來實現(xiàn)某一具體的處理。如果能充分利用存儲過程來完成應(yīng)用系統(tǒng)的操作與處理,則可大大提高系統(tǒng)的運行性能。 1.2 編寫可重用共享池中已有語句的SQL語句
共享內(nèi)存緩沖區(qū)和后臺進程合稱為一個Oracle實例。當啟動一個Oracle實例時,會有許多的Oracle后臺進程被啟動,每個進程都負責運行數(shù)據(jù)庫的不同方面的處理,各進程通過共享內(nèi)存彼此之間進行通信,該塊內(nèi)存就是系統(tǒng)全局區(qū)SGA。SGA被分隔為不同的區(qū)域,其中一個稱作共享池(Shared
Pool)的區(qū)域中包含了發(fā)送給數(shù)據(jù)庫的SQL語句的正文和PL/SQL塊,以及它們經(jīng)過分析后的表示形式與執(zhí)行方案,其中執(zhí)行方案是數(shù)據(jù)庫實際處理該語句的方法,例如,需要訪問哪些表和索引、是否需要執(zhí)行排序操作等等。
因為要執(zhí)行一條SQL 語句,數(shù)據(jù)庫就必須確定其執(zhí)行方案。當數(shù)據(jù)庫從客戶應(yīng)用程序接收到一條SQL語句時,它首先檢查是否該語句在共享池中。若在,那么不重新對其分析而是重復(fù)使用已經(jīng)在共享池中的形式及執(zhí)行方案;若不在,則對該語句進行分析,得到新的分析形式與執(zhí)行方案并進行存儲,覆蓋共享池中以前的內(nèi)容。
由此可以看出,編寫可重用共享池中語句的SQL語句就顯得十分必要,因為避免不必要的重新分析,會很大程度上減小服務(wù)器所承擔的工作量。要想重復(fù)使用共享池中的語句,就應(yīng)該編寫與其格式一致的語句,包括字母的大小寫、標點符號、換行的位置等都要一致。下面推薦一種有效實用的方法。
1.2.1 SQL語句各部分的格式
一條語句可以一行也可以分多行書寫,但最好換行書寫,每一子句一行,且每行的第一個關(guān)鍵字與第一行的關(guān)鍵字的尾部對齊,這樣做以確保每次使用同一條語句時分行的位置一致,而不要讓語句在第80列偶然溢出到下一行,例如下面的格式中字母T、M、E、D、P是對齊的,一子句占了一行:
SELECT col1,col2
FROM table―name1
WHERE col1 > col2
AND col2 > col3
GROUP BY col1;
當剛執(zhí)行過上述語句后,若又接收到下面的語句:
SELECT col1,col2
FROM table―name2
WHERE col1 > col2
AND col2 > col3
GROUP BY col2;
則通過檢查認為與共享池中的語句一致,可重復(fù)使用共享池中的執(zhí)行方案,不必重新分析。
而下面的的語句被認為是不同的,因為分行的位置不同,需要重新進行分析。
SELECT col1,col2 FROM table―name2
WHERE col1 > col2
AND col2 > col3
GROUP BY col1 ;
1.2.2 字母大小寫采用一致約定
關(guān)鍵字、保留字大寫,用戶聲明的標識符小寫。請看下面的兩條語句:
SELECT xm
FROM student;
與
select xm
FROM student;
比較的結(jié)果是這兩句不匹配或者說不等價,因為第一句中的SELECT是大寫的,而第二句的是小寫的。
1.2.3 其它,如運算符兩側(cè)各留一個空格等
總之,設(shè)計自己的編寫約定并遵守這些約定,使要處理的語句與共享池中的相一致,有助于運行性能的提高。
2 提高可維護性
2.1 編寫觸發(fā)器
對表中數(shù)據(jù)進行修改、刪除或插入是非常常見的操作。當表被修改時,應(yīng)該自動給其他需要執(zhí)行操作的程序發(fā)信號。觸發(fā)器可以完成這一功能。在Oracle8中,觸發(fā)器是一段程序,但是這段程序是當發(fā)生INSERT、UPDATE或DELETE操作時被自動執(zhí)行的,與過程的調(diào)用(是通過調(diào)用語句調(diào)用執(zhí)行)不同,因此當某事件的發(fā)生引起連環(huán)更新或其他的相應(yīng)操作時,通過自動執(zhí)行觸發(fā)器代碼實現(xiàn)而不用人工干預(yù),大大減輕了維護工作,同時也很好的保證了數(shù)據(jù)的一致性。
觸發(fā)器的優(yōu)點是自動激發(fā),不管什么引起數(shù)據(jù)修改(來自程序的或是來自用戶的),它們都工作,所以常常用于不同數(shù)據(jù)表中的相關(guān)數(shù)據(jù)的串接修改。采用這種方法實現(xiàn)數(shù)據(jù)表間接的數(shù)據(jù)關(guān)聯(lián)可由數(shù)據(jù)庫集中維護控制,規(guī)則變化時只需修改相應(yīng)的觸發(fā)器即可,這樣系統(tǒng)易于維護,提高了工作效率。 2.2 使用%TYPE、%ROWTYPE方式聲明變量
程序設(shè)計中常常要通過變量來實現(xiàn)程序間的數(shù)據(jù)傳遞,即將表中數(shù)據(jù)賦值給變量,或是把變量值插入到表中。而要完成這些操作的前提就是,表中數(shù)據(jù)與變量類型要一致。然而在實際中,表中數(shù)據(jù)或類型、或?qū)挾扔袝r要變化,一旦變化,就必須去修改程序中的變量聲明部分,否則程序?qū)⒉荒苷_\行。為了減少這部分程序的修改,編程時使用%TYPE、%ROWTYPE方式聲明變量,使變量聲明的類型與表中的保持同步,隨表的變化而變化,這樣的程序在一定程度上具有更強的通用性。
3 提高程序自檢能力
一個好的應(yīng)用系統(tǒng)不僅要有好的用戶界面、齊全的功能處理模塊,而且要有很強的錯誤處理能力。因此要求編程人員要預(yù)測可能的各種情況(聲明異常情態(tài)并引發(fā)),并盡可能從錯誤中恢復(fù)過來(編寫相應(yīng)異常情態(tài)處理器代碼),這就是Oracle8中的異常部分的程序設(shè)計內(nèi)容。然而這部分的設(shè)計絕非易事。在異常部分的最后設(shè)置OTHERS異常情態(tài)處理器是個很好的編程習慣,因為它為運行時刻捕捉到的其它錯誤指明了處理去向,從而保證了程序的正常運行。格式如下:
BEGIN
…
EXCEPTION
WHEN excep―name1 THEN
…
WHEN excep―name2 THEN
…
WHEN OTHERS THEN
…
END;
但是對程序中出現(xiàn)的錯誤要做到正確的處理(即正確選擇異常處理器并執(zhí)行它),還必須弄清楚異常情態(tài)的傳播問題。
異常情態(tài)的傳播指的是當在程序塊的聲明、執(zhí)行、異常部分分別出現(xiàn)異常情態(tài)時,或在本塊中沒有相應(yīng)的異常處理器時會將這個異常情態(tài)傳播到哪里,會去激發(fā)那個塊中的處理器。傳播規(guī)則是這樣的:
當一個異常情態(tài)是在塊的執(zhí)行部分引發(fā)的(最常見的),PL/SQL使用下面的規(guī)則確定激活哪個異常處理器。(1)若當前塊對該異常情態(tài)設(shè)置了處理器,則執(zhí)行它并成功完成該塊的執(zhí)行,然后控制轉(zhuǎn)給包含塊。(2)若當前塊沒有該處理器,則通過在包含塊中引發(fā)它來傳播異常情態(tài)。然后對包含塊執(zhí)行步驟1。另外,無論是在聲明部分引發(fā)了一個異常情態(tài),還是在異常處理部分引發(fā),則該異常情態(tài)將立即傳播給包含塊。在包含塊引用上述規(guī)則進行異常情態(tài)的處理,即使在當前塊設(shè)置了OTHERS處理器也不會被執(zhí)行。
4 易于閱讀
.對于子程序、觸發(fā)器、包等帶名的程序塊,使用結(jié)束標識。例如:
CREATE OR REPLACE PROCEDURE addstud IS
…
BEGIN
…
END addstud;
.采用統(tǒng)一的標識符命名規(guī)則。對于諸如變量名、子程序名、觸發(fā)器名等數(shù)據(jù)庫對象命名時,應(yīng)盡量能表示其功能用途或含義。
.對于過程性語句與程序塊采用縮進書寫風格,會使得程序結(jié)構(gòu)清晰、層次分明、易閱讀。
.采用統(tǒng)一的字母大小寫。盡管PL/SQL程序中不區(qū)分大小寫,但是采用統(tǒng)一的字母大小寫(如前文敘述的大小寫約定)將在很大程度上提高程序的可閱讀性。
.加注釋。
.一條語句分多行書寫,不讓其自動分行。
這方面的內(nèi)容大家都已很熟悉,不再詳述了。
總之,良好的程序設(shè)計風格,可以在多個方面提高系統(tǒng)的性能,提高開發(fā)效率,很值得我們在工作中給以重視。
作者簡介:楊延廣 (1965-),男,講師,主要研究方向:計算機應(yīng)用;
曹素麗 女,工程師,主要研究方向:計算機應(yīng)用。
作者單位:楊延廣(石家莊郵政高等??茖W?!『颖?strong>.石家莊050011)
曹素麗(石家莊郵政高等??茖W?!『颖?strong>.石家莊050011)
|