Lab 10.2 User-Defined Exceptions


Lab 10.2 User -Defined Exceptions

Lab Objective

After this Lab, you will be able to:

Use User-Defined Exceptions


Often in your programs you may need to handle problems that are specific to the program you write. For example, your program asks a user to enter a value for student_id. This value is then assigned to the variable v_student_id that is used later in the program. Generally, you want a positive number for an id. By mistake, the user enters a negative number. However, no error has occurred because student_id has been defined as a number, and the user has supplied a legitimate numeric value. Therefore, you may want to implement your own exception to handle this situation.

This type of an exception is called a user-defined exception because it is defined by the programmer. As a result, before the exception can be used, it must be declared. A user-defined exception is declared in the declarative part of a PL/SQL block as shown:

 
 DECLARE  exception_name  EXCEPTION; 

Notice that this declaration looks similar to a variable declaration. You specify an exception name followed by the keyword EXCEPTION. Consider the following code fragment.

FOR EXAMPLE

 
 DECLARE    e_invalid_id EXCEPTION; 

In the example, the name of the exception is prefixed by the letter "e." This is not a required syntax; rather, it allows you to differentiate between variable names and exception names .

Once an exception has been declared, the executable statements associated with this exception are specified in the exception-handling section of the block. The format of the exception-handling section is the same as for built-in exceptions. Consider the following code fragment.

FOR EXAMPLE

 
 DECLARE    e_invalid_id EXCEPTION; BEGIN    ... EXCEPTION    WHEN e_invalid_id THEN       DBMS_OUTPUT.PUT_LINE ('An id cannot be negative'); END; 

You already know that built-in exceptions are raised implicitly. In other words, when a certain error occurs, a built-in exception associated with this error is raised. Of course, you are assuming that you have included this exception in the exception-handling section of your program. For example, a TOO_MANY_ROWS exception is raised when a SELECT INTO statement returns multiple rows. Next , you will explore how a user-defined exception is raised.

A user-defined exception must be raised explicitly. In other words, you need to specify in your program under which circumstances an exception must be raised, as shown:

 
 DECLARE    exception_name EXCEPTION; BEGIN    ...    IF  CONDITION  THEN       RAISE exception_name;    ELSE       ...    END IF; EXCEPTION    WHEN exception_name THEN       ERROR-PROCESSING STATEMENTS; END; 

In the structure just shown, the circumstances under which a user-defined exception must be raised are determined with the help of the IF-THEN-ELSE statement. If CONDITION evaluates to TRUE, a user-defined exception is raised. If CONDITION evaluates to FALSE, the program proceeds with its normal execution. In other words, the statements associated with the ELSE part of the IF-THEN-ELSE statement are executed. Any form of the IF statement can be used to check when a user-defined exception must be raised.

In the next modified version of the earlier example used in this lab, you will see that the exception e_invalid_id is raised when a negative number is entered for the variable v_student_id .

FOR EXAMPLE

 
 DECLARE    v_student_id STUDENT.STUDENT_ID%TYPE := &sv_student_id;    v_total_courses NUMBER;    e_invalid_id EXCEPTION; BEGIN    IF v_student_id < 0 THEN       RAISE e_invalid_id;    ELSE       SELECT COUNT(*)         INTO v_total_courses         FROM enrollment        WHERE student_id = v_student_id;       DBMS_OUTPUT.PUT_LINE ('The student is registered for          'v_total_courses' courses');    END IF;    DBMS_OUTPUT.PUT_LINE ('No exception has been raised'); EXCEPTION    WHEN e_invalid_id THEN       DBMS_OUTPUT.PUT_LINE ('An id cannot be negative'); END; 

In this example, the exception e_invalid_id is raised with the help of IF-THEN-ELSE statement. Once a user supplies a value for the v_student_id , the sign of this numeric value is checked. If the value is less than zero, the IF-THEN-ELSE statement evaluates to TRUE, and the exception e_invalid_id is raised. Therefore, the control transfers to the exception-handling section of the block. Next, statements associated with this exception are executed. In this case, the message "An id cannot be negative" is displayed on the screen. If the value entered for the v_student_id is positive, the IF-THEN-ELSE statement yields FALSE, and the ELSE part of the IF-THEN-ELSE statement is executed.

