Learning Objectives – after this chapter you will be able to:
  • Explain exceptions and write exception handlers with WHEN … THEN and WHEN OTHERS.
  • Use SQLCODE and SQLERRM and recognise the common predefined exceptions.
  • Know when NO_DATA_FOUND is not raised.
  • Declare, raise and re-raise user-defined exceptions; use PRAGMA EXCEPTION_INIT.
  • Trace exception propagation and decide whether a block succeeded or failed.
What is an Exception?

In PL/SQL, errors and warnings are called exceptions. When a predefined error occurs (division by zero → ZERO_DIVIDE, SELECT finds no row → NO_DATA_FOUND) PL/SQL raises the exception automatically. Users can also create their own exceptions. An application is not complete without exception handling.

If an exception is not handled, the block is aborted with an error message. When it is handled, control moves to the exception-handling part; after the handler runs, control goes to the next statement of the enclosing block (or back to the host if there is none).

EXCEPTION WHEN exception-1 [OR exception-2] ... THEN statements; [WHEN exception-3 ... THEN statements;] ... [WHEN OTHERS THEN statements;]
Handling NO_DATA_FOUND
declare
   v_fee courses.fee%type;
begin
   select fee into v_fee from courses where ccode = 'c';
   update courses set fee = v_fee where ccode = 'c++';
exception
   when no_data_found then          -- course C does not exist
      update courses set fee = (select avg(fee) from courses) where ccode = 'c++';
end;
SQLCODE and SQLERRM

Most Oracle errors have no predefined exception name. In WHEN OTHERS, SQLCODE returns the error number and SQLERRM the error message of the most recent error. They cannot be used directly in an SQL statement – assign them to variables first.

WHEN OTHERS with SQLERRM
declare
   newccode varchar2(5) := null;
begin
   update courses set ccode = newccode where ccode = 'c';
exception
   when dup_val_on_index then
      dbms_output.put_line('Duplicate course code');
   when others then
      dbms_output.put_line(sqlerrm);
end;
Output
ORA-01407: cannot update ("BOOK"."COURSES"."CCODE") to NULL
Predefined Exceptions
ExceptionOracle errorSQLCODERaised when
CURSOR_ALREADY_OPENORA-06511-6511Opening a cursor that is already open
DUP_VAL_ON_INDEXORA-00001-1Duplicate value in a column with a unique index
INVALID_CURSORORA-01001-1001Illegal cursor operation
INVALID_NUMBERORA-01722-1722String-to-number conversion fails in an SQL statement
LOGIN_DENIEDORA-01017-1017Invalid username/password
NO_DATA_FOUNDORA-01403+100SELECT INTO returns no row (or an uninitialised PL/SQL table row is referenced)
SUBSCRIPT_BEYOND_COUNTORA-06533-6533Collection index larger than the number of elements
TOO_MANY_ROWSORA-01422-1422SELECT INTO returns more than one row
VALUE_ERRORORA-06502-6502Arithmetic, conversion, truncation or size-constraint error
ZERO_DIVIDEORA-01476-1476Division by zero

The PDF lists further predefined exceptions: ACCESS_INTO_NULL, COLLECTION_IS_NULL, NOT_LOGGED_ON, PROGRAM_ERROR, ROWTYPE_MISMATCH, SELF_IS_NULL, STORAGE_ERROR, SUBSCRIPT_OUTSIDE_LIMIT, SYS_INVALID_ROWID and TIMEOUT_ON_RESOURCE.

When is NO_DATA_FOUND not raised?
  • When the SELECT uses a group function: SUM, AVG etc. return NULL (COUNT returns 0) instead of raising the exception – check the result for NULL.
  • When UPDATE or DELETE affects no rows (use cursor attributes – Chapter 18).
User-defined Exceptions
  1. Declare it in the declarative part: out_of_stock exception; (available in that block).
  2. Raise it explicitly with RAISE out_of_stock; when your condition occurs.
  3. Handle it like a predefined exception: WHEN out_of_stock THEN …
Declare, raise and re-raise
declare
   out_of_stock exception;
