鍍金池/ 教程/ 數(shù)據(jù)庫(kù)/ PL/SQL異常
PL/SQL記錄
PL/SQL基本語(yǔ)法
PL/SQL集合
PL/SQL包
PL/SQL關(guān)系運(yùn)算符
PL/SQL比較運(yùn)算符
PL/SQL條件控制
PL/SQL字符串
PL/SQL算術(shù)運(yùn)算符
PL/SQL變量
PL/SQL IF-THEN-ELSIF語(yǔ)句
PL/SQL函數(shù)
PL/SQL異常
PL/SQL FOR循環(huán)語(yǔ)句
PL/SQL日期及時(shí)間
PL/SQL EXIT語(yǔ)句
PL/SQL DBMS輸出
PL/SQL過(guò)程
PL/SQL CONTINUE語(yǔ)句
PL/SQL數(shù)組
PL/SQL嵌套IF-THEN-ELSE語(yǔ)句
PL/SQL事務(wù)
PL/SQL CASE語(yǔ)句
PL/SQL IF-THEN語(yǔ)句
PL/SQL GOTO語(yǔ)句
PL/SQL運(yùn)算符優(yōu)先級(jí)
PL/SQL觸發(fā)器
PL/SQL運(yùn)算符
PL/SQL教程
PL/SQL WHILE循環(huán)語(yǔ)句
PL/SQL面向?qū)ο?/span>
PL/SQL循環(huán)
PL/SQL邏輯運(yùn)算符
PL/SQL IF-THEN-ELSE語(yǔ)句
PL/SQL數(shù)據(jù)類(lèi)型
PL/SQL環(huán)境安裝設(shè)置
PL/SQL游標(biāo)
PL/SQL基本循環(huán)語(yǔ)句
PL/SQL搜索CASE語(yǔ)句
PL/SQL常量和文字
PL/SQL嵌套循環(huán)

PL/SQL異常

程序執(zhí)行過(guò)程中出現(xiàn)錯(cuò)誤情況被稱(chēng)為在PL/SQL異常。 PL/SQL支持程序員在程序中使用異常塊捕獲這樣的條件并采取適當(dāng)?shù)膭?dòng)作應(yīng)對(duì)錯(cuò)誤情況。有兩種類(lèi)型的異常:

  • 系統(tǒng)定義的異常

  • 用戶(hù)定義的異常

異常處理語(yǔ)法

一般異常處理的語(yǔ)法如下。在這里可以列出下來(lái)很多,要處理異常。默認(rèn)的異常將使用WHEN others THEN處理:

DECLARE
   <declarations section>
BEGIN
   <executable command(s)>
EXCEPTION
   <exception handling goes here >
   WHEN exception1 THEN 
       exception1-handling-statements 
   WHEN exception2  THEN 
      exception2-handling-statements 
   WHEN exception3 THEN 
      exception3-handling-statements
   ........
   WHEN others THEN
      exception3-handling-statements
END;

示例

寫(xiě)一些簡(jiǎn)單的代碼來(lái)說(shuō)明這個(gè)概念。將使用我們已經(jīng)創(chuàng)建,并在前面的章節(jié)中使用的CUSTOMERS表:

DECLARE
   c_id customers.id%type := 8;
   c_name  customers.name%type;
   c_addr customers.address%type;
BEGIN
   SELECT  name, address INTO  c_name, c_addr
   FROM customers
   WHERE id = c_id;

   DBMS_OUTPUT.PUT_LINE ('Name: '||  c_name);
   DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
EXCEPTION
   WHEN no_data_found THEN
      dbms_output.put_line('No such customer!');
   WHEN others THEN
      dbms_output.put_line('Error!');
END;
/

當(dāng)上述代碼在SQL提示符執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:

No such customer!

PL/SQL procedure successfully completed. 

上述程序顯示一個(gè)客戶(hù)的ID給出的名字和地址。由于在我們的數(shù)據(jù)庫(kù)沒(méi)有ID值為8的客戶(hù),該程序運(yùn)行時(shí)引發(fā)一個(gè)異常NO_DATA_FOUND,這是捕獲異常EXCEPTION塊。

引發(fā)異常

異常是數(shù)據(jù)庫(kù)服務(wù)器自動(dòng)在內(nèi)部數(shù)據(jù)庫(kù)錯(cuò)誤,但異常可以明確地提出由程序員使用命令RAISE。以下是引發(fā)異常的簡(jiǎn)單的語(yǔ)法:

DECLARE
   exception_name EXCEPTION;
BEGIN
   IF condition THEN
      RAISE exception_name;
   END IF;
EXCEPTION
   WHEN exception_name THEN
   statement;
END;

可以在引發(fā)Oracle的標(biāo)準(zhǔn)異?;蛉魏斡脩?hù)定義的異常使用上述語(yǔ)法。下一節(jié)會(huì)顯示如何引發(fā)用戶(hù)定義異常,引發(fā)Oracle標(biāo)準(zhǔn)異常以及類(lèi)似的方法的例子。

