Oracle学习之三 程序控制结构
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子句中指定比較條件。
CASEWHEN 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子句之后只能跟異常名,不能跟錯誤號。
轉載于:https://www.cnblogs.com/lslvxy/archive/2013/05/05/3061163.html
總結
以上是生活随笔為你收集整理的Oracle学习之三 程序控制结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 4309(最大流+枚举状态)
- 下一篇: puppet集群之 Nginx and