?

ORACLE 異常處理剖析

2018-06-02 08:50林秀麗鄒貴紅盧道設
電腦知識與技術 2018年10期

林秀麗 鄒貴紅 盧道設

摘要:編程領域無論是高手還是新手,程序編寫過程中或業務邏輯處理中,遇到難以周全考慮的錯誤是很正常的,所以任何一個優秀程序都應該帶有對異常的捕獲、提示、處理并恢復的功能。目的提高程序的健壯性。該文以ORACLE數據庫為例,對異常處理進行剖析。

關鍵詞:ORACLE數據庫;程序健壯性;異常處理

中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2018)10-0003-03

Abstract: Either the master or novice programming, During the preparation process or business logic processing, It is difficult to take into account the error is normal, So any good programs should be with and on the recovery of abnormal, suggesting that capture, processing function,Objective to improve the robustness of the program。In this paper, the ORACLE database as an example, Analysis of exception handling.

Key words: ORACLE database; the robustness of the program; exception handling

程序編寫中,錯誤總會遇到不少,錯誤一般分為兩種,一種是輸入錯誤,另一種是邏輯性錯誤[1]。ORACLE將錯誤進行了歸納,即:編譯時刻錯誤;運行時刻錯誤(也稱異常錯誤)。

1 異常處理分類

1.1 編譯時刻錯誤

編譯錯誤是因用戶錯誤的拼寫關鍵字、對象名以及錯誤的語法格式等造成,此類錯誤在編譯時PL/SQL引擎會發并報告給用戶,此時程序是處在運行前。

例1:查詢中數據表名輸入錯,編譯時,PL/SQL引擎立馬發現錯誤并提示。

1.2 運行時刻錯誤(異常錯誤)

編譯即便通過,錯誤在運行時刻還是有可能產生。運行時刻錯誤產生的原因有很多,例如:硬件故障、內存不足、表的完整性約束被違反、被零除、數據在大小長度上的不匹配等[2][3]。

編譯時刻錯誤在程序內部沒必要做特殊處理。對運行時刻錯誤,因運行環境的不確定性此錯誤可能會隨時出現。程序員必須在寫程序過程中,對潛在的異常錯誤要盡可能的考慮并做針對性的處理,目的提高程序的健壯性。

PL/SQL對運行時刻錯誤提供了自動捕獲與處理機制。

例2:被零除錯誤產生的異常,在PL/SQL引擎編譯可以通過,只在運行時刻錯誤才呈現。

2 異常錯誤處理

對程序中出現的異常錯誤要進行處理,異常處理結構是固定的,如下:

異常定義區對預定義異常是不需要進行定義的;異常執行是可以顯式引發異常,也可以由PL/SQL引擎引發異常;若引發了異常,則引發異常的后續語句將停止執行,語句轉向異常處理區,直到異常處理完成,再回來。

異常分為預定義異常(系統預定義異常,非預定義異常)以及用戶定義異常。這兩種異常有不同的定義和引發方式,但對處理異常錯誤的程序編寫方法與執行過程是一樣的。

無論是哪一類異常,ORACLE在引發異常時都有一個序號,但程序進行異常處理時,不直接使用異常序號,異常的引用與處理必須使用名字。

2.1 預定義異常

預定義異常分為兩類:第一類是系統預定義異常,此類異常是系統定義的,提供了異常序號與異常名稱,二十來個,可直接使用,但在異常的捕獲與處理上太有限。第二類是非預定異常,此類異常系統只提供了異常產生時的序號,并沒有提供異常名,在程序中要捕獲這類異常,用戶就必須自己聲明異常的名稱,用EXCEPTION_INT編譯命令建立異常序號同異常名稱的聯系,當程序發生異常時,就會自動以該名稱引發對應序號的異常錯誤。

例3:系統預定義異常??捎枚鄺l件選擇,在CASE語句的WHEN條件部分,引發系統預定義的CASE_NOT_FOUNT異常錯誤,異常處理部分可直接使用異常錯誤名稱對異常錯誤進行捕獲。

例4:非預定義異常。在插入語句中出現插入異常錯誤,系統提供了異常錯誤序號(ORA-01400),但系統并沒有給此序號以對應的名稱,用戶就必須自己聲明名稱(ept_null_error),然后同異常錯誤序號ORA-01400對應,這樣程序就可以按異常名稱ept_null_error捕獲處理異常。

預定義異常還可以通過SQLCODE和SQLERRM內置函數來處理,但此兩函數在SQL語句中均不能直接使用,需要先將它們賦值給變量后,才能在SQL語句中使用。

