Introduction:
Exception handling is a crucial aspect of writing robust and reliable Oracle PL/SQL code. PL/SQL provides a powerful mechanism to handle errors and exceptions that may occur during program execution. This blog post will explore the fundamentals of PL/SQL exceptions, their importance, and best practices for handling them effectively.
- Understanding PL/SQL Exceptions:
In PL/SQL, exceptions represent error conditions that can occur during program execution. They provide a way to gracefully handle errors and take appropriate actions. PL/SQL exceptions can be predefined (e.g., NO_DATA_FOUND, TOO_MANY_ROWS) or user-defined based on specific requirements. - Exception Handling:
The EXCEPTION block is used to catch and handle exceptions in PL/SQL. It consists of one or more exception handlers that specify the actions to be taken when a particular exception occurs. The basic structure of an exception block includes the keywords BEGIN, EXCEPTION, and END. Exception handlers can be nested to handle different types of exceptions. - Exception Handling Best Practices:
a. Be specific in exception handling: Catch and handle exceptions at the appropriate level of granularity. Avoid using a generic “WHEN OTHERS” clause, as it can hide important error details and make debugging difficult.
b. Handle exceptions as close to the source as possible: Place exception handlers as close to the code that can potentially raise the exception. This helps in identifying and resolving issues more efficiently.
c. Use RAISE_APPLICATION_ERROR: When appropriate, use the RAISE_APPLICATION_ERROR procedure to raise custom exceptions with user-friendly error messages. This allows for better communication of errors to users or calling applications.
d. Log and track exceptions: Implement proper logging mechanisms to record exception details, including timestamps, error messages, and relevant contextual information. This information can be invaluable in troubleshooting and analyzing issues.
e. Test exception handling scenarios: Create comprehensive test cases that cover different exception scenarios to ensure your exception handling logic behaves as expected. - Exception Handling Examples:
a. Handling predefined exceptions:
BEGIN
SELECT column_name INTO var_name FROM table_name WHERE condition;
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- Handle the situation when no data is found
WHEN TOO_MANY_ROWS THEN
-- Handle the situation when more than one row is found
WHEN OTHERS THEN
-- Handle any other exceptions
END;
Pre-defined Exceptions
PL/SQL provides many pre-defined exceptions, which are executed when any database rule is violated by a program. For example, the predefined exception NO_DATA_FOUND is raised when a SELECT INTO statement returns no rows. The following table lists few of the important pre-defined exceptions −
Exception | Oracle Error | SQLCODE | Description |
---|---|---|---|
ACCESS_INTO_NULL | 06530 | -6530 | It is raised when a null object is automatically assigned a value. |
CASE_NOT_FOUND | 06592 | -6592 | It is raised when none of the choices in the WHEN clause of a CASE statement is selected, and there is no ELSE clause. |
COLLECTION_IS_NULL | 06531 | -6531 | It is raised when a program attempts to apply collection methods other than EXISTS to an uninitialized nested table or varray, or the program attempts to assign values to the elements of an uninitialized nested table or varray. |
DUP_VAL_ON_INDEX | 00001 | -1 | It is raised when duplicate values are attempted to be stored in a column with unique index. |
INVALID_CURSOR | 01001 | -1001 | It is raised when attempts are made to make a cursor operation that is not allowed, such as closing an unopened cursor. |
INVALID_NUMBER | 01722 | -1722 | It is raised when the conversion of a character string into a number fails because the string does not represent a valid number. |
LOGIN_DENIED | 01017 | -1017 | It is raised when a program attempts to log on to the database with an invalid username or password. |
NO_DATA_FOUND | 01403 | +100 | It is raised when a SELECT INTO statement returns no rows. |
NOT_LOGGED_ON | 01012 | -1012 | It is raised when a database call is issued without being connected to the database. |
PROGRAM_ERROR | 06501 | -6501 | It is raised when PL/SQL has an internal problem. |
ROWTYPE_MISMATCH | 06504 | -6504 | It is raised when a cursor fetches value in a variable having incompatible data type. |
SELF_IS_NULL | 30625 | -30625 | It is raised when a member method is invoked, but the instance of the object type was not initialized. |
STORAGE_ERROR | 06500 | -6500 | It is raised when PL/SQL ran out of memory or memory was corrupted. |
TOO_MANY_ROWS | 01422 | -1422 | It is raised when a SELECT INTO statement returns more than one row. |
VALUE_ERROR | 06502 | -6502 | It is raised when an arithmetic, conversion, truncation, or sizeconstraint error occurs. |
ZERO_DIVIDE | 01476 | 1476 | It is raised when an attempt is made to divide a number by zero. |
b. Raising custom exceptions:
DECLARE
custom_exception EXCEPTION;
PRAGMA EXCEPTION_INIT(custom_exception, -20001);
BEGIN
IF some_condition THEN
RAISE custom_exception;
END IF;
EXCEPTION
WHEN custom_exception THEN
-- Handle the custom exception
WHEN OTHERS THEN
-- Handle any other exceptions
END;
Conclusion:
Proper exception handling is essential for writing reliable and maintainable PL/SQL code. By understanding the fundamentals of exceptions and following best practices, you can ensure that your code gracefully handles errors and provides meaningful feedback to users. Remember to test your exception handling logic thoroughly to catch and address potential issues early on.