亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Oracle > 正文

Oracle PL/SQL語言初級教程之異常處理

2024-08-29 13:50:04
字體:
來源:轉載
供稿:網友
  PL/SQL處理異常不同于其他程序語言的錯誤治理方法,PL/SQL的異常處理機制與ADA很相似,有一個處理錯誤的全包含方法。當發生錯誤時,程序無條件轉到異常處理部分,這就要求代碼要非常干凈并把錯誤處理部分和程序的其它部分分開。Oracle答應聲明其他異常條件類型以擴展錯誤/異常處理。這種擴展使PL/SQL的異常處理非常靈活。

  當一個運行時錯誤發生時,稱為一個異常被拋出。PL/SQL程序編譯時的錯誤不是能被處理得異常,只有在運行時的異常能被處理。在PL/SQL程序設計中異常的拋出和處理是非常重要的內容。

  拋出異常

  由三種方式拋出異常

   . 通過PL/SQL運行時引擎

   . 使用RAISE語句

   . 調用RAISE_application_ERROR存儲過程

  當數據庫或PL/SQL在運行時發生錯誤時,一個異常被PL/SQL運行時引擎自動拋出。異常也可以通過RAISE語句拋出

  RAISE exception_name;

  顯式拋出異常是程序員處理聲明的異常的習慣用法,但RAISE不限于聲明了的異常,它可以拋出任何任何異常。例如,你希望用TIMEOUT_ON_RESOURCE錯誤檢測新的運行時異常處理器,你只需簡單的在程序中使用下面的語句:

  RAISE TIMEOUT_ON_RESOUCE;

  下面看一個訂單輸入系統,當庫存小于訂單時拋出一個inventory_too_low異常。