SQLCODE函數不帶參數,返回的是ORACLE錯誤序號。SQLERRM函數參數可寫可不寫,若寫參數則為錯誤序號,此函數帶參數時返回其錯誤序號對應的錯誤消息文本,若省去參數此函數返回SQLCODE當前值對應的錯誤消息文本。

例5:SQLCODE返回的錯誤序號為-2292,SQLERRM返回的是錯誤序號-2292的錯誤消息文本“ORA-02292: 違反完整約束條件 (HR.COUNTR_REG_FK) - 已找到子記錄”。

2.2 自定義異常

ORACLE能判斷的異常錯誤且能提供異常錯誤序號的只有預定義異常,但在實際使用中遠遠不能滿足異常處理的要求。程序員必須自定義一些異常,來滿足具體業務規則以及程序的編程與調試需求。自定義異常往往不一定是什么錯誤,而是讓程序的結構完美。如:利用異常處理部分對某些問題進行集中處理。

必須先聲明自定義異常,且異常引發要用RAISE語句顯示拋出,自定義異常沒有異常序號。

對于自定義異常也可以使用RAISE_APPLICATION_ERROR過程來實現,此函數對異常的錯誤序號與異常的錯誤消息文本都可自定義,使用靈活方便。此過程很多時候是為應用程序編程風格提供方便,不一定非要用于異常錯誤的處理。

例6:建一個使用了RAISE_APPLICATION_ERROR的過程dept_mgr,此過程是判斷一個部門是否有管理員的情況自定義異常錯誤代碼“-20001”,“-20002”與對應消息文本“該部門編碼超出了取值范圍”,“該部門沒有管理員”。僅接著調用dept_mgr過程,按部門編碼與該部門有沒有管理員來捕獲異常錯誤。

3 異常傳遞

當異常被引發時,就會立馬跳轉到EXCEPTION的異常處理語句中查詢是否有匹配的異常,若在當前語句塊或者子語句塊中都沒有匹配的異常,那么此異常就會向當前語句塊的外層或子語句塊的調用方傳遞,直到搜索塊終止還沒有匹配的異常,此時就會向PL/SQL引擎拋出一個未處理的異常。

以下詳細剖析異常的傳遞機制[4][5]。

3.1 異常傳遞引發于執行部分

在當前塊的執行部分引發異常的處理機制:若在當前塊中有匹配的異常處理,則執行該異常處理,然后將控制權傳到外層語句塊;若在當前塊中沒有匹配的異常處理,則異常會被傳到外層的異常處理部分查詢匹配的異常處理;若異常一直被傳遞直到最外層語句塊,都沒查詢到匹配的異常處理,則該程序將異常結束,且在被調用環境中顯示錯誤信息。

如圖2,異常1在當前塊中有匹配的異常處理;異常2被傳遞到外層塊中有匹配的異常處理對應;異常3是沒有查詢到匹配的異常處理的。

3.2 異常傳遞引發于聲明部分

異常傳遞引發于聲明部分,如變量在初始化是產生異常錯誤,此時異常會立馬向外層塊傳遞,而不被當前塊的異常處理部分捕獲。

如圖3,A 變量定義長度為3,可賦值長度超過了3,結果引發異常錯誤,此異常錯誤是向外層塊傳遞的。

3.3 異常傳遞引發于異常內部

異常傳遞引發于異常內部,是指異常在處理中也有引發異常的可能。異常內部引發異常,是會立馬被傳遞到外層語句塊,不論本塊是否能進行異常處理。異常內部引發異常,可有RAISE顯式引發,或者因某種錯誤由ORACLE檢測到進行隱式引發。

如圖4,異常2引發于異常1內部,結果被傳遞到外層塊處理。

4 結論

本文對PL/SQL中的異常進行了剖析,從程序的健壯性闡述了異常的分類,對異常的處理機制分為兩種,一種是預定義異常,一種是自定義異常,當預定義異常不能滿足程序需要時,自定義異??梢耘缮嫌脠?。同時詳細介紹了異常的不同傳遞。以便初學者深入理解異常處理機制,開發人員靈活使用異常機制解決問題。

參考文獻:

[1] 李興華,馬云濤. Oracle開發經典[M].北京:清華大學出版社,2012(16):436-448.

[2] 龔永罡. Oracle 11g管理與應用實踐教程[M].北京:清華大學出版社,2014(7).

[3] 路川,胡欣杰. Oracle 11g寶典[M].北京:電子工業出版社,2009(4):198-207.

[4] 谷長勇,吳逸云,單永紅,陳杰. Oracle 11g權威指南[M]. 2版.北京:電子工業出版社,2011(18).

[5] 明昌科技. Oracle從入門到精通[M].北京:清華大學出版社,2012(14).

91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合