Run this example for two values of v_student_id : 102 and “102.

A first run of the example (student ID is 102) produces the output shown:

 
  Enter value for sv_student_id: 102   old   2:    v_student_id STUDENT.STUDENT_ID%TYPE := &sv_student_id;   new   2:    v_student_id STUDENT.STUDENT_ID%TYPE := 102;   The student is registered for 2 courses   No exception has been raised   PL/SQL procedure successfully completed.  

For this run, you entered a positive value for the variable v_student_id . As a result, the IF-THEN-ELSE statement evaluates to FALSE, and the ELSE part of the statement executes. The SELECT INTO statement determines how many records are in the ENROLLMENT table for a given student_id. Next, the message "The student is registered for 2 courses" statement is displayed on the screen. At this point, the IF-THEN-ELSE statement is complete. So the control is transferred to the DBMS_OUTPUT.PUT_LINE statement that follows END IF. As a result, another message is displayed on the screen.

A second run of the example (student ID is -102) produces the following output:

 
  Enter value for sv_student_id: -102   old   2:    v_student_id STUDENT.STUDENT_ID%TYPE := &sv_student_id;   new   2:    v_student_id STUDENT.STUDENT_ID%TYPE := -102;   An id cannot be negative   PL/SQL procedure successfully completed.  

For the second run, a negative value was entered for the variable v_student_id . The IF-THEN-ELSE statement evaluates to TRUE, and the exception e_invalid_id is raised. As a result, control is transferred to the exception-handling section of the block, and the error message "An id cannot be negative" is displayed on the screen.

graphics/trick_icon.gif

It is important for you to note that the RAISE statement must be used in conjunction with an IF statement. Otherwise, control of the execution will be transferred to the exception-handling section of the block for every single execution. Consider the following example:

 
 DECLARE    e_test_exception EXCEPTION; BEGIN    DBMS_OUTPUT.PUT_LINE ('Exception has not been raised');    RAISE e_test_exception;    DBMS_OUTPUT.PUT_LINE ('Exception has been raised'); EXCEPTION    WHEN e_test_exception THEN       DBMS_OUTPUT.PUT_LINE ('An error has occurred'); END; 

Every time this example is run, the following output is produced:

 
  Exception has not been raised   An error has occurred   PL/SQL procedure successfully completed.  

Even though no error has occurred, control is transferred to the exception-handling section. It is important for you to check to see if the error has occurred before raising the exception associated with that error.


Just like for built-in exceptions, the same scope rules apply to user-defined exceptions. An exception declared in the inner block must be raised in the inner block and defined in the exception-handling section of the inner block. Consider the following example.

FOR EXAMPLE

 
 -- outer block BEGIN    DBMS_OUTPUT.PUT_LINE ('Outer block');    -- inner block    DECLARE       e_my_exception EXCEPTION;    BEGIN       DBMS_OUTPUT.PUT_LINE ('Inner block');    EXCEPTION       WHEN e_my_exception THEN          DBMS_OUTPUT.PUT_LINE ('An error has occurred');    END;    IF 10 > &sv_number THEN       RAISE e_my_exception;    END IF; END; 

In this example, the exception, e_my_exception , has been declared in the inner block. However, you are trying to raise this exception in the outer block. This example causes a syntax error because the exception declared in the inner block ceases to exists once the inner block terminates. As a result, this example produces the following output:

 
  Enter value for sv_number: 11   old  12:    IF 10 > &sv_number THEN   new  12:    IF 10 > 11 THEN   RAISE e_my_exception;   *   ERROR at line 13:   ORA-06550: line 13, column 13:   PLS-00201: identifier 'E_MY_EXCEPTION' must be declared   ORA-06550: line 13, column 7:   PL/SQL: Statement ignored  

Notice that the error message

 
  PLS-00201: identifier 'E_MY_EXCEPTION' must be declared  

is the same error message you get when trying to use a variable that has not been declared.



Oracle PL[s]SQL by Example
Oracle PL[s]SQL by Example
ISBN: 3642256902
EAN: N/A
Year: 2003
Pages: 289

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net