@@ -250,24 +250,32 @@ create or replace type body ut_compound_data_value as
250250 l_row_diffs ut_compound_data_helper.tt_row_diffs;
251251 c_max_rows constant integer := 20;
252252
253- type t_pk_val_rec is record
254- (
255- data_id raw(32),
256- item_hash raw(128),
257- pk_hash raw(128),
258- pk_value varchar2(4000)
259- );
260-
261- type t_pk_val_tab is table of t_pk_val_rec;
262- l_pk_val_tab t_pk_val_tab;
263-
264- function get_column_xpath(a_join_by_xpath varchar2) return varchar2 is
253+ function get_pk_value(a_join_by_xpath varchar2) return varchar2 is
265254 l_column varchar2(32767);
266255 begin
256+ /* due to possibility of key being to columns we cannot use xmlextractvalue
257+ usage of xmlagg is possible however it greatly complicates code and performance is impacted.
258+ xpath to be looked at or regex
259+ */
267260 if a_join_by_xpath is not null then
268- l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash( extract(t.item_data,:join_by_xpath).GetClobVal()) pk_hash ';
261+ l_column := ' extract(t.item_data,:join_by_xpath).GetStringVal() pk_value ';
269262 else
270- l_column := ':join_by_xpath pk_hash ';
263+ l_column := ' :join_by_xpath pk_value';
264+ end if;
265+ return l_column;
266+ end;
267+
268+ function get_column_pk_hash(a_join_by_xpath varchar2) return varchar2 is
269+ l_column varchar2(32767);
270+ begin
271+ /* due to possibility of key being to columns we cannot use xmlextractvalue
272+ usage of xmlagg is possible however it greatly complicates code and performance is impacted.
273+ xpath to be looked at or regex
274+ */
275+ if a_join_by_xpath is not null then
276+ l_column := l_ut_owner ||'.ut_compound_data_helper.get_hash(extract(ucd.item_data,:join_by_xpath).GetClobVal()) pk_hash';
277+ else
278+ l_column := ':join_by_xpath pk_hash';
271279 end if;
272280 return l_column;
273281 end;
@@ -281,81 +289,58 @@ create or replace type body ut_compound_data_value as
281289
282290 l_diff_id := ut_compound_data_helper.get_hash(self.data_id||l_other.data_id);
283291 l_column_filter := ut_compound_data_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
284-
292+
285293 /**
286294 * Due to incompatibility issues in XML between 11 and 12.2 and 12.1 versions we will prepopulate pk_hash upfront to
287295 * avoid optimizer incorrectly rewrite and causing NULL error or ORA-600
288- **/
289- -- Pre generate hash minus to leave only onese that are diffrent, for example duplicates or diffrent hash
290- /*if a_join_by_xpath is not null then
291- execute immediate q'[select
292- data_id,item_hash,pk_hash,
293- listagg(extractvalue(tcd.column_value, '/*'), '; ') within GROUP(ORDER BY item_hash) pk_value
294- from
295- (select
296- ucd.column_value row_data,
297- ]'|| l_ut_owner ||q'[.ut_compound_data_helper.get_hash(extract(ucd.column_value,:join_xpath).GetClobVal()) pk_hash ,
298- t.item_hash,
299- t.data_id
300- from ]' || l_ut_owner || q'[.ut_compound_data_tmp t ,
301- table(xmlsequence(extract(t.item_data,'/*'))) ucd
302- where data_id = :self_guid or data_id = :other_guid ),
303- table(xmlsequence(extract(row_data ,:join_xpath))) tcd
304- group by pk_hash,item_hash,data_id]'
305- bulk collect into l_pk_val_tab using a_join_by_xpath,self.data_id, l_other.data_id,a_join_by_xpath;
296+ **/
297+ execute immediate 'merge into ' || l_ut_owner || '.ut_compound_data_tmp tgt
298+ using (
299+ select '||l_ut_owner ||'.ut_compound_data_helper.get_hash(ucd.item_data.getclobval()) item_hash,
300+ pk_hash, ucd.item_no, ucd.data_id
301+ from
302+ (
303+ select '||l_column_filter||','||get_column_pk_hash(a_join_by_xpath)||', item_no, data_id
304+ from ' || l_ut_owner || q'[.ut_compound_data_tmp ucd
305+ where data_id = :self_guid or data_id = :other_guid
306+ ) ucd
307+ ) src
308+ on (tgt.item_no = src.item_no and tgt.data_id = src.data_id)
309+ when matched then update
310+ set tgt.item_hash = src.item_hash,
311+ tgt.pk_hash = src.pk_hash ]'
312+ using a_exclude_xpath, a_include_xpath,a_join_by_xpath,self.data_id, l_other.data_id;
306313
307- forall pk_vals in 1..l_pk_val_tab.COUNT
308- update ut_compound_data_tmp
309- set pk_hash = l_pk_val_tab(pk_vals).pk_hash
310- ,pk_value = l_pk_val_tab(pk_vals).pk_value
311- where data_id = l_pk_val_tab(pk_vals).data_id
312- and item_hash = l_pk_val_tab(pk_vals).item_hash;
313- end if;
314- */
315-
316- execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id,item_hash,pk_hash,duplicate_no)
317- with calc_pk as
318- ( select data_id,item_hash, '||get_column_xpath(a_join_by_xpath)||'
319- from ' || l_ut_owner || '.ut_compound_data_tmp t
320- )
321- select distinct :diff_id,tmp.item_hash,tmp.pk_hash,tmp.duplicate_no
314+ /* Peform minus on two sets two get diffrences that will be used later on to print results */
315+ execute immediate 'insert into ' || l_ut_owner || '.ut_compound_data_diff_tmp ( diff_id,item_hash,pk_hash,duplicate_no,pk_value)
316+ with source_data as
317+ ( select t.data_id,t.item_hash,row_number() over (partition by t.pk_hash,t.item_hash,t.data_id order by 1,2) duplicate_no,
318+ pk_hash, '||get_pk_value(a_join_by_xpath)||'
319+ from ' || l_ut_owner || '.ut_compound_data_tmp t
320+ where data_id = :self_guid or data_id = :other_guid
321+ )
322+ select distinct :diff_id,tmp.item_hash,tmp.pk_hash,tmp.duplicate_no,pk_value
322323 from(
323324 (
324- select t.item_hash,row_number() over (partition by t.item_hash,t.data_id order by 1,2) duplicate_no,
325- pc.pk_hash
326- from ' || l_ut_owner || '.ut_compound_data_tmp t,
327- calc_pk pc
325+ select t.item_hash,t. duplicate_no,t.pk_hash, t.pk_value
326+ from source_data t
328327 where t.data_id = :self_guid
329- and pc.data_id = t.data_id
330- and pc.item_hash = t.item_hash
331328 minus
332- select t.item_hash,row_number() over (partition by t.item_hash,t.data_id order by 1,2) duplicate_no,
333- pc.pk_hash
334- from ' || l_ut_owner || '.ut_compound_data_tmp t,
335- calc_pk pc
329+ select t.item_hash,t. duplicate_no,t.pk_hash, t.pk_value
330+ from source_data t
336331 where t.data_id = :other_guid
337- and pc.data_id = t.data_id
338- and pc.item_hash = t.item_hash
339332 )
340333 union all
341334 (
342- select t.item_hash,row_number() over (partition by t.item_hash,t.data_id order by 1,2) duplicate_no,
343- pc.pk_hash
344- from ' || l_ut_owner || '.ut_compound_data_tmp t,
345- calc_pk pc
335+ select t.item_hash,t. duplicate_no,t.pk_hash, t.pk_value
336+ from source_data t
346337 where t.data_id = :other_guid
347- and pc.data_id = t.data_id
348- and pc.item_hash = t.item_hash
349338 minus
350- select t.item_hash,row_number() over (partition by t.item_hash,t.data_id order by 1,2) duplicate_no,
351- pc.pk_hash
352- from ' || l_ut_owner || '.ut_compound_data_tmp t,
353- calc_pk pc
339+ select t.item_hash,t. duplicate_no,t.pk_hash, t.pk_value
340+ from source_data t
354341 where t.data_id = :self_guid
355- and pc.data_id = t.data_id
356- and pc.item_hash = t.item_hash
357342 ))tmp'
358- using a_join_by_xpath,
343+ using a_join_by_xpath,self.data_id, l_other.data_id,
359344 l_diff_id,
360345 self.data_id, l_other.data_id,
361346 l_other.data_id,self.data_id;
0 commit comments