Exception Handling in PL/SQL

An exception is an error which disrupts the normal flow of program instructions. PL/SQL provides us the exception block which raises the exception thus helping the programmer to find out the fault and resolve it.

There are two types of exceptions defined in PL/SQL

  1. User defined exception.
  2. System defined exceptions.

Syntax to write an exception



WHEN exception THEN 
    statement;

DECLARE
declarations section;

BEGIN
executable command(s);

EXCEPTION
WHEN exception1 THEN
statement1;
WHEN exception2 THEN
statement2;
[WHEN others THEN]
/* default exception handling code */

END;

Note:
When other keyword should be used only at the end of the exception handling block as no exception handling part present later will get executed as the control will exit from the block after executing the WHEN OTHERS.

  1. System defined exceptions:
    These exceptions are predefined in PL/SQL which get raised WHEN certain database rule is violated.
    System-defined exceptions are further divided into two categories:

    1. Named system exceptions.
    2. Unnamed system exceptions.

    • Named system exceptions: They have a predefined name by the system like ACCESS_INTO_NULL, DUP_VAL_ON_INDEX, LOGIN_DENIED etc. the list is quite big.

      So we will discuss some of the most commonly used exceptions:

      Lets create a table geeks.


      create table geeks(g_id int , g_name varchar(20), marks int); 
      insert into geeks values(1, 'Suraj',100);
      insert into geeks values(2, 'Praveen',97);
      insert into geeks values(3, 'Jessie', 99);
      

      1. NO_DATA_FOUND: It is raised WHEN a SELECT INTO statement returns no rows. For eg:
        filter_none

        edit
        close

        play_arrow

        link
        brightness_4
        code

        DECLARE
           temp varchar(20);
          
        BEGIN
           SELECT g_id into temp from geeks where g_name='GeeksforGeeks';
          
        exception
           WHEN no_data_found THEN
              dbms_output.put_line('ERROR');
              dbms_output.put_line('there is no name as');
              dbms_output.put_line('GeeksforGeeks in geeks table');
        end;

        chevron_right

        
        

        Output:

        ERROR
        there is no name as GeeksforGeeks in geeks table
        
      2. TOO_MANY_ROWS:It is raised WHEN a SELECT INTO statement returns more than one row.
        filter_none

        edit
        close

        play_arrow

        link
        brightness_4
        code

        DECLARE
           temp varchar(20);
          
        BEGIN
          
        -- raises an exception as SELECT 
        -- into trying to return too many rows
           SELECT g_name into temp from geeks;
           dbms_output.put_line(temp);
          
        EXCEPTION
           WHEN too_many_rows THEN
              dbms_output.put_line('error trying to SELECT too many rows');
          
        end;

        chevron_right

        
        

        Output:

        error trying to SELECT too many rows
        
      3. VALUE_ERROR:This error is raised WHEN a statement is executed that resulted in an arithmetic, numeric, string, conversion, or constraint error. This error mainly results from programmer error or invalid data input.
        filter_none

        edit
        close

        play_arrow

        link
        brightness_4
        code

        DECLARE
           temp number;   
          
        BEGIN
           SELECT g_name  into temp from geeks where g_name='Suraj';
           dbms_output.put_line('the g_name is '||temp);
          
        EXCEPTION
           WHEN value_error THEN
           dbms_output.put_line('Error');
           dbms_output.put_line('Change data type of temp to varchar(20)');
          
        END;

        chevron_right

        
        

        Output:

        Error
        Change data type of temp to varchar(20)
        
      4. ZERO_DIVIDE = raises exception WHEN dividing with zero.
        filter_none

        edit
        close

        play_arrow

        link
        brightness_4
        code

        DECLARE
           a int:=10;
           b int:=0;
           answer int;
          
        BEGIN
           answer:=a/b;
           dbms_output.put_line('the result after division is'||answer);
          
        exception
           WHEN zero_divide THEN
              dbms_output.put_line('dividing by zero please check the values again');
              dbms_output.put_line('the value of a is '||a);
              dbms_output.put_line('the value of b is '||b);
        END;

        chevron_right

        
        

        Output:

        dividing by zero please check the values again
        the value of a is 10
        the value of b is 0
        

    • Unnamed system exceptions:Oracle doesn’t provide name for some system exceptions called unnamed system exceptions.These exceptions don’t occur frequently.These exceptions have two parts code and an associated message.
      The way to handle to these exceptions is to assign name to them using Pragma EXCEPTION_INIT
      Syntax:

      PRAGMA EXCEPTION_INIT(exception_name, -error_number);
      

      error_number are pre-defined and have negative integer range from -20000 to -20999.

      Example:


      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      DECLARE
         exp exception;
         pragma exception_init (exp, -20015);
         n int:=10;
        
      BEGIN 
         FOR i IN 1..n LOOP
            dbms_output.put_line(i*i);
               IF i*i=36 THEN
                  RAISE exp;
               END IF;
         END LOOP;
        
      EXCEPTION
         WHEN exp THEN
            dbms_output.put_line('Welcome to GeeksforGeeks');
        
      END;

      chevron_right

      
      

      Output:

      1
      4
      9
      16
      25
      36
      Welcome to GeeksforGeeks
      






  2. User defined exceptions:
    This type of users can create their own exceptions according to the need and to raise these exceptions explicitly raise command is used.

    Example:

    • Divide non-negative integer x by y such that the result is greater than or equal to 1.

      From the given question we can conclude that there exist two exceptions

      • Division be zero.
      • If result is greater than or equal to 1 means y is less than or equal to x.
      filter_none

      edit
      close

      play_arrow

      link
      brightness_4
      code

      DECLARE
         x int:=&x; /*taking value at run time*/
         y int:=&y;
         div_r float;
         exp1 EXCEPTION;
         exp2 EXCEPTION;
        
      BEGIN
         IF y=0 then
             raise exp1;
        
         ELSEIF y > x then
            raise exp2;
        
         ELSE
            div_r:= x / y;
            dbms_output.put_line('the result is '||div_r);
        
         END IF;
        
      EXCEPTION
         WHEN exp1 THEN
            dbms_output.put_line('Error');
            dbms_output.put_line('division by zero not allowed');
        
         WHEN exp2 THEN
            dbms_output.put_line('Error');
            dbms_output.put_line('y is greater than x please check the input');
        
      END;

      chevron_right

      
      

      Input 1: x = 20
               y = 10
      
      Output: the result is 2
      
      Input 2: x = 20
               y = 0
      
      Output:
      Error
      division by zero not allowed
      
      Input 3: x=20
               y = 30
      
      Output:<.em>
      Error
      y is greater than x please check the input
      


    RAISE_APPLICATION_ERROR:
    It is used to display user-defined error messages with error number whose range is in between -20000 and -20999. When RAISE_APPLICATION_ERROR executes it returns error message and error code which looks same as Oracle built-in error.

    Example:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    DECLARE
        myex EXCEPTION;
        n NUMBER :=10;
      
    BEGIN
        FOR i IN 1..n LOOP
        dbms_output.put_line(i*i);
            IF i*i=36 THEN
            RAISE myex;
            END IF;
        END LOOP;
      
    EXCEPTION
        WHEN myex THEN
            RAISE_APPLICATION_ERROR(-20015, 'Welcome to GeeksForGeeks');
      
    END;

    chevron_right

    
    

    Output:

    Error report:
    ORA-20015: Welcome to GeeksForGeeks
    ORA-06512: at line 13
    
    1
    4
    9
    16
    25
    36
    
    
    

    Note: The output is based on Oracle Sql developer, the output order might change IF you’re running this code somewhere else.


    Scope rules in exception handling:

    1. We can’t DECLARE an exception twice but we can DECLARE the same exception in two dIFferent blocks.
    2. Exceptions DECLAREd inside a block are local to that block and global to all its sub-blocks.

    As a block can reference only local or global exceptions, enclosing blocks cannot reference exceptions DECLAREd in a sub-block.
    If we reDECLARE a global exception in a sub-block, the local declaration prevails i.e. the scope of local is more.

    Example:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    DECLARE
       GeeksforGeeks EXCEPTION;
       age NUMBER:=16;
    BEGIN
      
       --  sub-block BEGINs 
       DECLARE       
            
          -- this declaration prevails 
          GeeksforGeeks  EXCEPTION;  
          age NUMBER:=22;
        
       BEGIN
          IF age > 16 THEN
             RAISE GeeksforGeeks; /* this is not handled*/
          END IF;
         
       END;          
       -- sub-block ends
      
    EXCEPTION
      -- Does not handle raised exception 
      WHEN GeeksforGeeks THEN
        DBMS_OUTPUT.PUT_LINE
          ('Handling  GeeksforGeeks exception.');
        
      WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE
          ('Could not recognize exception GeeksforGeeks  in this scope.');
    END;

    chevron_right

    
    

    Output:

    Could not recognize exception GeeksforGeeks  in this scope.
    

