異常的語法格式
在begin語句內:
exception
when then
when then
when others then
--異常處理
--首先創建一份對象的用法
create type xtype as object (name varchar2(20));
declare
x xtype;
begin
x.name:='aaa';
exception
when ACCESS_INTO_NULL then
dbms_output.put_line('init x first');
end;
--不報錯了 變成了一種正常的行為
--case not found
declare
x number(9);
begin
x:=&x;
case
when x>100 then
dbms_output.put_line('>100');
when x>200 then
dbms_output.put_line('>200');
end case;
exception
when CASE_NOT_FOUND then
dbms_output.put_line('case not found');
end;
oracle在預定義包STANDARD包中提供了一系列的預定義異常。他們是調試Oracle PL/SQL程序的有用工具。大部分錯誤用負號作為錯誤號。可以使用SQLCODE內置函數看到錯誤代碼,使用SQLERRM得到異常的內置消息。
| 異常 |
錯誤 |
何時出現 |
| ACCESS_INTO_NULL |
ORA-06530 |
試圖訪問未初始化對象的時候出現 |
| CASE_NOT_FOUND |
ORA-06592 |
如果定義了一個沒有ELSE子句的CASE語句,而且沒有CASE語句滿足運行時條件時出現該異常 |
| COLLECTION_IS_NULL |
ORA-06531 |
當程序去訪問一個沒有進行初始化的NESTED TABLE或者是VARRAY的時候,會出現該異常 |
| CURSOR_ALREADY_OPEN |
ORA-06511 |
游標已經被OPEN,如果再次嘗試打開該游標的時候,會出現該異常 |
| DUP_VAL_ON_INDEX |
ORA-00001 |
如果插入一列被唯一索引約束的重復值的時候,就會引發該異常(該值被INDEX認定為沖突的) |
| INVALID_CURSOR |
ORA-01001 |
不允許的游標操作,比如關閉一個已經被關閉的游標,就會引發 |
| INVALID_NUMBER |
ORA-01722 |
給數字值賦非數字值的時候,該異常就會發生,這個異常也會發生在批讀取時候LIMIT子句返回非正數的時候 |
| LOGIN_DENIED |
ORA-01017 |
程序中,使用錯誤的用戶名和密碼登錄的時候,就會拋出這個異常 |
| NO_DATA_FOUND |
ORA_06548 |
在使用SELECT INTO 結構,並且語句返回NULL值的時候;訪問嵌套表中已經刪除的表或者是訪問INDEX BY表(聯合數組)中的未初始化元素就會出現該異常 |
| NOT_LOGGED_ON |
ORA-01012 |
當程序發出數據庫調用,但是沒有連接的時候(通常,在實際與會話斷開連接之后) |
| PROGRAM_ERROR |
ORA-06501 |
當Oracle還未正式捕獲的錯誤發生時常會發生,這是因為數據庫大量的Object功能而發生 |
| ROWTYPE_MISMATCH |
ORA-06504 |
如果游標結構不適合PL/SQL游標變量或者是實際的游標參數不同於游標形參的時候發生該異常 |
| SELF_IS_NULL |
ORA-30625 |
調用一個對象類型非靜態成員方法(其中沒有初始化對象類型實例)的時候發生該異常 |
| STORAGE_ERROR |
ORA-06500 |
當內存不夠分配SGA的足夠配額或者是被破壞的時候,引發該異常 |
| SUBSCRIPT_BEYOND_COUNT |
ORA-06533 |
當分配給NESTED TABLE或者VARRAY的空間小於使用的下標的時候,發生該異常(類似於java的ArrayIndexOutOfBoundsException) |
| SUBSCRIPT_OUTSIDE_LIMIT |
ORA-06532 |
使用非法的索引值來訪問NESTED TABLE或者VARRAY的時候引發 |
| SYS_INVALID_ROWID |
ORA-01410 |
將無效的字符串轉化為ROWID的時候引發 |
| TIMEOUT_ON_RESOURCE |
ORA-00051 |
當數據庫不能安全鎖定資源的時候引發 |
| TOO_MANY_ROWS |
ORA-01422 |
常見錯誤,在使用SELECT INTO 並且查詢返回多個行時引發。如果子查詢返回多行,而比較運算符為相等的時候也會引發該異常。 |
| USERENV_COMMITSCN_ERROR |
ORA-01725 |
只可使用函數USERENV('COMMITSCN')作為INSERT語句的VALUES子句中的頂級表達式或者作為UPDATE語句的SET子句中的右操作數 |
| VALUE_ERROR |
ORA-06502 |
將一個變量賦給另一個不能容納該變量的變量時引發 |
| ZERO_DIVIDE |
ORA-01476 |
將某個數字除以0的時候,會發生該異常 |
可以很方便的在SQL塊中使用EXCEPTION來捕捉異常並且進行處理(當然,編譯異常與在聲明塊中被拋出的異常除外,一個好的PL/SQL編程 習慣是規避在聲明塊中進行變量的賦值操作)。如果上面的預定義異常能夠滿足要求,就可以使用他們。如果不滿足,則可以像JAVA程序一樣,定義自己的異 常,並且可以使用RAISE EXCEPTION來拋出異常。
--pl/sql自定義的異常 比如更新數據時並沒有找到數據沒有數據進行改變
select * from myemp;
declare
emp_nofound_exception exception;
begin
update myemp set sal=sal+2 where empno=&empno;--如果輸入的輸一個字符串的話 就要用單引號括起來
if sql%notfound then
raise emp_nofound_exception;
else
dbms_output.put_line('ok');
end if;
exception
when emp_nofound_exception then
dbms_output.put_line('no emp found!');
when others then
dbms_output.put_line('others');
end;
--使用兩個函數
--sqlcode sqlerrm
declare
emp_nofound_exception exception;
begin
update myemp set sal=sal+2 where empno=&empno;--如果輸入的輸一個字符串的話 就要用單引號括起來
if sql%notfound then
raise emp_nofound_exception;
else
dbms_output.put_line('ok');
end if;
exception
when others then
dbms_output.put_line('sqlcode='||sqlcode);
dbms_output.put_line('sqlerrm='||sqlerrm);--如果錯誤信息很長的話 可以用substr(sqlerrm,1,100)切割成一百的字符串
end;
