Oracle学习之三 程序控制结构
1.條件控制
1.1 IF語句
if語句由于根據(jù)條件,執(zhí)行兩個(gè)代碼塊之一。其語法形式如下:
IF 條件1 THEN 。。。 ELSEIF 條件2 THEN 。。。 ELSE 。。。 END IF;這里,elseif和else塊時(shí)可選的。當(dāng)使用條件分支語句時(shí),不僅可以使用if語句進(jìn)行簡單條件判斷,而且還可以使用if語句進(jìn)行二重分支和多重分支判斷。
1.2 CASE語句和CASE表達(dá)式
使用CASE語句處理多重條件分支有兩種方法:使用單一選擇符進(jìn)行等值比較;使用多種條件進(jìn)行非等值比較。
1) 在CASE語句中使用單一選擇符進(jìn)行等值比較
當(dāng)使用CASE語句進(jìn)行多重條件分支時(shí),如果條件選擇符完全相同,并且條件表達(dá)式為相同條件選擇,那么可以選擇使用單一選擇符進(jìn)行等值比較。
CASE selector WHEN exp1 THEN state1; WHEN exp2 THEN state2; .... [else stateN;] END CASE;這里,selector用于指定條件選擇符,exp用于指定條件值的表達(dá)式,state用于指定要執(zhí)行的條件操作。如果設(shè)置的所有條件都不滿足,就會(huì)執(zhí)行else語句,為避免CASE_NOT_FOUND異常,在編寫CASE語句時(shí)應(yīng)該帶有else子句。
2) 在CASE語句中使用多種條件比較
如果包含有多種條件進(jìn)行不等比較,那么必須在WHEN子句中指定比較條件。
CASEWHEN condition1 THEN state1; WHEN condition2 THEN state2; .... [else stateN;] END CASE;condition用于指定不同的比較條件。
3) CASE表達(dá)式
CASE表達(dá)式也可以采用上面兩種形式。
case_experssion := CASE exp? WHEN。。。
或者
case_experssion := CASE? WHEN。。。
?
2.循環(huán)控制
2.1 基本循環(huán)
基本循環(huán)語句以LOOP開始,END LOOP 結(jié)束。
LOOP statement; ... EXIT [WHEN condition]; END LOOP;當(dāng)使用基本循環(huán)時(shí),無論是否滿足條件,語句至少會(huì)執(zhí)行一次。當(dāng)條件為true時(shí),會(huì)退出循環(huán),并執(zhí)行end LOOP后的相應(yīng)操作。注意,當(dāng)編寫基本循環(huán)時(shí),一定要包含exit語句,否則PL/SQL塊會(huì)陷入死循環(huán);另外還應(yīng)該定義循環(huán)控制變量,并且在循環(huán)體內(nèi)修改循環(huán)控制的值。
2.2 WHILE循環(huán)
只有條件為true時(shí),才執(zhí)行循環(huán)體內(nèi)的內(nèi)容,while循環(huán)以while…LOOP 開始,以end? LOOP結(jié)束。
2.3 FOR循環(huán)
當(dāng)使用基本循環(huán)或者while循環(huán)時(shí),需要定義循環(huán)控制變量,并且循環(huán)控制變量不僅可以是NUMBER類型,也可以使用其他數(shù)據(jù)類型;而當(dāng)使用for循環(huán)時(shí),會(huì)隱含定義循環(huán)控制變量
FOR counter IN [REVERSE] lower_bound ..upper_bound LOOP statement; ... end loop;counter是循環(huán)控制變量,該變量由Oracle隱含定義,不需要顯式定義;lower_bound和upper_bound分別對應(yīng)于循環(huán)控制變量的上下界值。默認(rèn)情況下,當(dāng)使用FOR循環(huán)時(shí),每次循環(huán)時(shí)循環(huán)控制變量會(huì)自動(dòng)加1,如果指定了reverse選項(xiàng),則每次循環(huán)控制變量自動(dòng)減1.
2.4嵌套循環(huán)和標(biāo)號
嵌套循環(huán)是指在一個(gè)循環(huán)語句中嵌入另一個(gè)循環(huán)語句,而標(biāo)號(Lable)則用于標(biāo)記嵌套塊或者嵌套循環(huán)。通過在嵌套循環(huán)中使用標(biāo)號,可以區(qū)分內(nèi)層和外層循環(huán),并且可以在內(nèi)層循環(huán)中直接退出外層循環(huán)。可以使用<>定義標(biāo)號。
3.順序控制
PL/SQL不僅提供了條件分支語句和循環(huán)控制語句,還提供了順序控制語句GOTO和NULL。但是,在一般情況下盡量不要使用goto和null語句。
3.1 GOTO語句
GOTO語句用于跳轉(zhuǎn)到指定標(biāo)號處去執(zhí)行語句。注意,因?yàn)槭褂肎OTO語句會(huì)增加程序的復(fù)雜性,并且使得應(yīng)用程序可讀性變差,所以開發(fā)應(yīng)用程序時(shí),一般不建議使用GOTO語句。
其語法形式為:
GOTO label_name;其中,label_name是已經(jīng)定義的標(biāo)號名,需要注意的是,標(biāo)號后至少要包含一條可執(zhí)行語句。
3.2 NULL語句
NULL語句不會(huì)執(zhí)行任何操作,并且會(huì)直接將控制傳遞到下一條語句。使用NULL語句的好處時(shí)可以提高程序的可讀性。
?
4.異常處理
PL/SQL語言中,任何類型的錯(cuò)誤將被看作為不應(yīng)該在程序中發(fā)生的異常情況。異常可以是以下之一:
☆ 由系統(tǒng)產(chǎn)生的錯(cuò)誤(例如內(nèi)存不足,重復(fù)索引值)
☆ 由用戶行為導(dǎo)致的錯(cuò)誤
☆ 由應(yīng)用程序發(fā)出給用戶的警告
PL/SQL使用一種異常處理器來捕獲和響應(yīng)這些錯(cuò)誤。當(dāng)發(fā)生錯(cuò)誤時(shí),不管是系統(tǒng)錯(cuò)誤還是應(yīng)用程序錯(cuò)誤都會(huì)拋出一個(gè)異常。此時(shí),當(dāng)前PL/SQL塊執(zhí)行部分的處理就會(huì)中止,程序流程就會(huì)轉(zhuǎn)到當(dāng)前塊的異常處理部分來處理異常。在完成異常處理后,程序不能返回到執(zhí)行部分。
通常,異常分為兩種類型:系統(tǒng)異常和程序員自定義的異常。
1) 系統(tǒng)異常
系統(tǒng)異常時(shí)由Oracle自己定義的,通常時(shí)由PL/SQL運(yùn)行時(shí)引擎在檢測了錯(cuò)誤時(shí)拋出的。
系統(tǒng)異常不需要我們定義,在應(yīng)用程序運(yùn)行時(shí)會(huì)自動(dòng)拋出,然后交給我們編寫異常處理部分進(jìn)行異常處理。
表4-1 Oracle預(yù)定義異常
| 異常名 | 對應(yīng)錯(cuò)誤號 | 說明 |
| ACCESS_INTO_NULL | ORA-06530 | 當(dāng)開發(fā)對象類型應(yīng)用時(shí),在引用對象屬性之前,必須先初始化對象。如果沒有初始化,直接為對象屬性賦值則會(huì)拋出異常。 |
| CASE_NOT_FOUND | ORA-06592 | 在CASE語句中,WHEN子句中沒有包含必須的條件分支,且沒有ELSE語句。 |
| COLLECTION_IS_NULL | ORA-06531 | 在給集合元素賦值前,必須首先初始化集合元素。 |
| CURSOR_ALREADY_OPEN | ORA-06511 | 當(dāng)重新打開已經(jīng)打開的游標(biāo)時(shí)拋出異常 |
| DUP_VAL_INDEX | ORA-00001 | 在唯一索引對應(yīng)的列上鍵入重復(fù)值時(shí)拋出異常 |
| INVALID_CURSOR | ORA-01001 | 當(dāng)試圖在不合法的游標(biāo)上執(zhí)行操作時(shí)拋出 |
| INVALID_NULBER | ORA-01722 | 當(dāng)內(nèi)嵌sql語句不能呢個(gè)有效地將字符轉(zhuǎn)換為數(shù)字時(shí)拋出 |
| NO_DATA_FOUND | ORA-01403 | 當(dāng)執(zhí)行select into 未返回行,或者引用了索引表未初始化元素時(shí)拋出 |
| TOO_MANY_ROWS | ORA-01422 | 當(dāng)執(zhí)行select into 語句時(shí),如果返回超過一行拋出 |
| ZERO_DIVIDE | ORA-01476 | 除數(shù)為0時(shí)拋出 |
| SUBSCRIPT-BEYOND-COUNT | ORA-06533 | 當(dāng)使用嵌套表或者VARRAY元素時(shí),如果元素下標(biāo)超過了范圍則拋出 |
| SUBSCRIPT_OUTSIDE_LIMIT | ORA-06532 | 當(dāng)使用嵌套表或者VARRAY元素時(shí),如果元素下標(biāo)為負(fù)數(shù)拋出 |
| VALUE_ERROR | ORA-06502 | 執(zhí)行賦值操作時(shí),如果變量長度不足以容納實(shí)際數(shù)據(jù)時(shí)拋出 |
| LOGIN_BENIED | ORA-01017 | 應(yīng)用程序需要連接到Oracle數(shù)據(jù)庫時(shí),如果提供了錯(cuò)誤的用戶名或口令時(shí)拋出 |
| NOT_LOGGED_ON | ORA-01012 | 如果應(yīng)用程序沒有連接到Oracle數(shù)據(jù)庫時(shí)拋出 |
| PROGRAM_ERROR | ORA-06501 | 如果出現(xiàn)該錯(cuò)誤說明PL/SQL內(nèi)部存在問題,可能需要重裝數(shù)據(jù)字典 |
| ROWTYPE_MISMATCH | ORA-06504 | 當(dāng)執(zhí)行賦值操作時(shí),如果宿主游標(biāo)變量和PL/SQL游標(biāo)變量的返回類型不兼容時(shí)拋出 |
| SELF_IS_NULL | ORA-30625 | 當(dāng)使用對象類型時(shí),如果在NULL實(shí)例上調(diào)用成員方法時(shí)拋出 |
| STORAGE_ERROR | ORA-06500 | 如果超出內(nèi)存空間或者內(nèi)存被損壞時(shí)拋出 |
| SYS_INVALID_ROWID | ORA-01410 | 將字符串轉(zhuǎn)換為rowid時(shí),必須使用有效的字符串,否則拋出異常 |
| TIMEOUT_ON_RESOURCE | ORA-00051 | 如果Oracle等待資源時(shí)出現(xiàn)超時(shí)錯(cuò)誤時(shí)拋出 |
2)自定義異常
異常處理的流程包括定義異常、拋出異常和處理異常三個(gè)部分。
4.1 定義異常
在異常被拋出或處理之前,必須先定義。系統(tǒng)異常已經(jīng)由Oracle本身定義了,因此我們在應(yīng)用程序中不需要定義它們。我們可以使用兩種不同的方式來自定義異常。
① 定義命名的異常
為了處理異常,必須對有一個(gè)該異常的名稱。通過在EXCEPTION關(guān)鍵字前列出我們想在程序中拋出的異常的名稱,就可以定義一個(gè)異常。
異常的名稱只能以兩種方式被引用:
☆ 在要跑出異常的程序執(zhí)行部分用RAISE語句引用
☆? 在要處理拋出的異常的異常處理部分的WHEN子句中引用。
②將異常名稱與錯(cuò)誤號關(guān)聯(lián)
EXCEPTION_INIT命令用于將一個(gè)內(nèi)部錯(cuò)誤號與異常的名稱關(guān)聯(lián)。關(guān)聯(lián)完成后,就可以通過名稱拋出異常,并編寫一個(gè)顯式的WHEN處理器捕獲異常。
EXCEPTION_INIT必須出現(xiàn)在塊的定義部分,并且異常的名字必須在相同的塊或者包規(guī)范中已經(jīng)定義了。
DECLARE 異常名稱 EXCEPTION; PRAGMA EXCEPTION_INIT(異常名稱,錯(cuò)誤號);這里,錯(cuò)誤號是一個(gè)整數(shù),他有如下的限制:
☆? 不能是-1403 (這個(gè)錯(cuò)誤號時(shí)給NO_DATA_FOUND的)
☆? 不能是0或者任何除100以外的正數(shù)。
☆? 不能時(shí)小于-10000000的負(fù)數(shù)。
4.2 拋出異常
在應(yīng)用程序中拋出異常的方式有三種:
☆? 當(dāng)Oracle檢測到錯(cuò)誤時(shí)會(huì)自動(dòng)拋出異常;
☆? 程序員可以使用RAISE語句拋出異常;
☆? 程序員可以使用RAISE_APPLICATION_ERROR內(nèi)置函數(shù)拋出異常。
1)RAISE語句拋出異常
使用RAISE語句可以拋出自定義異常或系統(tǒng)異常。
RAISE 異常名稱;2)RAISE_APPLICATION_ERROR語句拋出異常
使用RAISE_APPLICATION_ERROR替代RAISE的優(yōu)點(diǎn)在于,我們可以將錯(cuò)誤消息與異常關(guān)聯(lián)起來。注意,該過程只能在數(shù)據(jù)庫端的子程序(過程、函數(shù)、包、觸發(fā)器)中使用,而不能在匿名塊和客戶端的子程序中使用。
RAISE_APPLICATION_ERROR(錯(cuò)誤號,錯(cuò)誤描述 [,{true|false} ]);其中,錯(cuò)誤號必須是-20000到-20999之間的負(fù)整數(shù);錯(cuò)誤描述長度不能超過2048字節(jié);第三個(gè)參數(shù)為可選參數(shù),如果設(shè)置為true,則該錯(cuò)誤號被放在先前的錯(cuò)誤堆棧中;如果設(shè)置為false(默認(rèn)值),則會(huì)替代先前所有錯(cuò)誤。
4.3處理異常
一旦異常被拋出,當(dāng)前PL/SQL塊就會(huì)停止正常執(zhí)行,將控制權(quán)交給異常處理部分。為了處理拋出的異常,必須在異常處理部分編寫異常處理器。異常處理器必須出現(xiàn)在執(zhí)行部分之后,在END語句之前。EXception關(guān)鍵字指示了異常處理部分和異常處理器的開始。
異常只有在拋出的異常匹配WHEN子句中的異常名時(shí)才會(huì)被處理。這里WHEN子句之后只能跟異常名,不能跟錯(cuò)誤號。
轉(zhuǎn)載于:https://www.cnblogs.com/lslvxy/archive/2013/05/05/3061163.html
總結(jié)
以上是生活随笔為你收集整理的Oracle学习之三 程序控制结构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hdu 4309(最大流+枚举状态)
- 下一篇: puppet集群之 Nginx and