-
Notifications
You must be signed in to change notification settings - Fork 849
/
Copy pathdbms-utility-backtrace.sql
159 lines (145 loc) · 3.93 KB
/
dbms-utility-backtrace.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
The DBMS_UTILITY.format_error_backtrace function, added in Oracle Database 10g Release 2,
is a critical subprogram to call when logging exceptions. It returns a string that traces
the error back to the line on which it was raised! Note: if you re-raise an exception as
it propagates up the stack, you will lose the "original" line number. The back trace function
always only traces back to the most recently raised exception.
*/
CREATE OR REPLACE PROCEDURE proc1
IS
BEGIN
DBMS_OUTPUT.put_line ('running proc1');
RAISE NO_DATA_FOUND;
END;
/
CREATE OR REPLACE PROCEDURE proc2
IS
l_str VARCHAR2 (30) := 'calling proc1';
BEGIN
DBMS_OUTPUT.put_line (l_str);
proc1;
END;
/
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
DBMS_OUTPUT.put_line ('calling proc2');
proc2;
END;
/
-- Without Back Trace....
-- The only way to "see" the line number on which the error was raised was to let the exception go unhandled.
BEGIN
DBMS_OUTPUT.put_line ('Proc3 -> Proc2 -> Proc1 unhandled');
proc3;
END;
/
-- Trap and Display Error Stack (Error Message)
-- Sure, that works fine and is very good info to have, but the error stack (error message) will contain the line number on which the error was raised!
BEGIN
DBMS_OUTPUT.put_line ('Proc3 -> Proc2 -> Proc1 unhandled');
proc3;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
END;
/
-- Add Back Trace to Error Handler
-- Now we trap the exception at the top level subprogram and view both the error stack and the back trace.
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
DBMS_OUTPUT.put_line ('calling proc2');
proc2;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error backtrace at top level:');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
END;
/
BEGIN
DBMS_OUTPUT.put_line ('Proc3 -> Proc2 -> Proc1 backtrace');
proc3;
END;
/
-- Re-Raise Exception
-- I show the back trace, but then re-raise.
CREATE OR REPLACE PROCEDURE proc1
IS
BEGIN
DBMS_OUTPUT.put_line ('running proc1');
RAISE NO_DATA_FOUND;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error backtrace in block where raised:');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
RAISE;
END;
/
-- Can't Trace All the Way Back
-- The call to back trace in this upper-level subprogram no longer finds it way back to the line number of the original exception. That was wiped out with the call to RAISE;
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
DBMS_OUTPUT.put_line ('calling proc2');
proc2;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error backtrace at top level:');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
END;
/
BEGIN
DBMS_OUTPUT.put_line ('Proc3 -> Proc2 -> Proc1, re-reraise in Proc1');
proc3;
END;
/
-- Handle and Raise At Every Level
-- And see how the back trace changes!
CREATE OR REPLACE PROCEDURE proc1
IS
BEGIN
DBMS_OUTPUT.put_line ('running proc1');
RAISE NO_DATA_FOUND;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error stack in block where raised:');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
RAISE;
END;
/
CREATE OR REPLACE PROCEDURE proc2
IS
BEGIN
DBMS_OUTPUT.put_line ('calling proc1');
proc1;
EXCEPTION
WHEN OTHERS
THEN
RAISE VALUE_ERROR;
END;
/
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
DBMS_OUTPUT.put_line ('calling proc2');
proc2;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('Error backtrace at top level:');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_backtrace);
END;
/
BEGIN
DBMS_OUTPUT.put_line
('Proc3 -> Proc2 -> Proc1, re-reraise in Proc1, raise VE in Proc2');
proc3;
END;
/