Exception Handling: Bulletproofing Your PL/SQL Code
Don't let a single bad row crash a 5-hour batch job. Learn how to intercept system errors, raise custom business exceptions, and build rock-solid logging mechanisms using Autonomous Transactions.
The Anatomy of an Exception Block
Every PL/SQL block (BEGIN ... END) can optionally include an EXCEPTION section. If a runtime error occurs, execution immediately jumps to this section, bypassing the rest of the code.
Handling Predefined Exceptions
Oracle provides predefined names for common errors. It is best practice to handle specific errors rather than using a blanket WHEN OTHERS.
SQLERRM: Returns the actual error message string.SQLCODE: Returns the negative integer error code (e.g., -1403).
Raising User-Defined (Business) Exceptions
Sometimes the data is technically valid, but it violates a business rule. You can create your own exceptions and intentionally trigger them using the RAISE statement.
Naming ORA Errors (PRAGMA EXCEPTION_INIT)
Not all of Oracle's thousands of ORA- errors have predefined names. For example, ORA-02292: integrity constraint violated (trying to delete a parent with child rows) has no name.
You can bind a custom name to a specific Oracle error code using a compiler directive called PRAGMA EXCEPTION_INIT.
Building an Autonomous Logger
If an error occurs deep inside a massive batch job, you want to write that error to an ERROR_LOGS table.
The Problem: If the batch job fails and issues a ROLLBACK, it will also rollback your INSERT INTO error_logs statement! Your log disappears.
The Solution: Use PRAGMA AUTONOMOUS_TRANSACTION. This tells Oracle that the logging procedure operates in an independent transaction space. It can commit its logs even if the parent transaction rolls back.
Now, in your main code:
Common Gotchas
Important Gotchas
- !
Never, ever write
WHEN OTHERS THEN NULL;. This silently swallows every error in the system. The application will continue running in a corrupted state, and you will never know an error occurred until angry users call you. - !
If you catch an error and log
SQLERRM, you only get the error string. You lose the exact line number where the error occurred. For deep debugging, useDBMS_UTILITY.FORMAT_ERROR_BACKTRACEto capture the line number of the original crash.
Key Takeaways
Key Takeaways
- Handle specific predefined exceptions (
NO_DATA_FOUND) before using a genericWHEN OTHERSblock. - Define business-rule exceptions using
RAISE, or map them to Oracle errors usingPRAGMA EXCEPTION_INIT. - Always use
PRAGMA AUTONOMOUS_TRANSACTIONfor your logging procedures so error logs survive a rollback.