DECLARE
inventory_too_low EXCEPTION;
---其他聲明語句
BEGIN
.
.
IF order_rec.qty>inventory_rec.qty THEN
RAISE inventory_too_low;
END IF
.
.
EXCEPTION
WHEN inventory_too_low THEN
order_rec.staus:='backordered';
replenish_inventory(inventory_nbr=>
inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
END;

  這里replenish_inventory是一個觸發器。
 
  處理異常

  PL/SQL程序塊的異常部分包含了程序處理錯誤的代碼,當異常被拋出時,一個異常陷阱就自動發生,程序控制離開執行部分轉入異常部分,一旦程序進入異常部分就不能再回到同一塊的執行部分。下面是異常部分的一般語法:

EXCEPTION
 WHEN exception_name THEN
  Code for handing exception_name
 [WHEN another_exception THEN
  Code for handing another_exception]
 [WHEN others THEN
  code for handing any other exception.]

  用戶必須在獨立的WHEN子串中為每個異常設計異常處理代碼,WHEN OTHERS子串必須放置在最后面作為缺省處理器處理沒有顯式處理的異常。當異常發生時,控制轉到異常部分,ORACLE查找當前異常相應的WHEN..THEN語句,捕捉異常,THEN之后的代碼被執行,假如錯誤陷阱代碼只是退出相應的嵌套塊,那么程序將繼續執行內部塊END后面的語句。假如沒有找到相應的異常陷阱,那么將執行WHEN OTHERS。在異常部分WHEN 子串沒有數量限制。

EXCEPTION

 WHEN inventory_too_low THEN
  order_rec.staus:='backordered';
  replenish_inventory(inventory_nbr=>
  inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
 WHEN discontinued_item THEN
  --code for discontinued_item PRocessing
 WHEN zero_divide THEN
  --code for zero_divide
 WHEN OTHERS THEN
  --code for any other exception
END;

  當異常拋出后,控制無條件轉到異常部分,這就意味著控制不能回到異常發生的位置,當異常被處理和解決后,控制返回到上一層執行部分的下一條語句。

BEGIN
 DECLARE
  bad_credit;
 BEGIN
  RAISE bad_credit;
   --發生異常,控制轉向;
 EXCEPTION
  WHEN bad_credit THEN
   dbms_output.put_line('bad_credit');
  END;

  --bad_credit異常處理后,控制轉到這里
 EXCEPTION
  WHEN OTHERS THEN
   --控制不會從bad_credit異常轉到這里
   --因為bad_credit已被處理
END;


  當異常發生時,在塊的內部沒有該異常處理器時,控制將轉到或傳播到上一層塊的異常處理部分。

BEGIN
 DECLARE ---內部塊開始
  bad_credit;
 BEGIN
  RAISE bad_credit;
   --發生異常,控制轉向;
  EXCEPTION
  WHEN ZERO_DIVIDE THEN --不能處理bad_credite異常
   dbms_output.put_line('divide by zero error');
  END --結束內部塊

   --控制不能到達這里,因為異常沒有解決;
   --異常部分

  EXCEPTION
  WHEN OTHERS THEN
   --由于bad_credit沒有解決,控制將轉到這里
END;

  異常傳播

  沒有處理的異常將沿檢測異常調用程序傳播到外面,當異常被處理并解決或到達程序最外層傳播停止。
在聲明部分拋出的異常將控制轉到上一層的異常部分。

BEGIN
executable statements
BEGIN
today DATE:='SYADATE'; --ERRROR
BEGIN --內部塊開始
dbms_output.put_line('this line will not execute');
EXCEPTION
WHEN OTHERS THEN
--異常不會在這里處理
END;--內部塊結束

EXCEPTION
WHEN OTHERS THEN
處理異常
END

  執行部分拋出的異常將首先傳遞到同一塊的異常部分,假如在同一塊的異常部分沒有處理這個異常的處理器,那么異常將會傳播到上一層的異常部分中,一直到最外層。

  在異常部分拋出的異常將控制轉到上一層的異常部分。

  處理異常將停止異常的傳播和解決。有時用戶希望在錯誤發生時,程序仍然能執行一些動作,要達到這個目的,可以把希望執行的動作放在異常處理器中,然后執行不帶參數的RAISE語句,RAISE語句將重新拋出出現的異常,答應他繼續傳播。

DECLARE
order_too_old EXCEPTION;
BEGIN
RAISE order_too_old;
EXCEPTION
WHEN order_too_old THEN
DECLARE
file_handle UTL_FILE.FILE_TYPE;
BEGIN
--open file
file_handle:=UTL_FILE.FOPEN
(location=>'/ora01/app/oracle/admin/test/utlsir'
,filename=>'error.log'
.open_mode=>'W');
--write error stack
UTL_FILE.PUT_LINE(filehandle,
DBMS_UTILITY.FORMAT_ERROR_STACK);
--write the call stack
UTL_FILE.PUT_LINE(filehandle,
DBMS_UTILITY.FORMAT_CALL_STACK);
--close error log
UTL_FILE.FCLOSE(file_handle);
RAISE; --re-raise the exception
END
END

  假如從FORMAT_XXX_STACK輸出一個很大的值,那么使用DBMS_OUTPUT或UTL_FILE顯示錯誤或調用堆的異常部分自身也會拋出異常,這兩個堆常規下最多能返回2000字節,但utl_file.put_line被限制在1000字節以內,而dbms_output.put_line限制在512字節內。假如使用前面的代碼并且不答應這種可能性,那么在異常處理器中將拋出一個未處理的異常。

  GOTO語句不能用于將控制從執行部分傳遞到異常部分或反之。

  已命名異常

  在PL/SQL塊的異常部分只有已命名的異常才能被WHEN子串處理,ORACLE包含了一系列已命名的異常,這些異常都聲明在STANDARD包中,這些內建異常在這里就不一一講述,有愛好的讀者可以查閱有關資料?! L/SQL處理異常不同于其他程序語言的錯誤治理方法,PL/SQL的異常處理機制與ADA很相似,有一個處理錯誤的全包含方法。當發生錯誤時,程序無條件轉到異常處理部分,這就要求代碼要非常干凈并把錯誤處理部分和程序的其它部分分開。oracle答應聲明其他異常條件類型以擴展錯誤/異常處理。這種擴展使PL/SQL的異常處理非常靈活。

  當一個運行時錯誤發生時,稱為一個異常被拋出。PL/SQL程序編譯時的錯誤不是能被處理得異常,只有在運行時的異常能被處理。在PL/SQL程序設計中異常的拋出和處理是非常重要的內容。

  拋出異常

  由三種方式拋出異常

   . 通過PL/SQL運行時引擎

   . 使用RAISE語句

   . 調用RAISE_APPLICATION_ERROR存儲過程

  當數據庫或PL/SQL在運行時發生錯誤時,一個異常被PL/SQL運行時引擎自動拋出。異常也可以通過RAISE語句拋出

  RAISE exception_name;

  顯式拋出異常是程序員處理聲明的異常的習慣用法,但RAISE不限于聲明了的異常,它可以拋出任何任何異常。例如,你希望用TIMEOUT_ON_RESOURCE錯誤檢測新的運行時異常處理器,你只需簡單的在程序中使用下面的語句:

  RAISE TIMEOUT_ON_RESOUCE;

  下面看一個訂單輸入系統,當庫存小于訂單時拋出一個inventory_too_low異常。

DECLARE
inventory_too_low EXCEPTION;
---其他聲明語句
BEGIN
.
.
IF order_rec.qty>inventory_rec.qty THEN
RAISE inventory_too_low;
END IF
.
.
EXCEPTION
WHEN inventory_too_low THEN
order_rec.staus:='backordered';
replenish_inventory(inventory_nbr=>
inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
END;

  這里replenish_inventory是一個觸發器。
 
  處理異常

  PL/SQL程序塊的異常部分包含了程序處理錯誤的代碼,當異常被拋出時,一個異常陷阱就自動發生,程序控制離開執行部分轉入異常部分,一旦程序進入異常部分就不能再回到同一塊的執行部分。下面是異常部分的一般語法:

EXCEPTION
 WHEN exception_name THEN
  Code for handing exception_name
 [WHEN another_exception THEN
  Code for handing another_exception]
 [WHEN others THEN
  code for handing any other exception.]

  用戶必須在獨立的WHEN子串中為每個異常設計異常處理代碼,WHEN OTHERS子串必須放置在最后面作為缺省處理器處理沒有顯式處理的異常。當異常發生時,控制轉到異常部分,ORACLE查找當前異常相應的WHEN..THEN語句,捕捉異常,THEN之后的代碼被執行,假如錯誤陷阱代碼只是退出相應的嵌套塊,那么程序將繼續執行內部塊END后面的語句。假如沒有找到相應的異常陷阱,那么將執行WHEN OTHERS。在異常部分WHEN 子串沒有數量限制。

EXCEPTION

 WHEN inventory_too_low THEN
  order_rec.staus:='backordered';
  replenish_inventory(inventory_nbr=>
  inventory_rec.sku,min_amount=>order_rec.qty-inventory_rec.qty);
 WHEN discontinued_item THEN
  --code for discontinued_item processing
 WHEN zero_divide THEN
  --code for zero_divide
 WHEN OTHERS THEN
  --code for any other exception
END;

  當異常拋出后,控制無條件轉到異常部分,這就意味著控制不能回到異常發生的位置,當異常被處理和解決后,控制返回到上一層執行部分的下一條語句。

BEGIN
 DECLARE
  bad_credit;
 BEGIN
  RAISE bad_credit;
   --發生異常,控制轉向;
 EXCEPTION
  WHEN bad_credit THEN
   dbms_output.put_line('bad_credit');
  END;

  --bad_credit異常處理后,控制轉到這里
 EXCEPTION
  WHEN OTHERS THEN
   --控制不會從bad_credit異常轉到這里
   --因為bad_credit已被處理
END;


  當異常發生時,在塊的內部沒有該異常處理器時,控制將轉到或傳播到上一層塊的異常處理部分。

BEGIN
 DECLARE ---內部塊開始
  bad_credit;
 BEGIN
  RAISE bad_credit;
   --發生異常,控制轉向;
  EXCEPTION
  WHEN ZERO_DIVIDE THEN --不能處理bad_credite異常
   dbms_output.put_line('divide by zero error');
  END --結束內部塊

   --控制不能到達這里,因為異常沒有解決;
   --異常部分

  EXCEPTION
  WHEN OTHERS THEN
   --由于bad_credit沒有解決,控制將轉到這里
END;

  異常傳播

  沒有處理的異常將沿檢測異常調用程序傳播到外面,當異常被處理并解決或到達程序最外層傳播停止。
在聲明部分拋出的異常將控制轉到上一層的異常部分。

BEGIN
executable statements
BEGIN
today DATE:='SYADATE'; --ERRROR
BEGIN --內部塊開始
dbms_output.put_line('this line will not execute');
EXCEPTION
WHEN OTHERS THEN
--異常不會在這里處理
END;--內部塊結束

EXCEPTION
WHEN OTHERS THEN
處理異常
END

  執行部分拋出的異常將首先傳遞到同一塊的異常部分,假如在同一塊的異常部分沒有處理這個異常的處理器,那么異常將會傳播到上一層的異常部分中,一直到最外層。

  在異常部分拋出的異常將控制轉到上一層的異常部分。

  處理異常將停止異常的傳播和解決。有時用戶希望在錯誤發生時,程序仍然能執行一些動作,要達到這個目的,可以把希望執行的動作放在異常處理器中,然后執行不帶參數的RAISE語句,RAISE語句將重新拋出出現的異常,答應他繼續傳播。

DECLARE
order_too_old EXCEPTION;
BEGIN
RAISE order_too_old;
EXCEPTION
WHEN order_too_old THEN
DECLARE
file_handle UTL_FILE.FILE_TYPE;
BEGIN
--open file
file_handle:=UTL_FILE.FOPEN
(location=>'/ora01/app/oracle/admin/test/utlsir'
,filename=>'error.log'
.open_mode=>'W');
--write error stack
UTL_FILE.PUT_LINE(filehandle,
DBMS_UTILITY.FORMAT_ERROR_STACK);
--write the call stack
UTL_FILE.PUT_LINE(filehandle,
DBMS_UTILITY.FORMAT_CALL_STACK);
--close error log
UTL_FILE.FCLOSE(file_handle);
RAISE; --re-raise the exception
END
END

  假如從FORMAT_XXX_STACK輸出一個很大的值,那么使用DBMS_OUTPUT或UTL_FILE顯示錯誤或調用堆的異常部分自身也會拋出異常,這兩個堆常規下最多能返回2000字節,但utl_file.put_line被限制在1000字節以內,而dbms_output.put_line限制在512字節內。假如使用前面的代碼并且不答應這種可能性,那么在異常處理器中將拋出一個未處理的異常。

  GOTO語句不能用于將控制從執行部分傳遞到異常部分或反之。

  已命名異常

  在PL/SQL塊的異常部分只有已命名的異常才能被WHEN子串處理,ORACLE包含了一系列已命名的異常,這些異常都聲明在STANDARD包中,這些內建異常在這里就不一一講述,有愛好的讀者可以查閱有關資料。


上一篇:Oracle PL/SQL語言初級教程之游標

下一篇:案例討論:Oracle數據庫的分組問題

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产欧美在线视频| 精品夜色国产国偷在线| 国产视频精品久久久| 夜夜嗨av一区二区三区免费区| 国产在线拍偷自揄拍精品| 欧美激情久久久久久| 精品自在线视频| 欧美日韩亚洲精品内裤| 国产精品视频网| 亚洲国产97在线精品一区| 色无极影院亚洲| 国产精品极品尤物在线观看| 美女视频久久黄| 国产精品香蕉国产| 尤物yw午夜国产精品视频明星| 日韩免费在线播放| 久久99国产综合精品女同| 日韩美女写真福利在线观看| 国产成人精品最新| 国产视频观看一区| 色诱女教师一区二区三区| 日韩欧美国产网站| 国产69精品久久久久9999| 日韩av大片在线| 欧美美女操人视频| 日韩在线观看免费全| 日韩av有码在线| 国产香蕉97碰碰久久人人| 狠狠操狠狠色综合网| 日韩a**站在线观看| 91色视频在线观看| 亚洲免费av片| 欧美在线播放视频| 国内精品久久久久影院 日本资源| 亚洲国产精品专区久久| 最新69国产成人精品视频免费| 一区二区欧美久久| 欧美日韩国产一区在线| 亚洲iv一区二区三区| 久久综合伊人77777蜜臀| 国产精品爽爽爽| 国产91精品久久久| 日产精品99久久久久久| 日韩欧美国产黄色| 亚洲国产精品网站| 欧美一区二区三区免费观看| 亚洲色在线视频| 亚洲在线免费看| 亚洲高清久久久久久| 国产一区深夜福利| 中文字幕不卡av| 亚洲国产成人av在线| 欧洲永久精品大片ww免费漫画| 精品国产成人av| 久久国产视频网站| 国产区精品视频| 亚洲精品视频网上网址在线观看| 国产精品高潮在线| 亚洲精品日韩av| 精品中文字幕在线| 欧美专区中文字幕| 欧美电影电视剧在线观看| 日韩在线中文字幕| 欧美一级在线亚洲天堂| 亚洲欧美一区二区三区在线| 亚洲码在线观看| 欧美性生交xxxxxdddd| 国产精品久久久久久久久久三级| 欧美精品在线看| 久久免费精品日本久久中文字幕| 日韩在线播放视频| 国产va免费精品高清在线| 日韩美女福利视频| 欧美刺激性大交免费视频| 精品久久久久久中文字幕大豆网| 性视频1819p久久| 欧美国产在线视频| 亚洲欧美在线一区| 欧美在线视频网| 欧美性受xxx| 欧美在线播放视频| 亚洲国产欧美一区二区三区久久| 成人免费网站在线看| 国产一区二区三区免费视频| 欧美极品少妇全裸体| 日韩电影免费观看中文字幕| 亚洲一区二区免费| 91精品国产成人| 欧美伊久线香蕉线新在线| 在线看国产精品| 萌白酱国产一区二区| 国产精品老牛影院在线观看| 日韩av在线网站| 亚洲欧美一区二区三区四区| 国产精品成人免费电影| 国产亚洲精品一区二区| 成人精品视频在线| 国产玖玖精品视频| 欧美疯狂做受xxxx高潮| 欧美亚洲国产视频| 成人精品在线视频| 欧美情侣性视频| 亚洲成人xxx| 亚洲成年网站在线观看| 亚洲一区免费网站| 久久av资源网站| 国产剧情日韩欧美| 亚洲国产婷婷香蕉久久久久久| 欧美另类交人妖| 欧美性受xxxx黑人猛交| 欧美成人午夜激情视频| 久久久国产在线视频| 日韩欧美亚洲综合| 日韩综合中文字幕| 91成人国产在线观看| 国内精品小视频在线观看| 国产一区视频在线播放| 国产精品丝袜视频| 亚洲自拍偷拍网址| 亚洲国产精品热久久| 欧美极品第一页| 欧美精品免费在线观看| 狠狠色噜噜狠狠狠狠97| 久久精品国产精品| 亚洲日本中文字幕免费在线不卡| 国产欧美久久久久久| 97香蕉超级碰碰久久免费的优势| 亚洲日韩欧美视频一区| 色一区av在线| 亚洲最新中文字幕| 亚洲精品在线视频| 久热在线中文字幕色999舞| 欧美激情中文字幕在线| 国产精品男人爽免费视频1| 日韩电影视频免费| 亚洲美女中文字幕| 精品亚洲一区二区三区在线观看| 欧美日韩亚洲一区二| 美女av一区二区三区| 国产免费一区二区三区在线观看| 久久久久国产精品免费网站| 国产欧美一区二区三区在线| 91中文在线视频| 欧美中文字幕精品| 国语自产精品视频在线看| 日本精品va在线观看| 亚洲精品欧美极品| 国产999精品久久久| 中文字幕视频在线免费欧美日韩综合在线看| 色婷婷综合成人| 粉嫩av一区二区三区免费野| 日韩中文视频免费在线观看| 久久视频免费在线播放| 色综合色综合久久综合频道88| 欧美黑人一区二区三区| 亚洲国产精品中文| 日韩在线视频免费观看| 欧美一级淫片丝袜脚交| 国产美女久久久| 欧美日韩国产色视频| 欧美成人性色生活仑片| 国产精彩精品视频| 色综合五月天导航| 国产精品免费看久久久香蕉|