- Notifications
You must be signed in to change notification settings - Fork 849
/
Copy pathsqlerrm-format-error-stack.sql
162 lines (146 loc) · 3.28 KB
/
sqlerrm-format-error-stack.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
160
161
/*
SQLERRM is a function that returns the current error message (if no argument is passed to it)
or the system error message associated with the specified error code. DBMS_UTILITY.FORMAT_ERROR_STACK
also returns the error message (or stack, if there is a stack of errors) and avoids truncation issues
that may occur with SQLERRM.
*/
-- SQLERRM with No Arguments
BEGIN
RAISE TOO_MANY_ROWS;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (SQLERRM);
END;
/
-- SQLERRM as Lookup Function
BEGIN
DBMS_OUTPUT.put_line (SQLERRM (-1422));
END;
/
-- That's Right: Oracle Errors are Negative
-- Even though some other parts of Oracle Database store error codes as unsigned integers (LOG ERRORS, SAVE EXCEPTIONS).
BEGIN
DBMS_OUTPUT.put_line (SQLERRM (1422));
END;
/
-- Call Both Error Message Functions
-- And show the length of the string (useful when examining truncation issues in last step of script).
CREATE OR REPLACE PROCEDURE show_errors
IS
BEGIN
DBMS_OUTPUT.put_line ('-------SQLERRM-------------');
DBMS_OUTPUT.put_line (SQLERRM);
DBMS_OUTPUT.put_line ('-------FORMAT_ERROR_STACK--');
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
DBMS_OUTPUT.put_line ('');
END;
/
CREATE OR REPLACE PROCEDURE proc1
IS
BEGIN
RAISE NO_DATA_FOUND;
END;
/
CREATE OR REPLACE PACKAGE pkg1
IS
PROCEDURE proc2;
END pkg1;
/
CREATE OR REPLACE PACKAGE BODY pkg1
IS
PROCEDURE proc2
IS
BEGIN
proc1;
EXCEPTION
WHEN OTHERS
THEN
RAISE DUP_VAL_ON_INDEX;
END;
END pkg1;
/
-- Raise Application Error - and Keep the Stack
-- The third argument of raise_application_error determines whether or not the stack of errors is kept
-- or discarded. TRUE = Keep.
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
FOR indx IN1 .. 1000
LOOP
NULL;
END LOOP;
pkg1.proc2;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error (-20000, 'TOP MOST ERROR MESSAGE', TRUE);
END;
/
BEGIN
proc3;
EXCEPTION
WHEN OTHERS
THEN
show_errors;
END;
/
-- Now Discard Error Stack
CREATE OR REPLACE PROCEDURE proc3
IS
BEGIN
FOR indx IN1 .. 1000
LOOP
NULL;
END LOOP;
pkg1.proc2;
EXCEPTION
WHEN OTHERS
THEN
raise_application_error (-20000, 'TOP MOST ERROR MESSAGE', FALSE);
END;
/
BEGIN
proc3;
EXCEPTION
WHEN OTHERS
THEN
show_errors;
END;
/
-- SQLERRM Can Truncate on Long Stacks
-- DBMS_UTILITY.format_error_stack? Not so much. And notice down at the bottom: the original exception.
DECLARE
PROCEDURE show_errors
IS
BEGIN
DBMS_OUTPUT.put_line ('-------SQLERRM-------------');
DBMS_OUTPUT.put_line (LENGTH (SQLERRM));
DBMS_OUTPUT.put_line (SQLERRM);
DBMS_OUTPUT.put_line ('-------FORMAT_ERROR_STACK--');
DBMS_OUTPUT.put_line (
LENGTH (DBMS_UTILITY.format_error_stack));
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
END;
PROCEDURE raise_error (nth_in ININTEGER)
IS
BEGIN
IF nth_in <=10000
THEN
raise_error (nth_in +1);
ELSE
RAISE NO_DATA_FOUND;
END IF;
EXCEPTION
WHEN OTHERS
THEN
RAISE VALUE_ERROR;
END;
BEGIN
raise_error (1);
EXCEPTION
WHEN OTHERS
THEN
show_errors;
END;
/