begin
   begin                                   -- sub-block
      if qty < 10 then
         raise out_of_stock;
      end if;
   exception
      when out_of_stock then
         -- partial handling here, then
         raise;                            -- re-raise the current exception
   end;
exception
   when out_of_stock then                  -- handled again in the outer block
      null;
end;

RAISE without a name re-raises the current exception and is valid only inside an exception handler.

Associating an exception with an Oracle error
PRAGMA EXCEPTION_INIT
declare
   null_value_error exception;
   pragma exception_init(null_value_error, -1407);
   newccode varchar2(5) := null;
begin
   update courses set ccode = newccode where ccode = 'c';
exception
   when null_value_error then
      dbms_output.put_line('trying to set null value to a not null column');
end;
Exception Propagation
  • An exception handled in the block that raised it is not propagated; control resumes in the enclosing block after the inner block.
  • If the current block has no handler, the exception is propagated to the enclosing blocks, one by one from inside out, until a handler is found.
  • If no block handles it, it reaches the host (SQL*Plus, Oracle Forms, Oracle Server …), which decides the action.
  • An exception raised in the declaration of a block is propagated immediately to the enclosing block – that block’s own handlers do not catch it (e.g. assigning 'abcdef' to VARCHAR2(5) gives ORA-06502 in the outer handler).
Success or failure of a block
Successful if it…Unsuccessful if it…
exits without raising an exception, or raises one that its own exception part handlesexits with an unhandled exception, or executes RAISE_APPLICATION_ERROR

To find which of several SELECTs raised NO_DATA_FOUND, set a counter variable (n := 1, n := 2 …) after each SELECT and test it in the handler.

Key Takeaways
  • Predefined exceptions are raised automatically; user-defined ones are declared and raised with RAISE.
  • WHEN OTHERS + SQLCODE/SQLERRM catch unnamed errors; PRAGMA EXCEPTION_INIT names them.
  • Group functions and UPDATE/DELETE never raise NO_DATA_FOUND.
  • Unhandled exceptions propagate outward to the host.
Chapter 17 Notes (PDF)
ch17.pdf 13 pages 365 KB Open in PDF Viewer (Free Tool)

Your browser cannot show this PDF here. Open Chapter 17 Notes (PDF)

ch17.pdfKeys: ← → page · + − zoom · F full screen
Question / Answer (15 questions)

Moderate-level questions based on the Chapter 17 notes (PDF). Click a question to see the answer.

Answer : In PL/SQL, errors and warnings are called exceptions. Whenever a predefined error occurs, PL/SQL raises an exception automatically – e.g. ZERO_DIVIDE when a number is divided by zero and NO_DATA_FOUND when SELECT cannot find a record. Users can also create their own exceptions.

Answer : When it is handled, control is transferred to the exception-handling part; after the handler executes, control goes to the next statement in the enclosing block, or returns to the host if there is no enclosing block. If it is not handled, the block is terminated and an error message related to the exception is displayed.

Answer : EXCEPTION WHEN exception-1 [OR exception-2] THEN statements; [WHEN exception-3 THEN statements;] ... [WHEN OTHERS THEN statements;]. Several exceptions in one WHEN share the same action. WHEN OTHERS executes its statements for any exception not mentioned in the other handlers.

Answer : They are functions that return the error number and the error message of the most recently occurred error. They are used mainly in WHEN OTHERS because most Oracle errors have no predefined exception. They cannot be used directly in an SQL statement – their values must first be assigned to variables.

Answer : NO_DATA_FOUND (ORA-01403, SQLCODE +100) is raised when a SELECT INTO returns no rows or an uninitialised row of a PL/SQL table is referenced. TOO_MANY_ROWS (ORA-01422, SQLCODE -1422) is raised when a SELECT INTO returns more than one row.

Answer : DUP_VAL_ON_INDEX (ORA-00001) when a duplicate value is stored in a column constrained by a unique index; VALUE_ERROR (ORA-06502) when an arithmetic, conversion, truncation or size-constraint error occurs; INVALID_NUMBER (ORA-01722) when, in an SQL statement, converting a character string to a number fails.

