At the end of this session, the participants will be able to:
Understand the concept of Exceptions Comprehend the difference between system and user-defined exceptions Write PL/SQL blocks to handle system and user-defined exceptions
Exception Handling - Topics What are Exceptions? System defined exceptions User defined exceptions Exception Propagation
Exception Handling in PL/SQL An exception is an identifier in PL/SQL, raised during the execution of a block that terminates its main body of actions
How an exception is raised? 1. An exception is raised implicitly if an Oracle error occurs e. g. When no rows are retrieved by SELECT statement then PL/SQL raises the exception NO_DATA_FOUND
2. We raise an exception explicitly by issuing the RAISE statement within the block
Exception Handling in PL/SQL Trapping an Exception
If the exception is raised in the executable section and there is an associated handler, the exception is trapped EXCEPTION section specifies an exception, followed by a sequence of statements OTHERS traps exceptions not handled in exception handling section
Functions for Trapping Error Code and Message SQLCODE Returns the error number
SQLERRM Returns the error message associated with a given error number Example DECLARE v_code NUMBER; v_errm varchar2(255); BEGIN . . . . . . EXCEPTION . . . . . . WHEN OTHERS THEN v_code : = SQLCODE; v_errm : = SQLERRM(SQLCODE,1,80); INSERT INTO errors VALUES(v_code, v_errm); END; Exception Handling in PL/SQL Types of Exceptions - Predefined Oracle Server Exceptions - Non-predefined Oracle Server Exceptions - User-defined Exceptions Exception
Description
Direction for Handling
Predefined Oracle Server
Approximately 20 errors that occur most often in PL/SQL code Do not declare and allow the oracle server to raise them implicitly
Non-predefined Oracle Server
Any other standard Oracle Server error
Declare within the declarative section and allow the oracle server to raise them implicitly
User-defined
A condition that the developer determines is abnormal
Declare within the declarative section and raise explicitly
Exception Handling in PL/SQL Pre-defined Exceptions - Oracle has around 20 named Pre-defined exceptions - Trapped within the Exception handling block
Pre-defined Exceptions - NO_DATA_FOUND - TOO_MANY_ROWS - INVALID_CURSOR - ZERO_DIVIDE - VALUE_ERROR Pre-define Exception Example DECLARE v_emp_rec emp%ROWTYPE; BEGIN SELECT * INTO v_emp_rec FROM emp WHERE empno=1001; DBMS_OUTPUT.PUT_LINE(Empno : || v_emp_rec.empno); DBMS_OUTPUT.PUT_LINE(Emp Name : || v_emp_rec.ename); DBMS_OUTPUT.PUT_LINE(Emp Salary : || v_emp_rec.sal); DBMS_OUTPUT.PUT_LINE(Emp Deptno : || v_emp_rec.deptno); EXCEPTION WHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE(Employee Does Not Exist); END;
Exception Handling in PL/SQL Trapping Non-predefined Oracle Server errors - Trapped by declaring it first or by using OTHERS handler - PRAGMA EXCEPTION_INIT tells the compiler to associate an exception name with an oracle error number - PRAGMA keyword that signifies that the statement is a compiler directive, which is not processed when the PL/SQL block is executed
Example DECLARE e_emp_exist EXCEPTION; --Naming non-predefined oracle error PRAGMA EXCEPTION_INIT(e_emp_exist , -2292); v_deptno dept.deptno%TYPE := &p_dno; BEGIN DELETE FROM dept WHERE deptno = v_deptno; COMMIT; EXCEPTION WHEN e_emp_exist THEN DBMS_OUTPUT.PUT_LINE(Can not delete dept Employees exist); END; Oracle Server Errors ORA-00000: normal, successful completion Cause: Normal exit. Action: None. ORA-00001: unique constraint (string.string) violated Cause: An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level. Action: Either remove the unique restriction or do not insert the key. ORA-00017: session requested to set trace event Cause: The current session was requested to set a trace event by another session. Action: This is used internally; no action is required. ORA-00018: maximum number of sessions exceeded Cause: All session state objects are in use. Action: Increase the value of the SESSIONS initialization parameter. Oracle Server Errors ORA-00019: maximum number of session licenses exceeded Cause: All licenses are in use. Action: Increase the value of the LICENSE MAX SESSIONS initialization parameter. ORA-02286: no options specified for ALTER SEQUENCE Cause: Self-evident. Action: The statement is meaningless without any options. ORA-02287: sequence number not allowed here Cause: The specified sequence number (CURRVAL or NEXTVAL) is inappropriate here in the statement. Action: Remove the sequence number. ORA-02288: invalid OPEN mode Cause: A token other than RESETLOGS appears following ALTER DATABASE <name> OPEN. Action: Either nothing or RESETLOGS should be placed following OPEN.
Oracle Server Errors ORA-02289: sequence does not exist Cause: The specified sequence does not exist, or the user does not have the required privilege to perform this operation. Action: Make sure the sequence name is correct, and that you have the right to perform the desired operation on this sequence. ORA-02290: check constraint (string.string) violated Cause: The values being inserted do not satisfy the named check constraint. Action: do not insert values that violate the constraint. ORA-02291: integrity constraint (string.string) violated - parent key not found Cause: A foreign key value has no matching primary key value. Action: Delete the foreign key or add a matching primary key. ORA-02292: integrity constraint (string.string) violated - child record found Cause: attempted to delete a parent key value that had a foreign key dependency. Action: delete dependencies first then parent or disable constraint. ORA-02293: cannot validate (string.string) - check constraint violated Cause: an alter table operation tried to validate a check constraint to a populated table that had nocomplying values. Action: Obvious
Exception Handling in PL/SQL User-defined Exceptions - Declared in the Declare Section with type as EXCEPTION - Raised Explicitly by using RAISE keyword - Handled in the Exception Section - Local to a PL/SQL block
DECLARE
RAISE
REFERENCE Declarative Section Executable Section Exception Handling Section Example DECLARE -- Declaring user defined exception e_invalid_product EXCEPTION; BEGIN UPDATE product SET descrip = &prod_desc WHERE prod_id = &prod_no; IF SQL%NOTFOUND THEN --Raising user defined exception RAISE e_invalid_product END IF; COMMIT; EXCEPTION --Handling user defined exception WHEN e_invalid_product THEN DBMS_OUTPUT.PUT_LINE(Invalid Product Number); END; RAISE_APPLICATION_ERROR To display your own error messages one can use the built-in RAISE_APPLICATION_ERROR. They display the error message in the same way as Oracle errors. You should use a negative number between 20000 to 20999 for the errornumber The error message should not exceed 512 characters.
Example BEGIN DBMS_OUTPUT.PUT_LINE(Enter Your Name :: ); str:=&NAME; IF LENGTH(str) < 2 THEN RAISE_APPLICATION_ERROR(-20888, What a Funny Name You have); ELSE RAISE_APPLICATION_ERROR(-20222, What a Lovely Name); END IF; END;
Enter value for name : LARRY Old 5: str:=&NAME; New 5: str:=LARRY;
ERROR at Line 1: ORA-20222: What a Lovely Name ORA-06512: at line 9 Exception Propagation Exceptions Raised in the Executable Section PL/SQL uses the following rule to determine which exception handler to invoke: 1. Current block has a handler for the exception, execute it and complete the block successfully. Control then passes to the enclosing block.
2. No handler for current exception, propagate the exception by raising it in the enclosing block. Step 1 is executed for the enclosing block. If there is no enclosing block, the exception will be propagated out to the calling environment, such as SQL* Plus. Exceptions Raised in the Executable Section: Example 1
DECLARE A EXCEPTION; BEGIN BEGIN RAISE A; EXCEPTION WHEN A THEN . . . END; END; Exception A is raised in the inner block A is handled in the inner block Control resumes here Exceptions Raised in the Executable Section: Example 2
DECLARE A EXCEPTION; B EXCEPTION; BEGIN BEGIN RAISE B; EXCEPTION WHEN A THEN . . . END; EXCEPTION WHEN B THEN . . . END; Exception B is raised in the inner block No handler for exception B in the inner block Exception B is propagated to the enclosing block and handle there Control then passes out of enclosing block, which completes successfully Exceptions Raised in Declarative Section: Example 1
DECLARE v_number NUMBER(3):=ABC; BEGIN . . . EXCEPTION WHEN OTHERS THEN . . . END; Illegal assignment raises VALUE_ERROR Even though there is a WHEN OTHERS handler, it is not executed The block completes unsuccessfully with the VALUE_ERROR exception Exceptions Raised in Declarative Section: Example 2 BEGIN DECLARE v_number NUMBER(3):=ABC; BEGIN . . . EXCEPTION WHEN OTHERS THEN . . . END; EXCEPTION WHEN OTHERS THEN . . . END; Illegal assignment raises VALUE_ERROR Even though there is an OTHERS handler for the inner block, it is not executed The exception handler in the outer block handles the exception Control then passes out of enclosing block which completes successfully Exceptions Raised in Exception Section: Example 1
DECLARE A EXCEPTION; B EXCEPTION; BEGIN RAISE A; EXCEPTION WHEN A THEN RAISE B; WHEN B THEN . . . END; Exception A is raised Exception A is handled and B is raised in As handler Even though there is a handler for B here, it is not executed. The exception is propagated out of the block The block completes unsuccessfully with unhandled exception B Exception Handling The biggest advantage of exception handling is it improves readability and reliability of the code. Errors from many statements of code can be handles with a single handler. Instead of checking for an error at every point we can just add an exception handler and if any exception is raised it is handled by that. For checking errors at a specific spot it is always better to have those statements in a separate begin end block.
Points To Ponder:
An Exception cannot be declared twice in the same block. Exceptions declared in a block are considered as local to that block and global to its sub-blocks. An enclosing block cannot access Exceptions declared in its sub-block. Where as it possible for a sub-block to refer its enclosing Exceptions.
Summary We have discussed,
Terms : Exceptions and Exception handling Predefined exceptions User defined exceptions Exception Propagation