@@ -263,16 +263,36 @@ create or replace type body ut_compound_data_value as
263263 end;
264264
265265 member function compare_implementation_by_sql(a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2, a_join_by_xpath varchar2, a_inclusion_compare boolean := false) return integer is
266- l_compare_sql varchar2(32767);
266+
267267 l_ut_owner varchar2(250) := ut_utils.ut_owner;
268268 l_actual ut_data_value_refcursor := treat(a_other as ut_data_value_refcursor);
269269 l_diff_id ut_compound_data_helper.t_hash;
270+
271+ --Variable for dynamic SQL - to review and simplify ??
270272 l_table_stmt varchar2(32767);
271273 l_where_stmt varchar2(32767);
272274 l_join_by_stmt varchar2(32767);
273275 l_exec_sql varchar2(32767);
276+ l_compare_sql varchar2(32767);
277+
274278 l_other ut_compound_data_value;
275279 l_result integer;
280+ --Max rows to prevent out of memory for too much diffs especially on join by non unique
281+ l_max_rows integer := greatest(self.elements_count,1000);
282+ l_loop_curs sys_refcursor;
283+ type t_diff_rec is record (
284+ act_item_data clob,
285+ act_data_id raw(32),
286+ exp_item_data clob,
287+ exp_data_id raw(32),
288+ item_no integer
289+ );
290+ type t_diff_tab is table of t_diff_rec;
291+ l_diff_tab t_diff_tab;
292+
293+ --TEST
294+ t1 pls_integer;
295+
276296 begin
277297
278298 -- TODO : Add column filters!!!!
@@ -290,16 +310,16 @@ create or replace type body ut_compound_data_value as
290310 if a_join_by_xpath is null then
291311 -- If no key defined do the join on all columns
292312 l_join_by_stmt := ut_compound_data_helper.generate_equal_sql(l_actual.columns_info);
293- l_compare_sql := l_compare_sql || q'[select a.item_data act_item_data, a.data_id act_data_id, e.item_data exp_item_data, e.data_id exp_data_id ]'
313+ l_compare_sql := l_compare_sql || q'[select xmlelement( name "ROW", a.item_data) act_item_data, a.data_id act_data_id, xmlelement( name "ROW", e.item_data) exp_item_data, e.data_id exp_data_id, rownum item_no ]'
294314 || q'[from act a full outer join exp e on ( ]'
295315 ||l_join_by_stmt||q'[ ) where a.data_id is null or e.data_id is null]';
296316 else
297317 -- If key defined do the join or these and where on diffrences
298318 l_where_stmt := ut_compound_data_helper.generate_not_equal_sql(l_actual.columns_info, a_join_by_xpath);
299319 --l_join_is_null := ut_compound_data_helper.generate_join_null_sql(l_actual.columns_info, a_join_by_xpath);
300320 l_join_by_stmt := ut_compound_data_helper.generate_join_by_on_stmt (l_actual.columns_info, a_join_by_xpath);
301- l_compare_sql := l_compare_sql || 'select a.item_data act_item_data, a.data_id act_data_id,'
302- ||' e.item_data exp_item_data, e.data_id exp_data_id from act a full outer join exp e on ( '
321+ l_compare_sql := l_compare_sql || 'select xmlserialize(content (xmlelement( name "ROW", a.item_data)) no indent) act_item_data, a.data_id act_data_id,'
322+ ||' xmlserialize(content (xmlelement( name "ROW", e.item_data)) no indent) exp_item_data, e.data_id exp_data_id, rownum item_no from act a full outer join exp e on ( '
303323 ||l_join_by_stmt||' ) '
304324 ||' where '||
305325 case
@@ -313,11 +333,29 @@ create or replace type body ut_compound_data_value as
313333
314334 l_exec_sql := 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp '
315335 ||'( diff_id, act_item_data, act_data_id, exp_item_data, exp_data_id, item_no )'
316- ||' select :diff_id, nvl2(act_item_data,xmlelement( name "ROW", act_item_data),null) act_item_data, act_data_id,'
317- ||' nvl2( exp_item_data,xmlelement( name "ROW", exp_item_data),null) exp_item_data, exp_data_id , rownum '
336+ ||' select :diff_id, act_item_data, act_data_id,'
337+ ||' exp_item_data, exp_data_id , item_no '
318338 ||'from ( '|| l_compare_sql ||')';
319339
320- execute immediate l_exec_sql using l_diff_id, self.data_id,l_actual.data_id;
340+ open l_loop_curs for l_compare_sql using self.data_id,l_actual.data_id;
341+
342+ loop
343+ fetch l_loop_curs bulk collect into l_diff_tab limit l_max_rows;
344+ exit when l_diff_tab.count = 0;
345+ --Pass it to helper as authid as definer
346+ t1 := dbms_utility.get_time;
347+
348+ forall idx in 1..l_diff_tab.count
349+ insert into ut3.ut_compound_data_diff_tmp
350+ ( diff_id, act_item_data, act_data_id, exp_item_data, exp_data_id, item_no )
351+ values
352+ (l_diff_id, l_diff_tab(idx).act_item_data, l_diff_tab(idx).act_data_id, l_diff_tab(idx).exp_item_data, l_diff_tab(idx).exp_data_id,l_diff_tab(idx).item_no);
353+ dbms_output.put_line((dbms_utility.get_time - t1)/100 || ' seconds - get col info');
354+ --Exit after first fetch of max rows (to look later)
355+ exit;
356+ end loop;
357+
358+ --execute immediate l_exec_sql using l_diff_id, self.data_id,l_actual.data_id;
321359 --result is OK only if both are same
322360 if sql%rowcount = 0 and self.elements_count = l_other.elements_count then
323361 l_result := 0;
0 commit comments