Answer : When a group function is used in the SELECT – e.g. SUM or AVG return NULL and COUNT returns 0 when no row is retrieved – and when UPDATE or DELETE commands affect no rows.

Answer : Since AVG returns NULL instead of raising NO_DATA_FOUND, the result variable is checked: IF v_avgdur IS NULL THEN display "No batch of C++ has been completed" ELSE display the average.

Answer : Declare it in the declarative part (out_of_stock EXCEPTION;), raise it explicitly with the RAISE command when the required condition occurs (IF qty < 10 THEN RAISE out_of_stock; END IF;), and handle it in the exception part like a predefined exception (WHEN out_of_stock THEN ...).

Answer : A predefined exception has a name defined by PL/SQL for a common error and is raised automatically when the corresponding error occurs. A user-defined exception is declared in the block in which it is used and must be raised explicitly with RAISE.

Answer : In an exception handler, RAISE without an exception name raises the current exception again so that it is propagated to the outer block, e.g. a sub-block handles OUT_OF_STOCK partially and then executes RAISE so the outer block also handles it. RAISE without a name is valid only in an exception handler.

Answer : Declare the exception and use PRAGMA EXCEPTION_INIT(exception_name, error_number) in the declarative part, e.g. PRAGMA EXCEPTION_INIT(null_value_error, -1407). Whenever Oracle error -1407 (setting a NOT NULL column to null) occurs, PL/SQL raises NULL_VALUE_ERROR automatically.

Answer : If an exception is not handled in the current block it is propagated to the enclosing blocks one after another, from inside to outside, until a handler is found. If no enclosing block handles it, it is sent to the host environment (e.g. SQL*Plus, Oracle Forms, Oracle Server), and the action depends on the host.

Answer : It is immediately propagated to the enclosing block and is not handled by the handlers of the block in which it occurred. For example, assigning 'abcdef' to a VARCHAR2(5) variable in an inner block’s declaration is caught by the outer block: ORA-06502: numeric or value error: character string buffer too small.

Answer : It is successful if it exits without raising any exception, or raises an exception that is handled in its own exception-handling part. It is unsuccessful if it exits with an unhandled exception or executes RAISE_APPLICATION_ERROR to generate a user-defined error.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. Which statement is used to re-raise the current exception?

Show Answer

Correct Answer : B. RAISE (without a name)
RAISE without an exception name, used inside a handler, re-raises the current exception.

Q2. Which function returns the error message of the most recent error?

Show Answer

Correct Answer : C. SQLERRM
SQLERRM returns the message; SQLCODE returns the error number.

Q3. When an UPDATE command could not update any rows, what happens?

Show Answer

Correct Answer : D. No exception is raised
NO_DATA_FOUND is not raised for UPDATE and DELETE; no exception occurs.

Q4. When an exception is not handled in the current block, it:

Show Answer

Correct Answer : A. Is propagated to the outer block
Unhandled exceptions propagate to enclosing blocks and finally to the host.

Q5. Which statement associates a user-defined exception with an Oracle error number?

Show Answer

Correct Answer : B. PRAGMA EXCEPTION_INIT
PRAGMA EXCEPTION_INIT(exception, error_number) makes PL/SQL raise the exception for that Oracle error.

Bibliography/References

The chapter notes PDF is the course study material and is credited to its author below. The explanations, questions and MCQs on this page are original study aids written for this course from the topics covered in that PDF. The other works are cited for verification and further reading. Oracle, SQL*Plus and PL/SQL are trademarks of Oracle Corporation; other names belong to their respective owners.

  1. Srikanth, P. (n.d.). Oracle For Beginners (chapter notes – the PDF shown on each chapter page). Srikanth Technologies. http://www.srikanthtechnologies.com/
  2. Oracle Corporation. (n.d.). Oracle Database PL/SQL Language Reference, 19c. https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/
  3. Oracle Corporation. (n.d.). Oracle Database Error Messages, 19c. https://docs.oracle.com/en/database/oracle/oracle-database/19/errmg/
  4. Feuerstein, S., & Pribyl, B. (2014). Oracle PL/SQL Programming (6th ed.). O’Reilly Media.