Oracle異常錯誤處理
一、ORACLE 提供異常情況(EXCEPTION)和異常處理(EXCEPTION HANDLER)來實現錯誤處理。
1.異常處理的概念。
異常情況處理(EXCEPTION
)是用來處理正常執行過程中未預料的事件,程式塊的異常處理預定義的錯誤和自定義錯誤,由於PL/SQL程式塊一旦產生異常而沒有指出如何處理時,程式就會自動終止整個程式執行.
2.異常處理的型別。
預定義 ( Predefined )錯誤:ORACLE預定義的異常情況大約有24個。對這種異常情況的處理,無需在程式中定義,由ORACLE自動將其引發。
非預定義 ( Predefined
)錯誤:即其他標準的ORACLE錯誤。對這種異常情況的處理,需要使用者在程式中定義,然後由ORACLE自動將其引發。
使用者定義(User_define) 錯誤:程式執行過程中,出現程式設計人員認為的非正常情況。對這種異常情況的處理,需要使用者在程式中定義,然後顯式地在程式中將其引發。
3.異常處理的語句。
異常處理部分一般放在 PL/SQL 程式體的後半部,結構為:
EXCEPTION
WHEN first_exception THEN <code to handle first exception >
WHEN second_exception THEN <code to handle second exception >
WHEN OTHERS THEN <code to handle others exception >
END;
4.列出24個預定義的異常處理。
錯誤號 | 異常錯誤資訊名稱 | 說明 |
---|---|---|
ORA-0001 | Dup_val_on_index | 違反了唯一性限制 |
ORA-0051 | Timeout-on-resource | 在等待資源時發生超時 |
ORA-0061 | Transaction-backed-out | 由於發生死鎖事務被撤消 |
ORA-1001 | Invalid-CURSOR | 試圖使用一個無效的遊標 |
ORA-1012 | Not-logged-on | 沒有連線到ORACLE |
ORA-1017 | Login-denied | 無效的使用者名稱/口令 |
ORA-1403 | No_data_found | SELECT INTO沒有找到資料 |
ORA-1422 | Too_many_rows | SELECT INTO 返回多行 |
ORA-1476 | Zero-divide | 試圖被零除 |
ORA-1722 | Invalid-NUMBER | 轉換一個數字失敗 |
ORA-6500 | Storage-error | 記憶體不夠引發的內部錯誤 |
ORA-6501 | Program-error | 內部錯誤 |
ORA-6502 | Value-error | 轉換或截斷錯誤 |
ORA-6504 | Rowtype-mismatch | 宿主遊標變數與 PL/SQL變數有不相容行型別 |
ORA-6511 | CURSOR-already-OPEN | 試圖開啟一個已處於開啟狀態的遊標 |
ORA-6530 | Access-INTO-null | 試圖為null 物件的屬性賦值 |
ORA-6531 | Collection-is-null | 試圖將Exists 以外的集合( collection)方法應用於一個null pl/sql 表上或varray上 |
ORA-6532 | Subscript-outside-limit | 對巢狀或varray索引得引用超出宣告範圍以外 |
ORA-6533 | Subscript-beyond-count | 對巢狀或varray 索引得引用大於集合中元素的個數. |
二、三種異常的處理的基本介紹和語法。
假如例項表如下:
-- Create table
create table G_TEST_SAL
(
sid NUMBER,
sname CHAR(5),
salary BINARY_FLOAT,
time TIMESTAMP(6)
)
tablespace TBS_RPT
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
-- 插入資料
insert into G_Test_SAL values(1,'gal1',3000,to_timestamp('2000-1-1 0:0:0.0', 'syyyy-mm-dd hh24:mi:ss.ff'));
insert into G_Test_SAL values(2,'gal2',3050,to_timestamp('2000-1-1 0:0:0.0', 'syyyy-mm-dd hh24:mi:ss.ff'));
commit;
1. 預定義的異常處理。
預定義的異常情況的處理,只需在PL/SQL塊的異常處理部分,直接引用相應的異常情況名,並對其完成相應的異常錯誤處理即可。
----異常處理
---例1:更新指定員工工資,如工資小於1500,則加100;
DECLARE
v_empno G_Test_SAL.Sid%TYPE := &empno; ----%TYpe 此句的含義是定義一個變數v_empno,變數型別為G_Test_SAL.Sid的欄位型別,而且一旦G_Test_SAL.Sid型別變化,v_empno的型別也變化
----:= 是賦值的含義
----&的含義是empno變數由外部手動錄入
v_sal G_Test_SAL.Salary%TYPE;
BEGIN
SELECT Salary INTO v_sal FROM G_Test_SAL WHERE Sid = v_empno; -- select into
IF v_sal<=1500 THEN
UPDATE G_Test_SAL SET Salary = Salary + 100 WHERE Sid=v_empno;
DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'員工工資已更新!'); --||字串連線符
ELSE
DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'員工工資已經超過規定值!');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('資料庫中沒有編碼為'||v_empno||'的員工');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('程式執行錯誤!請使用遊標');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
執行上面的語句,並輸入異常empno
如下圖:
2. 非預定義的異常處理。
對於這類異常情況的處理,首先必須對非定義的ORACLE錯誤進行定義。步驟如下:
- 在PL/SQL 塊的定義部分定義異常情況:
<異常情況> EXCEPTION;
- 將其定義好的異常情況,與標準的ORACLE錯誤聯絡起來,使用
EXCEPTION_INIT
語句:
PRAGMA EXCEPTION_INIT(<異常情況>, <錯誤程式碼>);
- 在PL/SQL 塊的異常情況處理部分對異常情況做出相應的處理。
--非預定義異常處理
--例2:刪除指定員工的記錄資訊
DECLARE
v_empno G_Test_SAL.Sid%TYPE := &empno;
empno_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT(empno_remaining, -2292);
/* -2292 是違反一致性約束的錯誤程式碼 */
BEGIN
DELETE FROM G_Test_SAL WHERE Sid = v_empno;
EXCEPTION
WHEN empno_remaining THEN
DBMS_OUTPUT.PUT_LINE('違反資料完整性約束!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
3.使用者自定義的異常處理
當與一個異常錯誤相關的錯誤出現時,就會隱含觸發該異常錯誤。使用者定義的異常錯誤是通過顯式使用 RAISE 語句來觸發。當引發一個異常錯誤時,控制就轉向到 EXCEPTION
塊異常錯誤部分,執行錯誤處理程式碼。
對於這類異常情況的處理,步驟如下:
1. 在PL/SQL 塊的定義部分定義異常情況:
<異常情況> EXCEPTION;
2. RAISE <異常情況>;
3. 在PL/SQL 塊的異常情況處理部分對異常情況做出相應的處理。
---------------------------自定義的異常處理--------------------------------
--例3:更新指定員工工資,增加100;
DECLARE
v_empno employees.employee_id%TYPE :=&empno;
no_result EXCEPTION;
BEGIN
UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;
IF SQL%NOTFOUND THEN -----------SQL%NOTFOUND 是一個布林值。與最近的sql語句(update,insert,delete,select)發生互動,當最近的一條sql語句沒有涉及任何行的時候,則返回true。否則返回false。
RAISE no_result;
END IF;
EXCEPTION
WHEN no_result THEN
DBMS_OUTPUT.PUT_LINE('你的資料更新語句失敗了!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'---'||SQLERRM);
END;
三、在 PL/SQL 中使用 SQLCODE, SQLERRM異常處理函式。
SQLCODE
返回遇到的Oracle錯誤號。
SQLERRM
返回遇到的Oracle錯誤資訊.
目前專案中遇到的各種處理資訊,我們都放在了一張日誌表中。
1.第一種直接寫入日誌表。
-------------------第一種-----------------------------
----日誌表:
R_SQLRunLog(err_time char(19),err_code number,err_msg varchar2(200),info varchar2(200))
----異常處理:
WHEN OTHERS THEN
v_ErrCode = SQLCODE
v_ErrTxt = SUBSTR(SQLERRM,1,200);
INSERT INTO R_SqlRunLog(err_time,err_code,err_msg,info)
values(to_char(sysdate,'yyyy-mm-dd HH24:MI:SS'),v_ErrCode,v_ErrTxt,'使用者加入儲存過程或函式名稱');
2.第二種呼叫儲存過程,當我們每次執行一個操作的時候,都會呼叫此過程來將錯誤資訊新增到一個日誌表中。
--------------------------------第二種---------------------------------------------
CREATE OR REPLACE PROCEDURE PETL.P_ETL_LOG_WRT
(v_txdate IN VARCHAR2,
v_serialno IN NUMBER,
v_stepnum IN NUMBER,
v_dealtype IN VARCHAR2,
v_dealtab IN VARCHAR2,
v_errcode IN NUMBER,
v_errstate IN VARCHAR2,
v_rcount IN NUMBER,
v_dealprc IN VARCHAR2) AS
----------------------------------------------------------------------------------------
-- 名 稱:日誌記錄儲存過程
-- 功能說明:記錄日誌
-- 源表資訊:
-- 目 標 表:PETL.ETL_JOB_LOG
-- 建立資訊:
-- 修改項1 :
-- 修改項2 :
----------------------------------------------------------------------------------------
BEGIN
INSERT INTO PETL.ETL_JOB_LOG VALUES(v_txdate,v_serialno,v_stepnum,v_dealtype,v_dealtab,TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS'),v_errcode,v_errstate,v_rcount,0,v_dealprc);
COMMIT;
END;
相關文章
- ORACLE 異常錯誤處理Oracle
- 異常錯誤資訊處理
- Python錯誤處理和異常處理(二)Python
- rust學習十、異常處理(錯誤處理)Rust
- C++錯誤和異常處理C++
- php錯誤與異常處理方法PHP
- goang 錯誤&異常處理機制Go
- oracle異常處理Oracle
- 前端錯誤收集以及統一異常處理前端
- Python之錯誤異常和檔案處理Python
- .NET----錯誤和異常處理機制
- 在vue使用異常處理做錯誤提示Vue
- 說說你對異常處理和錯誤處理的理解
- Oracle 監聽異常處理Oracle
- thinkphp原始碼分析(四)—錯誤及異常處理篇PHP原始碼
- PHP 核心知識點(一)異常和錯誤處理PHP
- oracle常見異常等待——latch處理思路Oracle
- oracle ora-00054錯誤處理Oracle
- Oracle開發基礎-異常處理Oracle
- 在大型軟體專案中如何處理錯誤和異常
- 異常篇——異常處理
- oracle分散式事務異常處理方法Oracle分散式
- 異常處理
- SpringBoot錯誤處理機制以及自定義異常響應原理解析Spring Boot
- JSP 異常處理如何處理?JS
- PHP錯誤和異常PHP
- python錯誤與異常Python
- 異常-throws的方式處理異常
- 錯誤處理
- React 異常處理React
- JS異常處理JS
- Python——異常處理Python
- Python異常處理Python
- ThinkPHP 異常處理PHP
- JavaScript 異常處理JavaScript
- JAVA 異常處理Java
- 異常的處理
- golang - 異常處理Golang