文章目錄
- 1.1 IF語句
- 1.2 CASE語句和CASE運算式
- 3) CASE運算式
- 2.1 基本迴圈
- 2.2 WHILE迴圈
- 2.3 FOR迴圈
- 2.4嵌套迴圈和標號
- 3.1 GOTO語句
- 3.2 NULL語句
- 4.1 定義異常
- 4.2 拋出異常
- 4.3處理異常
1.條件控制1.1 IF語句
if語句由於根據條件,執行兩個代碼塊之一。其文法形式如下:
IF 條件1 THEN 。。。 ELSEIF 條件2 THEN 。。。 ELSE 。。。 END IF;
這裡,elseif和else塊時可選的。當使用條件分支語句時,不僅可以使用if語句進行簡單條件判斷,而且還可以使用if語句進行二重分支和多重分支判斷。
1.2 CASE語句和CASE運算式
使用CASE語句處理多重條件分支有兩種方法:使用單一選擇符進行等值比較;使用多種條件進行非等值比較。
1) 在CASE語句中使用單一選擇符進行等值比較
當使用CASE語句進行多重條件分支時,如果條件選擇符完全相同,並且條件運算式為相同條件選擇,那麼可以選擇使用單一選擇符進行等值比較。
CASE selector WHEN exp1 THEN state1; WHEN exp2 THEN state2; .... [else stateN;] END CASE;
這裡,selector用於指定條件選擇符,exp用於指定條件值的運算式,state用於指定要執行的條件操作。如果設定的所有條件都不滿足,就會執行else語句,為避免CASE_NOT_FOUND異常,在編寫CASE語句時應該帶有else子句。
2) 在CASE語句中使用多種條件比較
如果包含有多種條件進行不等比較,那麼必須在WHEN子句中指定比較條件。
CASE WHEN condition1 THEN state1; WHEN condition2 THEN state2; .... [else stateN;] END CASE;
condition用於指定不同的比較條件。
3) CASE運算式
CASE運算式也可以採用上面兩種形式。
case_experssion := CASE exp WHEN。。。
或者
case_experssion := CASE WHEN。。。
2.迴圈控制2.1 基本迴圈
基本迴圈語句以LOOP開始,END LOOP 結束。
LOOP statement; ... EXIT [WHEN condition]; END LOOP;
當使用基本迴圈時,無論是否滿足條件,語句至少會執行一次。當條件為true時,會退出迴圈,並執行end LOOP後的相應操作。注意,當編寫基本迴圈時,一定要包含exit語句,否則PL/SQL塊會陷入死迴圈;另外還應該定義迴圈控制變數,並且在迴圈體內修改迴圈控制的值。
2.2 WHILE迴圈
只有條件為true時,才執行迴圈體內的內容,while迴圈以while…LOOP 開始,以end LOOP結束。
2.3 FOR迴圈
當使用基本迴圈或者while迴圈時,需要定義迴圈控制變數,並且迴圈控制變數不僅可以是NUMBER類型,也可以使用其他資料類型;而當使用for迴圈時,會隱含定義迴圈控制變數
FOR counter IN [REVERSE] lower_bound ..upper_bound LOOP statement; ... end loop;
counter是迴圈控制變數,該變數由Oracle隱含定義,不需要顯式定義;lower_bound和upper_bound分別對應於迴圈控制變數的上下界值。預設情況下,當使用FOR迴圈時,每次迴圈時迴圈控制變數會自動加1,如果指定了reverse選項,則每次迴圈控制變數自動減1.
2.4嵌套迴圈和標號
嵌套迴圈是指在一個迴圈語句中嵌入另一個迴圈語句,而標號(Lable)則用於標記嵌套塊或者嵌套迴圈。通過在嵌套迴圈中使用標號,可以區分內層和外層迴圈,並且可以在內層迴圈中直接退出外層迴圈。可以使用<>定義標號。
3.順序控制
PL/SQL不僅提供了條件分支語句和迴圈控制語句,還提供了順序控制語句GOTO和NULL。但是,在一般情況下盡量不要使用goto和null語句。
3.1 GOTO語句
GOTO語句用於跳轉到指定標號處去執行語句。注意,因為使用GOTO語句會增加程式的複雜性,並且使得應用程式可讀性變差,所以開發應用程式時,一般不建議使用GOTO語句。
其文法形式為:
GOTO label_name;
其中,label_name是已經定義的標號名,需要注意的是,標號後至少要包含一條可執行語句。
3.2 NULL語句
NULL語句不會執行任何操作,並且會直接將控制傳遞到下一條語句。使用NULL語句的好處時可以提高程式的可讀性。
4.異常處理
PL/SQL語言中,任何類型的錯誤將被看作為不應該在程式中發生的異常情況。異常可以是以下之一:
☆ 由系統產生的錯誤(例如記憶體不足,重複索引值)
☆ 由使用者行為導致的錯誤
☆ 由應用程式發出給使用者的警告
PL/SQL使用一種異常處理器來捕獲和響應這些錯誤。當發生錯誤時,不管是系統錯誤還是應用程式錯誤都會拋出一個異常。此時,當前PL/SQL塊執行部分的處理就會中止,程式流程就會轉到當前塊的異常處理部分來處理異常。在完成異常處理後,程式不能返回到執行部分。
通常,異常分為兩種類型:系統異常和程式員自訂的異常。
1) 系統異常
系統異常時由Oracle自己定義的,通常時由PL/SQL運行時引擎在檢測了錯誤時拋出的。
系統異常不需要我們定義,在應用程式運行時會自動拋出,然後交給我們編寫異常處理部分進行異常處理。
表4-1 Oracle預定義異常
異常名 |
對應錯誤號碼 |
說明 |
ACCESS_INTO_NULL |
ORA-06530 |
當開發物件類型應用時,在引用對象屬性之前,必須先初始化對象。如果沒有初始化,直接為對象屬性賦值則會拋出異常。 |
CASE_NOT_FOUND |
ORA-06592 |
在CASE語句中,WHEN子句中沒有包含必須的條件分支,且沒有ELSE語句。 |
COLLECTION_IS_NULL |
ORA-06531 |
在給集合元素賦值前,必須首先初始化集合元素。 |
CURSOR_ALREADY_OPEN |
ORA-06511 |
當重新開啟已經開啟的遊標時拋出異常 |
DUP_VAL_INDEX |
ORA-00001 |
在唯一索引對應的列上鍵入重複值時拋出異常 |
INVALID_CURSOR |
ORA-01001 |
當試圖在不合法的遊標上執行操作時拋出 |
INVALID_NULBER |
ORA-01722 |
當內嵌sql語句不能呢個有效地將字元轉換為數字時拋出 |
NO_DATA_FOUND |
ORA-01403 |
當執行select into 未返回行,或者引用了索引表未初始化元素時拋出 |
TOO_MANY_ROWS |
ORA-01422 |
當執行select into 語句時,如果返回超過一行拋出 |
ZERO_DIVIDE |
ORA-01476 |
除數為0時拋出 |
SUBSCRIPT-BEYOND-COUNT |
ORA-06533 |
當使用巢狀表格或者VARRAY元素時,如果元素下標超過了範圍則拋出 |
SUBSCRIPT_OUTSIDE_LIMIT |
ORA-06532 |
當使用巢狀表格或者VARRAY元素時,如果元素下標為負數拋出 |
VALUE_ERROR |
ORA-06502 |
執行賦值操作時,如果變數長度不足以容納實際資料時拋出 |
LOGIN_BENIED |
ORA-01017 |
應用程式需要串連到Oracle資料庫時,如果提供了錯誤的使用者名稱或口令時拋出 |
NOT_LOGGED_ON |
ORA-01012 |
如果應用程式沒有串連到Oracle資料庫時拋出 |
PROGRAM_ERROR |
ORA-06501 |
如果出現該錯誤說明PL/SQL內部存在問題,可能需要重裝資料字典 |
ROWTYPE_MISMATCH |
ORA-06504 |
當執行賦值操作時,如果宿主遊標變數和PL/SQL遊標變數的傳回型別不相容時拋出 |
SELF_IS_NULL |
ORA-30625 |
當使用物件類型時,如果在NULL執行個體上調用成員方法時拋出 |
STORAGE_ERROR |
ORA-06500 |
如果超出記憶體空間或者記憶體被損壞時拋出 |
SYS_INVALID_ROWID |
ORA-01410 |
將字串轉換為rowid時,必須使用有效字串,否則拋出異常 |
TIMEOUT_ON_RESOURCE |
ORA-00051 |
如果Oracle等待資源時出現逾時錯誤時拋出 |
2)自訂異常
異常處理的流程包括定義異常、拋出異常和處理異常三個部分。
4.1 定義異常
在異常被拋出或處理之前,必須先定義。系統異常已經由Oracle本身定義了,因此我們在應用程式中不需要定義它們。我們可以使用兩種不同的方式來自訂異常。
① 定義命名的異常
為了處理異常,必須對有一個該異常的名稱。通過在EXCEPTION關鍵字前列出我們想在程式中拋出的異常的名稱,就可以定義一個異常。
異常的名稱只能以兩種方式被引用:
☆ 在要跑出異常的程式執行部分用RAISE語句引用
☆ 在要處理拋出的異常的異常處理部分的WHEN子句中引用。
②將異常名稱與錯誤號碼關聯
EXCEPTION_INIT命令用於將一個內部錯誤號碼與異常的名稱關聯。關聯完成後,就可以通過名稱拋出異常,並編寫一個顯式的WHEN處理器捕獲異常。
EXCEPTION_INIT必須出現在塊的定義部分,並且異常的名字必須在相同的塊或者包規範中已經定義了。
DECLARE 異常名稱 EXCEPTION; PRAGMA EXCEPTION_INIT(異常名稱,錯誤號碼);
這裡,錯誤號碼是一個整數,他有如下的限制:
☆ 不能是-1403 (這個錯誤號碼時給NO_DATA_FOUND的)
☆ 不能是0或者任何除100以外的正數。
☆ 不能時小於-10000000的負數。
4.2 拋出異常
在應用程式中拋出異常的方式有三種:
☆ 當Oracle檢測到錯誤時會自動拋出異常;
☆ 程式員可以使用RAISE語句拋出異常;
☆ 程式員可以使用RAISE_APPLICATION_ERROR內建函數拋出異常。
1)RAISE語句拋出異常
使用RAISE語句可以拋出自訂異常或系統異常。
RAISE 異常名稱;
2)RAISE_APPLICATION_ERROR語句拋出異常
使用RAISE_APPLICATION_ERROR替代RAISE的優點在於,我們可以將錯誤訊息與異常關聯起來。注意,該過程只能在資料庫端的子程式(過程、函數、包、觸發器)中使用,而不能在匿名塊和用戶端的子程式中使用。
RAISE_APPLICATION_ERROR(錯誤號碼,錯誤描述 [,{true|false} ]);
其中,錯誤號碼必須是-20000到-20999之間的負整數;錯誤描述長度不能超過2048位元組;第三個參數為選擇性參數,如果設定為true,則該錯誤號碼被放在先前的錯誤堆棧中;如果設定為false(預設值),則會替代先前所有錯誤。
4.3處理異常
一旦異常被拋出,當前PL/SQL塊就會停止正常執行,將控制權交給異常處理部分。為了處理拋出的異常,必須在異常處理部分編寫異常處理器。異常處理器必須出現在執行部分之後,在END語句之前。EXception關鍵字指示了異常處理部分和異常處理器的開始。
異常只有在拋出的異常匹配WHEN子句中的異常名時才會被處理。這裡WHEN子句之後只能跟異常名,不能跟錯誤號碼。
菊子曰:專業的部落格管理軟體