@@ -29,26 +29,41 @@ create or replace type body ut_executable is
2929 return;
3030 end;
3131
32- member function is_valid (self in out nocopy ut_executable) return boolean is
32+ member function is_defined (self in out nocopy ut_executable) return boolean is
3333 l_result boolean := false;
3434 l_message_part varchar2(4000) := 'Call params for ' || self.associated_event_name || ' are not valid: ';
3535 begin
3636
3737 if self.object_name is null then
3838 self.error_stack := l_message_part || 'package is not defined';
39- elsif not ut_metadata.package_valid(self.owner_name, self.object_name) then
40- self.error_stack := l_message_part || 'package does not exist or is invalid: ' ||upper(self.owner_name||'.'||self.object_name);
4139 elsif self.procedure_name is null then
4240 self.error_stack := l_message_part || 'procedure is not defined';
41+ else
42+ l_result := true;
43+ end if;
44+
45+ return l_result;
46+ end is_defined;
47+
48+ /**
49+ * We will check if error raised because package was invalid if not we let it propagate.
50+ **/
51+ member function is_invalid(self in out nocopy ut_executable) return boolean is
52+ l_result boolean := true;
53+ l_message_part varchar2(4000) := 'Call params for ' || self.associated_event_name || ' are not valid: ';
54+ begin
55+
56+ if not ut_metadata.package_valid(self.owner_name, self.object_name) then
57+ self.error_stack := l_message_part || 'package does not exist or is invalid: ' ||upper(self.owner_name||'.'||self.object_name);
4358 elsif not ut_metadata.procedure_exists(self.owner_name, self.object_name, self.procedure_name) then
4459 self.error_stack := l_message_part || 'procedure does not exist '
4560 || upper(self.owner_name || '.' || self.object_name || '.' ||self.procedure_name);
4661 else
47- l_result := true ;
62+ l_result := false ;
4863 end if;
4964
5065 return l_result;
51- end is_valid ;
66+ end is_invalid ;
5267
5368 member function form_name return varchar2 is
5469 begin
@@ -66,6 +81,7 @@ create or replace type body ut_executable is
6681 l_status number;
6782 l_cursor_number number;
6883 l_completed_without_errors boolean := true;
84+ l_failed_with_invalid_pck boolean := true;
6985 l_start_transaction_id varchar2(250);
7086 l_end_transaction_id varchar2(250);
7187
@@ -95,7 +111,7 @@ create or replace type body ut_executable is
95111 --listener - before call to executable
96112 ut_event_manager.trigger_event('before_'||self.associated_event_name, self);
97113
98- l_completed_without_errors := self.is_valid ();
114+ l_completed_without_errors := self.is_defined ();
99115 if l_completed_without_errors then
100116 l_statement :=
101117 'declare' || chr(10) ||
@@ -117,15 +133,32 @@ create or replace type body ut_executable is
117133 ut_utils.debug_log('ut_executable.do_execute l_statement: ' || l_statement);
118134
119135 l_cursor_number := dbms_sql.open_cursor;
120- dbms_sql.parse(l_cursor_number, statement => l_statement, language_flag => dbms_sql.native);
121- dbms_sql.bind_variable(l_cursor_number, 'a_error_stack', to_char(null), 32767);
122- dbms_sql.bind_variable(l_cursor_number, 'a_error_backtrace', to_char(null), 32767);
123-
124- l_status := dbms_sql.execute(l_cursor_number);
125- dbms_sql.variable_value(l_cursor_number, 'a_error_stack', self.error_stack);
126- dbms_sql.variable_value(l_cursor_number, 'a_error_backtrace', self.error_backtrace);
127- dbms_sql.close_cursor(l_cursor_number);
128136
137+ /**
138+ * The code will allow to execute once we check if packages are defined
139+ * If it fail with 6550 (usually invalid package) it will check if because of invalid state or missing
140+ * if for any other reason we will propagate it up as we didnt expected.
141+ **/
142+ begin
143+ dbms_sql.parse(l_cursor_number, statement => l_statement, language_flag => dbms_sql.native);
144+ dbms_sql.bind_variable(l_cursor_number, 'a_error_stack', to_char(null), 32767);
145+ dbms_sql.bind_variable(l_cursor_number, 'a_error_backtrace', to_char(null), 32767);
146+ l_status := dbms_sql.execute(l_cursor_number);
147+ dbms_sql.variable_value(l_cursor_number, 'a_error_stack', self.error_stack);
148+ dbms_sql.variable_value(l_cursor_number, 'a_error_backtrace', self.error_backtrace);
149+ dbms_sql.close_cursor(l_cursor_number);
150+ exception
151+ when ut_utils.ex_invalid_package then
152+ l_failed_with_invalid_pck := self.is_invalid();
153+ dbms_sql.close_cursor(l_cursor_number);
154+ if not l_failed_with_invalid_pck then
155+ raise;
156+ end if;
157+ when others then
158+ dbms_sql.close_cursor(l_cursor_number);
159+ raise;
160+ end;
161+
129162 save_dbms_output;
130163
131164 l_completed_without_errors := (self.error_stack||self.error_backtrace) is null;
@@ -144,6 +177,7 @@ create or replace type body ut_executable is
144177 ut_utils.set_client_info(null);
145178
146179 return l_completed_without_errors;
180+
147181 end do_execute;
148182
149183 member function get_error_stack_trace return varchar2 is
0 commit comments