Advantages:

  • Exception handling is very useful for error handling, without it we have to issue the command at every point to check for execution errors:
    Example:

    Select ..
    .. check for 'no data found' error
    Select ..
    .. check for 'no data found' error
    Select .. 
    .. check for 'no data found' error
    

    Here we can see that it is not robust as error processing is not separated from normal processing and IF we miss some line in the code than it may lead to some other kind of error.

  • With exception handling we handle errors without writing statements multiple times and we can even handle dIFferent types of errors in one exception block:
    Example:

    BEGIN
       SELECT ...
       SELECT ...
       SELECT ...
        .
        .
        .
    exception 
       WHEN NO_DATA_FOUND THEN  /* catches all 'no data found' errors */
         ...
       WHEN ZERO_DIVIDE THEN    /* different types of */
       WHEN value_error THEN    /* errors handled in same block */
       ...   
     

From above code we can conclude that exception handling

  1. Improves readability by letting us isolate error-handling routines and thus providing robustness.
  2. Provides reliability, instead of checking for dIFferent types of errors at every point we can simply write them in exception block and IF error exists exception will be raised thus helping the programmer to find out the type of error and eventually resolve it.

Uses: One of the real lIFe use of exception can be found in online train reservation system.
While filling the station code to book the ticket IF we input wrong code it shows us the exception that the code doesn’t exist in database.

Reference: You can find the list of all pre-defined exception here.
Total number of pre-defined exceptions



My Personal Notes arrow_drop_up

A polyglot and a Big Data enthusiast 専攻はコンピュータ科学です

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.