Oracle學習之三 程式控制結構

來源:互聯網
上載者:User
文章目錄
  • 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子句之後只能跟異常名,不能跟錯誤號碼。

 菊子曰:專業的部落格管理軟體
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.