用戶(hù)自定義異常

PL/SQL允許根據(jù)程序的需要定義自己的異常。用戶(hù)定義的異常必須聲明,然后明確地提出使用一個(gè)RAISE語(yǔ)句或程序DBMS_STANDARD.RAISE_APPLICATION_ERROR。

聲明一個(gè)異常的語(yǔ)法是:

DECLARE
   my-exception EXCEPTION;

示例:

下面的例子說(shuō)明了這個(gè)概念。該程序需要一個(gè)客戶(hù)ID,當(dāng)用戶(hù)輸入了一個(gè)無(wú)效的ID,異常invalid_id引發(fā)。

DECLARE
   c_id customers.id%type := &cc_id;
   c_name  customers.name%type;
   c_addr customers.address%type;

   -- user defined exception
   ex_invalid_id  EXCEPTION;
BEGIN
   IF c_id <= 0 THEN
      RAISE ex_invalid_id;
   ELSE
      SELECT  name, address INTO  c_name, c_addr
      FROM customers
      WHERE id = c_id;
	  
      DBMS_OUTPUT.PUT_LINE ('Name: '||  c_name);
      DBMS_OUTPUT.PUT_LINE ('Address: ' || c_addr);
   END IF;
EXCEPTION
   WHEN ex_invalid_id THEN
      dbms_output.put_line('ID must be greater than zero!');
   WHEN no_data_found THEN
      dbms_output.put_line('No such customer!');
   WHEN others THEN
      dbms_output.put_line('Error!'); 
END;
/

當(dāng)上述代碼在SQL提示符執(zhí)行時(shí),它產(chǎn)生了以下結(jié)果:

Enter value for cc_id: -6 (let's enter a value -6)
old  2: c_id customers.id%type := &cc_id;
new  2: c_id customers.id%type := -6;
ID must be greater than zero!

PL/SQL procedure successfully completed.

預(yù)定義異常

PL/SQL提供許多預(yù)先定義的異常,這是在被執(zhí)行時(shí)的任何數(shù)據(jù)庫(kù)規(guī)則由程序引發(fā)。例如,預(yù)定義異常NO_DATA_FOUND時(shí)引發(fā)一個(gè)SELECT INTO語(yǔ)句返回?cái)?shù)據(jù)行。下表列出了一些重要的預(yù)先定義的異常:

Exception Oracle Error SQLCODE 描述
ACCESS_INTO_NULL 06530 -6530 當(dāng)一個(gè)空對(duì)象會(huì)自動(dòng)分配一個(gè)值引發(fā)此異常
CASE_NOT_FOUND 06592 -6592 當(dāng)沒(méi)有任何選擇,在當(dāng)選擇一個(gè)CASE語(yǔ)句的子句,并且沒(méi)有ELSE子句時(shí)被引發(fā)
COLLECTION_IS_NULL 06531 -6531 當(dāng)程序試圖申請(qǐng)其他收集方法不是存在未初始化的嵌套表或VARRAY,或程序試圖值分配給未初始化的嵌套表或變長(zhǎng)數(shù)組的元素時(shí)被引發(fā)
DUP_VAL_ON_INDEX 00001 -1 當(dāng)重復(fù)值試圖被存儲(chǔ)在具有唯一索引的列時(shí)被引發(fā)
INVALID_CURSOR 01001 -1001 當(dāng)嘗試以使這是不允許的,如關(guān)閉一個(gè)未打開(kāi)的游標(biāo)的游標(biāo)操作時(shí)被引發(fā)
INVALID_NUMBER 01722 -1722 當(dāng)一個(gè)字符的字符串轉(zhuǎn)換成一個(gè)數(shù)失敗,因?yàn)樽址槐硎疽粋€(gè)有效的數(shù)據(jù)被引發(fā)
LOGIN_DENIED 01017 -1017 當(dāng)程序試圖登錄到數(shù)據(jù)庫(kù)使用無(wú)效的用戶(hù)名或密碼被引發(fā)
NO_DATA_FOUND 01403 +100 它被引發(fā)當(dāng)一個(gè)SELECT INTO語(yǔ)句無(wú)任何行返回
NOT_LOGGED_ON 01012 -1012 在不連接到數(shù)據(jù)庫(kù)發(fā)出數(shù)據(jù)庫(kù)調(diào)用它被引發(fā)
PROGRAM_ERROR 06501 -6501 它被引發(fā)當(dāng)PL/SQL有一個(gè)內(nèi)部問(wèn)題
ROWTYPE_MISMATCH 06504 -6504 當(dāng)游標(biāo)取值有不兼容的數(shù)據(jù)類(lèi)型的變量被引發(fā)
SELF_IS_NULL 30625 -30625 它被引發(fā),當(dāng)對(duì)象的成員方法被調(diào)用,但對(duì)象類(lèi)型的實(shí)例沒(méi)有被初始化。
上一篇:PL/SQL記錄下一篇:PL/SQL DBMS輸出