The PL/SQL Challenge quiz for 10 September - 16 September 2016 explored the different ways you can obtain the error message / stack in PL/SQL. Note: an error stack is a sequence of multiple error messages that can occur when an exception is propagated and re-raised through several layers of nested blocks.
The three ways are:
Other helpful resources regarding error management in PL/SQL:
Nine Good to Knows for PL/SQL Error Management
PL/SQL Error Handling (doc)
Finally, here's the code from our quiz that you can copy/paste into your editor to check out these alternatives.
The three ways are:
- SQLERRM - The original, traditional and (oddly enough) not currently recommended function to get the current error message. Not recommended because the next two options avoid a problem which you are unlikely to run into: the error stack will be truncated at 512 bytes, and you might lose some error information.
- DBMS_UTILITY.FORMAT_ERROR_STACK - Returns the error message / stack, and will not truncate your string like SQLERRM will.
- UTL_CALL_STACK API - Added in Oracle Database 12c, the UTL_CALL_STACK package offers a comprehensive API into the execution call stack, the error stack and the error backtrace.
Other helpful resources regarding error management in PL/SQL:
Nine Good to Knows for PL/SQL Error Management
PL/SQL Error Handling (doc)
Finally, here's the code from our quiz that you can copy/paste into your editor to check out these alternatives.
CREATE OR REPLACE PROCEDURE plch_check_balance (
balance_in IN NUMBER) AUTHID DEFINER IS BEGIN IF balance_in < 0 THEN RAISE VALUE_ERROR; END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line (SQLERRM); END; / BEGIN plch_check_balance (-1); END; / CREATE OR REPLACE PROCEDURE plch_check_balance (
balance_in IN NUMBER) AUTHID DEFINER IS BEGIN IF balance_in < 0 THEN RAISE VALUE_ERROR; END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack); END; / BEGIN plch_check_balance (-1); END; / CREATE OR REPLACE PROCEDURE plch_check_balance (
balance_in IN NUMBER) AUTHID DEFINER IS BEGIN IF balance_in < 0 THEN RAISE VALUE_ERROR; END IF; EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.put_line ( 'ORA-' || TO_CHAR (UTL_CALL_STACK.error_number (1), 'fm00000') || ': ' || UTL_CALL_STACK.error_msg (1)); END; / BEGIN plch_check_balance (-1); END; / DROP PROCEDURE plch_check_balance /
Hi Steven,
ReplyDeleteLove the article (as usual). But wasn't UTL_CALL_STACK introduced in 12c instead of 11g?
Ha! Yes, Erwin, you are absolutely correct. Will fix the post.
DeleteDBMS_UTILITY.FORMAT_ERROR_STACK (at least in the 11g server I have access to) contains exactly the same as SQLERRM (i.e., no strack trace or original line number, just plain error code and message).
ReplyDelete:_(
Alvaro, please check out this LiveSQL script to see the differences - and verify them for yourself: https://livesql.oracle.com/apex/livesql/file/content_CSHKGPS5AHKCMUIAYYMTL1QYT.html
DeleteThey *can* be the same under some circumstances, but not always.
Interesting... I've tried the LiveSQL commands and my output is slightly different. Stack trace is included or omitted as you describe, but SQLERRM still contains the same output than DBMS_UTILITY.FORMAT_ERROR_STACK in every example. I've tested it in XE 11g, for what it matters.
DeleteBTW, thanks to your article I found DBMS_UTILITY.FORMAT_ERROR_BACKTRACE() in Oracle documentation and it solved my immediate needs.