看一例子就知道了
FUNCTION company_name
(id_in IN NUMBER, access_type_in IN VARCHAR2)
RETURN VARCHAR2
IS
/* Return value of the function */
return_value VARCHAR2 (60);
/* Our own exception - used to represent bad data NO_DATA_FOUND. */
bad_data_in_select EXCEPTION;
BEGIN
/* Retrieve company name from the database */
IF access_type_in = 'DBMS'
THEN
/* Place the SELECT inside its own BEGIN-END. */
BEGIN
SELECT name INTO return_value
FROM company
WHERE company_id = id_in;
RETURN return_value;
/* Now it can have its OWN exception section too ! */
EXCEPTION
/* This NO_DATA_FOUND is only from the SELECT. */
WHEN NO_DATA_FOUND
THEN
/*
|| Raise my exception to propagate to
|| the main body of the function.
*/
RAISE bad_data_in_select;
END;
/* Retrieve company name from an in-memory PL/SQL table */
ELSIF access_type_in = 'MEMORY'
THEN
/*
|| Direct access from table. If this ID is not defined
|| then the NO_DATA_FOUND exception is raised.
*/
RETURN company_name_table (id_in);
END IF;
EXCEPTION
/*
|| This exception occurs only when NO_DATA_FOUND was raised by
|| the implicit cursor inside its own BEGIN-END.
*/
WHEN bad_data_in_select
THEN
DBMS_OUTPUT.PUT_LINE
(' Unable to locate company in database!');
/*
|| This exception occurs only when we have not previously placed
|| the company name for company id id_in in the table.
*/
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE
(' Unable to locate company in memorized table!');
END;
概念和其它語言裡面是一致的。
一個例子:
DECLARE
v_ErrorCode NUMBER; -- Code for the error
v_ErrorMsg VARCHAR2(200); -- Message text for the error
v_CurrentUser VARCHAR2(8); -- Current database user
v_Information VARCHAR2(100); -- Information about the error
BEGIN
/* Code which processes some data here */
NULL;
EXCEPTION
WHEN OTHERS THEN
-- Assign values to the log variables, using built-in
-- functions.
v_ErrorCode := SQLCODE;
v_ErrorMsg := SQLERRM;
v_CurrentUser := USER;
v_Information := 'Error encountered on ' ||
TO_CHAR(SYSDATE) || ' by database user ' || v_CurrentUser;
-- Insert the log message into log_table.
INSERT INTO log_table (code, message, info)
VALUES (v_ErrorCode, v_ErrorMsg, v_Information);
END;
/
BEGIN
DECLARE
Insufficient_credite EXCEPTION;
BEGIN
RASISE Insufficient_credite;
EXCEPTION
WHEN Insufficient_credite THEN
--可以在此处理异常
extend_credite(cust_id);
END -嵌套块结束
EXCEPTION
WHEN Insufficient_credite THEN
--超出范围,不能在这里处理异常
END;
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;
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 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;--内部块结束