PL/SQL 異常和goto語句
異常
預定義異常
oracle常見預定義異常:
錯誤號 | 異常錯誤信息名稱 | 說明 |
---|---|---|
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 | 轉換一個數字失敗 |
OTHERS(總是寫在最后) | 其它的異常(總是放在異常處理塊的最后) |
Oracle內置有兩個與異常有關的函數
SQLCODE
返回Oracle的錯誤代碼SQLERRM
返回Oracle的錯誤消息
--使用預定義異常
declare
v_empno employee.empno%type;
rec_emp employee%rowtype;
begin
v_empno := &請輸入員工編號;
select * into rec_emp from employee;-- where empno=v_empno;
dbms_output.put_line('編號:'||rec_emp.empno||', 姓名:'||rec_emp.ename);
--異常處理
exception
when NO_DATA_FOUND then --數據未找到
dbms_output.put_line('數據未找到,原因:'||SQLCODE||','||SQLERRM);
when TOO_MANY_ROWS THEN
dbms_output.put_line('數據過多,不能給變量賦值,原因:'||SQLCODE||','||SQLERRM);
when others then
dbms_output.put_line('未知異常,原因:'||SQLCODE||','||SQLERRM);
end;
/
自定義異常
- 聲明異常: 變量名 exception;
- 拋出異常: raise 變量名;
- 處理異常:exception
--問題:如果某員工沒有獎金時拋出“無獎金異常”
declare
v_empno employee.empno%type := &請輸入編號;
rec_emp employee%rowtype;
ex_no_comm exception; --定義無獎金異常
begin
select * into rec_emp from employee where empno=v_empno;
if (rec_emp.comm is null or rec_emp.comm=0) then
raise ex_no_comm;--2. 拋出異常
end if;
--3. 異常處理
exception
when ex_no_comm then
dbms_output.put_line('無獎金異常');
end;
/
異常交給java處理(了解)
使用SQL中的函數RAISE_APPLICATION_ERROR(error_number, error_message)
即可把異常交給java處理。
java中通過try捕獲到SQLException,之后通過SQLException的getCode和getMessage方法來獲得
goto語句
--若XXX員工的工資小於獎金的 3倍,則為該員工的工資增加30%。
declare
v_empno employee.empno%type;
v_sal employee.sal%type;
v_comm employee.comm%type;
begin
v_empno := &請輸入員工編號;
select sal,comm into v_sal,v_comm from employee where empno=v_empno;
if v_sal<nvl(v_comm,0)*3 then
goto updating;
end if;
--定義標號
<<updating>>
update employee set sal=sal+sal*0.3 where empno=v_empno;
commit;
<<quit>>
null; --空語句,什么都不做
end;
/