pl/sql中錯誤的異常處理
pl/sql中對於錯誤的處理是很重要的一個部分,就跟寫程式中對於異常的處理一樣。可能程式中正常的流程實現部分不是很複雜,但是對於各種可能發生的異常情況都需要面面俱到的處理要佔一半以上的程式碼量。
首先Pl/sql中的異常處理需要重視,但是異常的處理絕大多數的人寫pl/sql的時候都不夠重視,通常在資料處理完之後對於異常的處理都是以如下的形式結尾:
when others then
dbms_output.put_line('error......');
如果你也是這樣的習慣來用when others,就需要注意了。tom大師在自己的書《深入資料庫體系結構》也做了詳細的解釋,下面標黃的這句話讓人很有感觸。
?You should ignore all others – or of you do catch them to clean up a resource, RE-RAISE them
oracle的pl/sql小組在新版本的改進中曾希望他提出3點建議,他的第一點建議就是去除when others,最後這個部分還是保留了,但是如果你的pl/sql中when others沒有後面沒有raise 或者raise_application_error的部分,就會給出警告。
SQL> alter session set plsql_warnings='enable:all';
Session altered.
SQL> create or replace procedure test_proc
2 as
3 begin
4 dbms_output.put_line('this is a test');
5 exception
6 when others
7 then
8 dbms_output.put_line('error handling...');
9 end;
10 /
SP2-0804: Procedure created with compilation warnings
SQL> show errors
Errors for PROCEDURE TEST_PROC:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/1 PLW-05018: unit TEST_PROC omitted optional AUTHID clause;
default value DEFINER used
6/6 PLW-06009: procedure "TEST_PROC" OTHERS handler does not end in
RAISE or RAISE_APPLICATION_ERROR
簡單解釋一下原因,就是因為在pl/sql的執行中,打個比方,有兩個Insert子句。
insert into t values(1);
insert into t values(2);
在pl/sql中是這樣執行的
savepoint insert_point1;
insert into t values(1);
if error then rollback to insert_point1;
savepoint insert_point2;
insert into t values(2);
if error then rollback to insert_point2;
這個步驟就相當於在一個事物中,每一個原子操作如果失敗,都會在錯誤處理中進行rollback;
但是如果你在資料處理中,已經顯式做了事物提交,那麼你在錯誤處理的時候再rollback就晚了,前一部分已經提交了。
這個情景就類似下面的場景
insert into t values(1);
commit;
insert into t values('xxxxx'); --這個語句會報錯
那麼在整個事物的處理中第一部分已經提交了,第二部分出錯了也沒辦法做回滾了。
在when others 中加入了rollback也無濟於事。
可能大家在更多的錯誤處理中都是簡單把錯誤資訊列印出來而已,這樣的處理結果相當於你重寫了錯誤的處理方法,
下面隱式的錯誤處理就被覆蓋了,除非你定義了合理的錯誤處理場景,使用raise或者raise_application_error對錯誤做了正確的處理。
if error then rollback to insert_point1;
if error then rollback to insert_point2;
所以在錯誤的處理中還是建議不要使用when others 子句。這種籠統的錯誤處理可能更多的時候會造成資料的不一致。
如果一定想要使用when others then
可以採用類似下面的形式。
begin
savepoint sp;
process;--這個部分就是具體的處理程式碼
exception
when others then
rollback to sp;
dbms_output.put_line('Error,||sqlerrm);
end;
/
這樣即使程式碼中的某一部分出現異常,也能保證整個事物是一個原子操作。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1347005/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PL SQL異常處理.SQL
- PL/SQL異常處理初步(轉)SQL
- (轉)pl/sql開發異常處理SQL
- 異常錯誤資訊處理
- Oracle異常錯誤處理Oracle
- ORACLE 異常錯誤處理Oracle
- pl/sql 異常處理的概念和術語SQL
- PHP錯誤處理和異常處理PHP
- 深入探討Java中的異常與錯誤處理Java
- Python錯誤處理和異常處理(二)Python
- php錯誤與異常處理方法PHP
- goang 錯誤&異常處理機制Go
- C++錯誤和異常處理C++
- Laravel Exceptions——異常與錯誤處理LaravelException
- 總結:整理 oracle異常錯誤處理 .Oracle
- PHP系列(七)PHP錯誤異常處理PHP
- Oracle PL/SQL語言初級教程之異常處理OracleSQL
- 在vue使用異常處理做錯誤提示Vue
- .NET----錯誤和異常處理機制
- 前端錯誤收集以及統一異常處理前端
- PHP異常、錯誤處理機制筆記PHP筆記
- 在大型軟體專案中如何處理錯誤和異常
- Python之錯誤異常和檔案處理Python
- PL/SQL 08 異常 exceptionSQLException
- 自定義PL/SQL異常SQL
- Swift 中的錯誤與異常Swift
- PHP 核心知識點(一)異常和錯誤處理PHP
- thinkphp原始碼分析(四)—錯誤及異常處理篇PHP原始碼
- Java基礎知識:通過異常處理錯誤Java
- SQL Server 連線常見錯誤及其處理方法SQLServer
- pl/sql程式碼中不得犯的錯誤!SQL
- SQL Server 異常程式碼處理SQLServer
- Python 中的異常處理Python
- React 16 中的異常處理React
- Ruby中的TypeError異常處理Error
- 異常的處理
- 異常篇——異常處理
- 異常-throws的方式處理異常