1 PACKAGE BODY HZ_DQM_MR_PVT AS
2 /* $Header: ARHDIMRB.pls 120.18 2006/07/21 06:24:49 rarajend noship $ */
3 ----------------------------------------------------------------------------------------------------------------
4 ----------------------------------------------------------------------------------------------------------------
5 --- UTILITY FUNCTIONS FOR GETTING MATCH RULE INFO
6 ----------------------------------------------------------------------------------------------------------------
7 ----------------------------------------------------------------------------------------------------------------
8
9
10 TYPE score_rec_type IS RECORD (
11 sum_score NUMBER,
12 max_score NUMBER,
13 min_score NUMBER
14 );
15
16
17 /*
18 -- just to debug execute immediate
19 -- if in case we use dynamic sql in our match rules
20 PROCEDURE sl(str VARCHAR2) IS
21 refstr1 varchar2(32000);
22 refstr2 varchar2(32000);
23 refstr3 varchar2(32000);
24 refstr4 varchar2(32000);
25 refstr5 varchar2(32000);
26 refstr6 varchar2(32000);
27 refstr7 varchar2(32000);
28 refstr8 varchar2(32000);
29
30
31 BEGIN
32 -- SPIT OUT ONLY IF DEBUG FLAG IS ON
33 IF debug_flag = 'Y'
34 THEN
35 refstr1 := replace(str,'''''','#');
36 refstr2 := replace(refstr1,'''');
37 refstr3 := replace(refstr2,'|| #%#', '@');
38 refstr4 := replace(refstr3,'||');
39 refstr5 := replace(refstr4,'@',' || ''%''');
40 refstr6 := replace(refstr5,'#','''');
41 refstr7 := replace(refstr6,'party_join_str');
42 refstr8 := replace(refstr7,'subset_sql');
43 dbms_output.put_line(refstr8);
44 END IF;
45
46 HZ_GEN_PLSQL.add_line(str);
47 END;
48 */
49
50 -- Alias dbms.put_line, to avoid typing
51 PROCEDURE l(str VARCHAR2) IS
52 BEGIN
53 HZ_GEN_PLSQL.add_line(str);
54 END;
55
56
57 FUNCTION get_misc_scores(p_match_rule_id number)
58 return score_rec_type
59 IS
60 CURSOR c0
61 IS
62 select sum(sc) sum_score , max(sc) max_score , min(sc) min_score
63 from
64 (select entity_name ename, sum(score) sc
65 from hz_trans_attributes_vl a, hz_match_rule_secondary s
66 where s.match_rule_id = p_match_rule_id
67 and s.attribute_id = a.attribute_id
68 group by entity_name
69 order by sum(score) desc
70 );
71 srt score_rec_type ;
72 BEGIN
73 -- initialise the record type , just to make sure
74 srt.sum_score := 0 ;
75 srt.max_score := 0 ;
76 srt.min_score := 0 ;
80 srt.sum_score := score_rec.sum_score;
77
78 FOR score_rec IN c0
79 LOOP
81 srt.max_score := score_rec.max_score;
82 srt.min_score := score_rec.min_score;
83 END LOOP;
84 return srt ;
85 END;
86
87 FUNCTION get_match_threshold (p_match_rule_id number)
88 RETURN number
89 IS
90 CURSOR c0
91 IS
92 select match_score
93 from hz_match_rules_vl
94 where match_rule_id = p_match_rule_id;
95 l_yn number ;
96 result VARCHAR2(1);
97 BEGIN
98 OPEN c0;
99 FETCH c0 INTO l_yn;
100 CLOSE c0;
101 RETURN l_yn ;
102 END get_match_threshold ;
103
104
105 FUNCTION get_auto_merge_threshold (p_match_rule_id number)
106 RETURN number
107 IS
108 CURSOR c0
109 IS
110 select auto_merge_score
111 from hz_match_rules_vl
112 where match_rule_id = p_match_rule_id;
113 l_yn number ;
114 result VARCHAR2(1);
115 BEGIN
116 OPEN c0;
117 FETCH c0 INTO l_yn;
118 CLOSE c0;
119 RETURN l_yn ;
120 END get_auto_merge_threshold ;
121
122
123 FUNCTION get_match_all_flag (p_match_rule_id number)
124 RETURN varchar2
125 IS
126 CURSOR c0
127 IS
128 select match_all_flag
129 from hz_match_rules_vl
130 where match_rule_id = p_match_rule_id;
131 result VARCHAR2(1);
132 BEGIN
133 OPEN c0;
134 FETCH c0 INTO result ;
135 CLOSE c0;
136 RETURN result ;
137 END get_match_all_flag ;
138
139
140 FUNCTION has_party_filter_attributes (p_match_rule_id number)
141 RETURN varchar2
142 IS
143 result VARCHAR2(1) := 'N' ;
144 filter_count number := 0;
145 BEGIN
146
147 SELECT count(1) into filter_count
148 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
149 where p.match_rule_id=p_match_rule_id
150 and p.attribute_id=a.attribute_id
151 and a.entity_name = 'PARTY'
152 and p.filter_flag = 'Y';
153 IF filter_count > 0
154 THEN
155 result := 'Y';
156 END IF;
157
158 return result;
159 END has_party_filter_attributes ;
160
161 FUNCTION has_entity_filter_attributes (p_match_rule_id number, p_entity_name in varchar2)
162 RETURN varchar2
163 IS
164 result VARCHAR2(1) := 'N' ;
165 filter_count number := 0;
166 BEGIN
167
168 SELECT count(1) into filter_count
169 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
170 where p.match_rule_id=p_match_rule_id
171 and p.attribute_id=a.attribute_id
172 and a.entity_name = p_entity_name
173 and p.filter_flag = 'Y';
174 IF filter_count > 0
175 THEN
176 result := 'Y';
177 END IF;
178
179 return result;
180 END has_entity_filter_attributes ;
181
182 -- will return true if this match rule has scoring attributes, for the passed in entity
183 FUNCTION has_scoring_attributes ( p_match_rule_id IN NUMBER, p_entity_name IN VARCHAR2)
184 RETURN BOOLEAN
185 IS
186 temp BOOLEAN := FALSE ;
187 BEGIN
188 FOR attrs in (
189 SELECT s.attribute_id
190 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
191 where a.attribute_id=s.attribute_id
192 and s.match_rule_id=p_match_rule_id
193 and a.entity_name = p_entity_name
194 )
195 LOOP
196 temp := TRUE ;
197 END LOOP;
198 return temp ;
199 END has_scoring_attributes ;
200
201
202 -- will return true if this match rule has any scoring attributes what so ever
203 FUNCTION has_scoring_attributes ( p_match_rule_id IN NUMBER)
204 RETURN BOOLEAN
205 IS
206 temp BOOLEAN := FALSE ;
207 BEGIN
208 IF has_scoring_attributes ( p_match_rule_id, 'PARTY')
209 OR
210 has_scoring_attributes ( p_match_rule_id, 'PARTY_SITES')
211 OR
212 has_scoring_attributes ( p_match_rule_id, 'CONTACTS')
213 OR
214 has_scoring_attributes ( p_match_rule_id, 'CONTACT_POINTS')
215 THEN
216 temp := TRUE;
217 return temp ;
218 END IF;
219 return temp;
220 END has_scoring_attributes ;
221
222 -------------------------------------------------------------------------
223 -- get_insert_threshold : This will return the threshold that needs
224 -- to be exceeded by every party level dup identification insert statement
225 -- in the generated code for the match rule
226 -------------------------------------------------------------------------
227
228
229 FUNCTION get_insert_threshold ( p_match_rule_id NUMBER)
230 return number
231 IS
232 CURSOR entity_cur IS
233 select entity_name, sum(score) sc
234 from hz_trans_attributes_vl a, hz_match_rule_secondary s
235 where s.match_rule_id = p_match_rule_id
236 and s.attribute_id = a.attribute_id
237 group by entity_name
238 order by sum(score) desc ;
239 srt score_rec_type;
240 threshold number;
241 row_count number;
242 match_score number;
243 no_of_entities number;
244 match_all_flag varchar2(1);
245 insert_threshold number;
246 BEGIN
247
248
249
250 -- Get the threshold and match_all_flag
251 select match_score, match_all_flag into match_score, match_all_flag
252 from hz_match_rules_vl
253 where match_rule_id = p_match_rule_id;
254
255 -- threhold for the most part is the match-score, except that
256 -- we would change it according to the match_all_flag
257 -- to force inserts and updates in a certain way
258 threshold := match_score;
259
260 -- we want to capture the insert threshold for insert statements
261 -- insert_threshold = (match score - sum of update entity scores)
262 -- first, we initialize it by making it as big as the match score itself
263 insert_threshold := match_score ;
264
265 -- Get the different aggregates that would help in determining the template
266 -- that need to be used -- UNION/UPDATE for the corresponding entity.
267 srt := get_misc_scores(p_match_rule_id);
268
269 -- Initialize the number of entities
270 no_of_entities := 0;
271
272 -- Get the number of entities
273 FOR c0 in entity_cur
274 LOOP
275 no_of_entities := no_of_entities + 1;
276 END LOOP;
277
278
279 -- Before generating the code for the given match rule, we look at the
280 -- match_all_flag to determine, the structure of the code that needs
281 -- to go into the generated match rule package.
282 -- The flag is always assumed to be 'N' by default ie., a match on ANY of the
283 -- entities, would be given consideration.
284 -- If flag = 'Y', then we need to make sure that every query after the first
285 -- one is an update. We make this happen by manually setting the threshold.
286
287 IF match_all_flag = 'Y'
288 THEN
289 threshold := srt.sum_score;
290 END IF;
291
292 -- Open the entity cursor, determine the templates (INSERT/UPDATE) for each
293 -- entity and keep substracting the score for every update entity
294 -- from insert_threshold
295 row_count := 0;
296
297 FOR entity_cur_rec in entity_cur
298 LOOP
299 row_count := row_count + 1;
300 IF row_count = 2
301 THEN
302 IF (srt.sum_score - srt.max_score - threshold) < 0
303 THEN
304 insert_threshold := insert_threshold - entity_cur_rec.sc ;
305 END IF;
306 END IF;
307
308 IF row_count = 3
309 THEN
310 IF no_of_entities = 3
311 THEN
312 IF (entity_cur_rec.sc - threshold) < 0
313 THEN
314 insert_threshold := insert_threshold - entity_cur_rec.sc ;
315 END IF;
316
317 ELSE
318 IF ( entity_cur_rec.sc + srt.min_score - threshold) < 0
319 THEN
320 insert_threshold := insert_threshold - entity_cur_rec.sc ;
321 END IF;
322 END IF;
323 END IF;
324
325 IF row_count = 4
326 THEN
327 IF (entity_cur_rec.sc - threshold) < 0
328 THEN
329 insert_threshold := insert_threshold - entity_cur_rec.sc ;
330 END IF;
331 END IF;
332
333 END LOOP;
334
335 return insert_threshold;
336 END;
337
338 -----------------------------------------------------------------------------------------------
339 -----------------------------------------------------------------------------------------------
340 -- MATCH RULE GENERATION FOR SPEC
341 -----------------------------------------------------------------------------------------------
342 -----------------------------------------------------------------------------------------------
343
344
345 -------------------------------------------------------------------------
346 -- gen_pkg_spec: A Private procedure that will generate the package spec
347 -- of the match rule
348 -------------------------------------------------------------------------
349
350
351 PROCEDURE gen_pkg_spec (
352 p_pkg_name IN VARCHAR2,
353 p_match_rule_id IN NUMBER
354 )
355 IS
356 BEGIN
357 l('CREATE or REPLACE PACKAGE ' || p_pkg_name || ' AUTHID CURRENT_USER AS');
358 l('PROCEDURE tca_join_entities(trap_explosion in varchar2, rows_in_chunk in number,inserted_duplicates out number);');
359 HZ_IMP_DQM_STAGE.gen_pkg_spec(p_pkg_name, p_match_rule_id);
360 l('');
361 l('');
362 l('PROCEDURE interface_tca_join_entities(p_batch_id in number,');
363 l(' from_osr in varchar2, to_osr in varchar2, p_threshold in number, p_auto_merge_threshold in number);');
364 l('');
365 l('');
366 l('PROCEDURE interface_join_entities(p_batch_id in number,');
367 l(' from_osr in varchar2, to_osr in varchar2, p_threshold in number);');
368 l('END ;');
369
370 END;
371
372
373 -------------------------------------------------------------------------
374 -- gen_footer:
375 -------------------------------------------------------------------------
376 PROCEDURE gen_footer
377 IS
378 BEGIN
379 l('END;');
380 END;
381
382
383 -----------------------------------------------------------------------------------------------
384 -----------------------------------------------------------------------------------------------
385 -- MATCH RULE GENERATION FOR TCA JOIN
386 -----------------------------------------------------------------------------------------------
387 -----------------------------------------------------------------------------------------------
388
389
390 -------------------------------------------------------------------------
391 -- gen_header_tca :
392 -------------------------------------------------------------------------
393 PROCEDURE gen_header_tca (
394 p_pkg_name IN VARCHAR2,
395 p_match_rule_id IN NUMBER
396 )
397 IS
398 temp number;
399 BEGIN
400 l('CREATE or REPLACE PACKAGE BODY ' || p_pkg_name || ' AS');
401 HZ_IMP_DQM_STAGE.gen_pkg_body(p_pkg_name, p_match_rule_id);
402 l('');
403 l('');
404 l('');
405 l('');
406 l('---------------------------------------------------------------');
407 l('-------------------- TCA JOIN BEGINS --------------------------');
408 l('---------------------------------------------------------------');
409 l('PROCEDURE tca_join_entities(trap_explosion in varchar2, rows_in_chunk in number, inserted_duplicates out number)');
410 l('IS');
411 l(' x_ent_cur HZ_DQM_DUP_ID_PKG.EntityCur;');
412 temp := get_insert_threshold(p_match_rule_id);
413 l(' x_insert_threshold number := ' || temp || ';');
414 l(' l_party_limit NUMBER := 50000;');
415 l(' l_detail_limit NUMBER := 100000;');
416 l('BEGIN');
417 l('FND_FILE.put_line(FND_FILE.log,''Start time of insert of Parties ''||to_char(sysdate,''hh24:mi:ss''));');
418 l('insert into hz_dup_results(fid, tid, ord_fid, ord_tid, score)');
419 l('select f, t, least(f,t), greatest(f,t), sum(score) score from (');
420 END;
421
422
423 -------------------------------------------------------------------------
424 -- gen_footer_tca : A Private procedure that will generate the footer
425 -- for the package body of the match rule
426 -------------------------------------------------------------------------
427 PROCEDURE gen_footer_tca(p_pkg_name VARCHAR2)
428 IS
429 BEGIN
430 l('');
431 l('');
432 l('---------- exception block ---------------');
433 l('EXCEPTION');
434 l('WHEN OTHERS THEN');
435 l(' IF sqlcode=-1722');
436 l(' THEN');
437 l(' inserted_duplicates := -1;');
438 l(' ELSE');
439 l(' FND_MESSAGE.SET_NAME(''AR'', ''HZ_DQM_API_ERROR'');');
440 l(' FND_MESSAGE.SET_TOKEN(''PROC'',''' || p_pkg_name || '.tca_join_entities'');');
441 l(' FND_MESSAGE.SET_TOKEN(''ERROR'' ,SQLERRM );');
442 l(' FND_MSG_PUB.ADD;');
443 l(' RAISE FND_API.G_EXC_UNEXPECTED_ERROR;');
444 l(' END IF;');
445 l('END tca_join_entities;');
446 END;
447
448 -------------------------------------------------------------------------
449 -- gen_insert_template_tca :
450 -------------------------------------------------------------------------
451 PROCEDURE gen_insert_template_tca(
452 p_table VARCHAR2,
453 p_match_rule_id NUMBER,
454 p_entity VARCHAR2,
455 p_match_all_flag VARCHAR2
456 )
457 IS
458 FIRST BOOLEAN ;
459 FIRST1 BOOLEAN;
460 no_primary_attr_rows number := 0 ;
461 row_count number := 0;
462 outer_row_count number := 0 ;
463 inner_row_counter number := 0;
464 outer_row_counter number := 0;
465 match_all_flag varchar2(1);
466
467 BEGIN
468
469
470 -- aggregation should happen only for non party entities
471 IF p_entity <> 'PARTY'
472 THEN
473 l('select f, t, max(score) score from (');
474 END IF;
475
476 l('select /*+ ORDERED */ s1.party_id f, s2.party_id t,');
477
478 l('-------' || p_entity || ' ENTITY: SCORING SECTION ---------');
479
480 SELECT count(1) into outer_row_count
481 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
482 where a.attribute_id=s.attribute_id
483 and s.match_rule_id=p_match_rule_id
484 and a.entity_name = p_entity;
485
486 IF has_scoring_attributes(p_match_rule_id, p_entity)
487 THEN
488 -- Generate the Secondary Attribute section of the query for the passed in entity
489 FOR attrs in (
490 SELECT score,s.attribute_id , secondary_attribute_id
491 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
492 where a.attribute_id=s.attribute_id
493 and s.match_rule_id=p_match_rule_id
494 and a.entity_name = p_entity)
495 LOOP
496 outer_row_counter := outer_row_counter + 1;
497 inner_row_counter := 0;
498
499 FOR trans in (
500 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
501 FROM hz_secondary_trans st, hz_trans_functions_vl f
502 where f.function_id=st.function_id
503 and st.secondary_attribute_id = attrs.secondary_attribute_id
504 order by transformation_weight desc)
505 LOOP
506 inner_row_counter := inner_row_counter + 1;
507 l('decode(instrb(s2.'||trans.staged_attribute_column
508 || ',s1.'||trans.staged_attribute_column||
509 '),1,'|| trans.score||',');
510
511 END LOOP;
512
513 l('0');
514
515 -- Need to have as many right parentheses as inner_row_counter
516 FOR I IN 1 .. inner_row_counter
517 LOOP
518 l(')');
519 END LOOP;
520
521 IF outer_row_counter < outer_row_count
522 THEN
523 l(' + ');
524 END IF;
525 END LOOP;
526 ELSE
527 l('0 ');
528 END IF;
529
530 l(' score ');
531 l('from hz_dup_worker_chunk_gt p, '||p_table||' s1, '||p_table||' s2');
532 l('where p.party_id = s1.party_id and s1.party_id<>s2.party_id ');
533
534 --Adding the condition of 'Status = A' below, to fix bug 4669400.
535 --This will make sure that the Merged and Inactive Parties (with status as 'M' and 'I')
536 --will not be considered for duplicate idenfication.
537
538 -- Status flag should be checked only for Party entity
539 IF p_entity = 'PARTY' THEN
540 l('and nvl(s1.status,''A'') = ''A'' and nvl(s2.status,''A'') = ''A'' ');
541 END IF;
542
543 -- To make sure that the detail records (party sites, contacts and contact points) are
544 -- are considered for duplicate indentification, only if the parent party is Active.
545 IF p_entity <> 'PARTY' THEN
546 l('and exists(SELECT 1 from hz_staged_parties q where q.party_id = s2.party_id and nvl(q.status,''A'') = ''A'') ');
547 END IF;
548
549 -- SET CHUNK EXPLOSION LIMIT
550 IF p_entity = 'PARTY'
551 THEN
552 l('and 1=decode(trap_explosion,''N'',1,decode(rownum,l_party_limit,to_number(''A''),1))');
553 ELSE
554 l('and 1=decode(trap_explosion,''N'',1,decode(rownum,l_detail_limit,to_number(''A''),1))');
555 END IF;
556
557 l('and (');
558
559 -- Generate the Primary Attribute section of the query for the passed in entity
560 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
561 FIRST1 := TRUE;
562 FOR attrs in (
563 SELECT primary_attribute_id
564 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
565 where p.match_rule_id=p_match_rule_id
566 and p.attribute_id=a.attribute_id
567 and a.entity_name = p_entity
568 and nvl(p.filter_flag,'N') = 'N' )
569 LOOP
570 -- between attributes
571 IF FIRST1
572 THEN
573 FIRST1 := FALSE;
574 l('-------' || p_entity || ' ENTITY: ACQUISITION ON NON-FILTER ATTRIBUTES---------');
575 ELSE
576 IF p_match_all_flag = 'Y'
577 THEN
578 l('and');
579 ELSE
580 l('or');
581 END IF;
582
583 END IF;
584
585 FIRST := TRUE;
586 FOR trans in ( SELECT staged_attribute_column
587 FROM hz_primary_trans pt, hz_trans_functions_vl f
588 where f.function_id = pt.function_id
589 and pt.primary_attribute_id = attrs.primary_attribute_id
590 )
591 LOOP
592 IF FIRST
593 THEN
594 l('-- do an or between all the transformations of an attribute -- ');
595 l('(');
596 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
597 's2.'|| trans.staged_attribute_column || ' like s1.'||
598 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
599 FIRST := FALSE;
600 ELSE
601 l('or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
602 's2.'|| trans.staged_attribute_column || ' like s1.'||
603 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
604 END IF;
605
606 END LOOP;
607 l(')');
608 END LOOP;
609 l(')');
610
611 -- NOW, TAKE CARE OF ENTITY FILTER ATTRIBUTES FOR ALL ENTITIES
612 -- OTHER THAN PARTIES
613 IF p_entity <> 'PARTY' AND has_entity_filter_attributes(p_match_rule_id, p_entity)= 'Y'
614 THEN
615 FIRST1 := TRUE;
616 FOR attrs in (
617 SELECT primary_attribute_id
618 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
619 where p.match_rule_id=p_match_rule_id
620 and p.attribute_id=a.attribute_id
621 and a.entity_name = p_entity
622 and nvl(p.filter_flag,'N') = 'Y' )
623 LOOP
624 IF FIRST1
625 THEN
626 FIRST1 := FALSE;
627 l('-------' || p_entity || ' ENTITY: ACQUISITION ON FILTER ATTRIBUTES---------');
628 END IF;
629
630 -- between attributes
631 l('and');
632
633 FIRST := TRUE;
634 FOR trans in ( SELECT staged_attribute_column
635 FROM hz_primary_trans pt, hz_trans_functions_vl f
636 where f.function_id = pt.function_id
637 and pt.primary_attribute_id = attrs.primary_attribute_id
638 )
639 LOOP
640 IF FIRST
641 THEN
642 l('-- do an or between all the transformations of an attribute -- ');
643 l('(');
644 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
645 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
646 's2.'|| trans.staged_attribute_column || ' = s1.'||
647 trans.staged_attribute_column || ')');
648 FIRST := FALSE;
649 ELSE
650 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
651 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
652 's2.'|| trans.staged_attribute_column || ' = s1.'||
653 trans.staged_attribute_column || ')');
654 END IF;
655
656 END LOOP;
657 l(')');
658 END LOOP;
659 END IF;
660
661 -- complete aggregation for non party entities
662 IF p_entity <> 'PARTY'
663 THEN
664 l(' ) group by f, t ');
665 END IF;
666
667
668
669 END;
670
671
672 -------------------------------------------------------------------------
673 -- gen_insert_footer_tca : A Private procedure that will generate the footer
674 -- for the union part of the package body of the match rule
675 -------------------------------------------------------------------------
676 PROCEDURE gen_insert_footer_tca(p_match_rule_id number)
677 IS
678 FIRST1 boolean;
679 FIRST boolean;
680 BEGIN
681
682 l(' )');
683
684 -- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES
685 IF has_party_filter_attributes(p_match_rule_id)= 'Y'
686 THEN
687 l('------- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES---------');
688 l('where EXISTS (');
689 l('SELECT 1 FROM HZ_STAGED_PARTIES p1, HZ_STAGED_PARTIES p2');
690 l('WHERE p1.party_id = f and p2.party_id = t');
691 FIRST1 := TRUE;
692 FOR attrs in (
693 SELECT primary_attribute_id
694 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
695 where p.match_rule_id=p_match_rule_id
696 and p.attribute_id=a.attribute_id
697 and a.entity_name = 'PARTY'
698 and nvl(p.filter_flag,'N') = 'Y' )
699 LOOP
700 IF FIRST1
701 THEN
705 -- between attributes
702 FIRST1 := FALSE;
703 END IF;
704
706 l('and');
707
708 FIRST := TRUE;
709 FOR trans in ( SELECT staged_attribute_column
710 FROM hz_primary_trans pt, hz_trans_functions_vl f
711 where f.function_id = pt.function_id
712 and pt.primary_attribute_id = attrs.primary_attribute_id
713 )
714 LOOP
715 IF FIRST
716 THEN
717 l('-- do an or between all the transformations of an attribute -- ');
718 l('(');
719 l('((p1.'|| trans.staged_attribute_column || ' is null and ' ||
720 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
721 'p2.'|| trans.staged_attribute_column || ' = p1.'||
722 trans.staged_attribute_column || ')');
723 FIRST := FALSE;
724 ELSE
725 l('or ((p1.'|| trans.staged_attribute_column || ' is null and ' ||
726 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
727 'p2.'|| trans.staged_attribute_column || ' = p1.'||
728 trans.staged_attribute_column || ')');
729 END IF;
730
731 END LOOP;
732 l(')');
733 END LOOP;
734 l(')');
735 END IF;
736
737 l('group by f, t ');
738
739 -- having clause should exist only if x_insert_threshold
740 -- is positive
741 IF get_insert_threshold(p_match_rule_id) > 0
742 THEN
743 l('having sum(score) >= x_insert_threshold');
744 END IF;
745
746 l(';');
747 l('inserted_duplicates := (SQL%ROWCOUNT);');
748 l('FND_FILE.put_line(FND_FILE.log,''Number of parties inserted ''||SQL%ROWCOUNT);');
749 l('FND_FILE.put_line(FND_FILE.log,''End time of insert ''||to_char(sysdate,''hh24:mi:ss''));');
750 l('FND_CONCURRENT.AF_Commit;');
751
752 END;
753
754
755 -------------------------------------------------------------------------
756 -- gen_update_template_tca : A Private procedure that will generate the header
757 -- for the package body of the match rule
758 -------------------------------------------------------------------------
759 PROCEDURE gen_update_template_tca (
760 p_table VARCHAR2,
761 p_match_rule_id NUMBER,
762 p_entity VARCHAR2,
763 p_match_all_flag VARCHAR2
764 )
765 IS
766 FIRST BOOLEAN ;
767 FIRST1 BOOLEAN;
768 outer_row_count number := 0 ;
769 inner_row_counter number := 0;
770 outer_row_counter number := 0;
771
772 BEGIN
773
774 l('');
775 l('');
776 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
777 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Beginning update of Parties on the basis of ' || p_entity || ''''|| ');');
778 l('FND_FILE.put_line(FND_FILE.log,''Start time of update ''||to_char(sysdate,''hh24:mi:ss''));');
779 l('open x_ent_cur for');
780
781 -- aggregation should happen only for non party entities
782 IF p_entity <> 'PARTY'
783 THEN
784 l('select f, t, max(score) score from (');
785 END IF;
786
787 l(' select /*+ ORDERED */ s1.party_id f, s2.party_id t,');
788
789
790 SELECT count(1) into outer_row_count
791 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
792 where a.attribute_id=s.attribute_id
793 and s.match_rule_id=p_match_rule_id
794 and a.entity_name = p_entity;
795
796 IF has_scoring_attributes(p_match_rule_id, p_entity)
797 THEN
798
799 -- Generate the Secondary Attribute section of the query for the passed in entity
800 FOR attrs in (
801 SELECT score,s.attribute_id , secondary_attribute_id
802 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
803 where a.attribute_id=s.attribute_id
804 and s.match_rule_id=p_match_rule_id
805 and a.entity_name = p_entity)
806 LOOP
807 outer_row_counter := outer_row_counter + 1;
808 inner_row_counter := 0;
809
810 FOR trans in (
811 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
812 FROM hz_secondary_trans st, hz_trans_functions_vl f
813 where f.function_id=st.function_id
814 and st.secondary_attribute_id = attrs.secondary_attribute_id
815 order by transformation_weight desc)
816 LOOP
817 inner_row_counter := inner_row_counter + 1;
818 l('decode(instrb(s2.'||trans.staged_attribute_column
819 || ',s1.'||trans.staged_attribute_column||
820 '),1,'|| trans.score||',');
821
822 END LOOP;
823
824 l('0');
825
826 -- Need to have as many right parentheses as inner_row_counter
827 FOR I IN 1 .. inner_row_counter
831
828 LOOP
829 l(')');
830 END LOOP;
832 IF outer_row_counter < outer_row_count
833 THEN
834 l('+');
835 END IF;
836 END LOOP;
837 ELSE
838 l('0 ');
839 END IF;
840
841 l('score');
842 l('from hz_dup_worker_chunk_gt p, hz_dup_results h1, '||p_table||' s1, '||p_table||' s2');
843 l('where p.party_id=h1.fid and s1.party_id = h1.fid and s2.party_id = h1.tid');
844 l('and ( ');
845
846 -- Generate the Primary Attribute section of the query for the passed in entity
847 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
848 FIRST1 := TRUE;
849 -- Generate the Primary Attribute section of the query for the passed in entity
850 FOR attrs in (
851 SELECT primary_attribute_id
852 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
853 where p.match_rule_id=p_match_rule_id
854 and p.attribute_id=a.attribute_id
855 and a.entity_name = p_entity
856 and nvl(p.filter_flag,'N') = 'N' )
857 LOOP
858 -- between attributes
859 IF FIRST1
860 THEN
861 FIRST1 := FALSE;
862 l('------------ NON FILTER ATTRIBUTES SECTION ------------------------');
863 ELSE
864 IF p_match_all_flag = 'Y'
865 THEN
866 l('and');
867 ELSE
868 l('or');
869 END IF;
870
871 END IF;
872
873 FIRST := TRUE;
874 FOR trans in ( SELECT staged_attribute_column
875 FROM hz_primary_trans pt, hz_trans_functions_vl f
876 where f.function_id = pt.function_id
877 and pt.primary_attribute_id = attrs.primary_attribute_id
878 )
879 LOOP
880 IF FIRST
881 THEN
882 l('-- do an or between all the transformations of an attribute -- ');
883 l('(');
884 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
885 's2.'|| trans.staged_attribute_column || ' like s1.'||
886 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
887 FIRST := FALSE;
888 ELSE
889 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
890 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
891 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
892 END IF;
893
894 END LOOP;
895 l(')');
896
897 END LOOP;
898 l(')');
899
900 -- NOW TAKE CARE OF FILTER ATTRIBUTES FIRST
901 FIRST1 := TRUE;
902 FOR attrs in (
903 SELECT primary_attribute_id
904 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
905 where p.match_rule_id=p_match_rule_id
906 and p.attribute_id=a.attribute_id
907 and a.entity_name = p_entity
908 and nvl(p.filter_flag,'N') = 'Y' )
909 LOOP
910 -- between attributes
911 IF FIRST1
912 THEN
913 FIRST1 := FALSE;
914 l('------------ FILTER ATTRIBUTES SECTION ------------------------');
915 END IF;
916
917 -- between attributes
918 l('and ');
919
920
921 FIRST := TRUE;
922 FOR trans in ( SELECT staged_attribute_column
923 FROM hz_primary_trans pt, hz_trans_functions_vl f
924 where f.function_id = pt.function_id
925 and pt.primary_attribute_id = attrs.primary_attribute_id
926 )
927 LOOP
928 IF FIRST
929 THEN
930 l('-- do an or between all the transformations of an attribute -- ');
931 l('(');
932 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
933 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
934 's2.'|| trans.staged_attribute_column || ' = s1.'||
935 trans.staged_attribute_column || ')');
936 FIRST := FALSE;
937 ELSE
938 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
939 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
940 's2.'|| trans.staged_attribute_column || ' = s1.'||
941 trans.staged_attribute_column || ')');
942 END IF;
943
944 END LOOP;
945 l(')');
946 END LOOP;
947
948
949 -- aggregation should happen only for non party entities
950 IF p_entity <> 'PARTY'
951 THEN
952 l(') group by f,t ;');
953 ELSE
954 l(';');
955 END IF;
956
957 l('HZ_DQM_DUP_ID_PKG.update_hz_dup_results(x_ent_cur);');
958 l('close x_ent_cur;');
962 l('FND_CONCURRENT.AF_Commit;');
959 l('FND_FILE.put_line(FND_FILE.log,''Number of parties updated ''||SQL%ROWCOUNT);');
960 l('FND_FILE.put_line(FND_FILE.log,''End time to update ''||to_char(sysdate,''hh24:mi:ss''));');
961 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Ending update of Parties on the basis of ' || p_entity || ''''|| ');');
963 END;
964
965
966
967
968 PROCEDURE gen_pkg_body_tca_join (
969 p_pkg_name IN VARCHAR2,
970 p_match_rule_id IN NUMBER,
971 p_att_flag IN VARCHAR2
972 )
973 IS
974
975 CURSOR entity_cur IS
976 select entity_name, entity_table_name, sc, att_flag
977 from
978 (select entity_name, decode(entity_name,
979 'PARTY','HZ_STAGED_PARTIES',
980 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
981 'CONTACTS','HZ_STAGED_CONTACTS',
982 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
983 sum(score) sc, 'S' att_flag
984 from hz_trans_attributes_vl a, hz_match_rule_secondary s
985 where s.match_rule_id = p_match_rule_id
986 and s.attribute_id = a.attribute_id
987 group by entity_name
988 union all
989 select entity_name, decode(entity_name,
990 'PARTY','HZ_STAGED_PARTIES',
991 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
992 'CONTACTS','HZ_STAGED_CONTACTS',
993 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
994 0 sc, 'P' att_flag
995 from hz_trans_attributes_vl a, hz_match_rule_primary p
996 where p.match_rule_id = p_match_rule_id
997 and p.attribute_id = a.attribute_id
998 group by entity_name
999 )
1000 where att_flag = p_att_flag
1001 order by sc desc ;
1002 srt score_rec_type;
1003 threshold number;
1004 row_count number;
1005 no_of_entities number;
1006 template varchar2(30);
1007 match_all_flag varchar2(1);
1008 insert_stmt_is_open boolean;
1009 BEGIN
1010
1011 -- dbms_output.put_line('Attribute flag is ' || p_att_flag );
1012 -- Get the threshold and match_all_flag
1013 select match_score, match_all_flag into threshold, match_all_flag
1014 from hz_match_rules_vl
1015 where match_rule_id = p_match_rule_id;
1016
1017 -- Get the different aggregates that would help in determining the template
1018 -- that need to be used -- UNION/UPDATE for the corresponding entity.
1019
1020 -- If attribute flag is 'P', make the threshold 0
1021 -- This signifies that the match rule has no scoring attributes
1022 IF p_att_flag = 'P'
1023 THEN
1024 threshold := 0;
1025 srt.sum_score := 0;
1026 srt.min_score := 0;
1027 srt.max_score := 0;
1028 ELSE
1029 srt := get_misc_scores(p_match_rule_id);
1030 END IF;
1031
1032
1033 -- Initialize the number of entities
1034 no_of_entities := 0;
1035
1036
1037 -- Get the number of entities
1038
1039 FOR c0 in entity_cur
1040 LOOP
1041 no_of_entities := no_of_entities + 1;
1042 END LOOP;
1043
1044
1045 -- Before generating the code for the given match rule, we look at the
1046 -- match_all_flag to determine, the structure of the code that needs
1047 -- to go into the generated match rule package.
1048 -- The flag is always assumed to be 'N' by default ie., a match on ANY of the
1049 -- entities, would be given consideration.
1050 -- If flag = 'Y', then we need to make sure that every query after the first
1051 -- one is an update. We make this happen by manually setting the threshold.
1052 IF match_all_flag = 'Y'
1053 THEN
1054 threshold := srt.sum_score;
1055 END IF;
1056
1057
1058 -- Generate the Header
1059 gen_header_tca(p_pkg_name, p_match_rule_id);
1060
1061 -- Open the entity cursor, determine the templates (INSERT/UPDATE) for each
1062 -- and call the appropriate function to add lines to the generated package
1063 -- for the corresponding entity
1064 row_count := 0;
1065 insert_stmt_is_open := false;
1066
1067 -- some basic observations that would help in this logic
1068 -- 1. There will always be atleast one insert statement
1069 -- 2. all insert templates would come under the insert statement
1070 -- 3. all update templates are modular and do not need any special treatment for opening and closing.
1071 -- 4. all update templates would be together
1072 -- 5. when generating an update template, we need to make sure that the insert statement is closed.
1073 -- 6. in the event that we never have an update template, we close the insert statement, outside the loop.
1074 FOR entity_cur_rec in entity_cur
1075 LOOP
1076 row_count := row_count + 1;
1077
1078 -- First row, is always an insert, unless the match rule returns nothing due
1079 -- to an erroneous combination of the threshold/match rule configuration.
1080 -- If that happnes we , get the hell out of here.
1081 IF row_count = 1
1082 THEN
1083 -- pass the first entity forcefully
1084 IF (srt.sum_score - threshold) >= 0
1085 THEN
1086 -- dbms_output.put_line('about insert for first entity');
1090 ELSE
1087 gen_insert_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1088 match_all_flag);
1089 insert_stmt_is_open := true;
1091 -- need to handle this by reporting an error and getting the hell out of here.
1092 -- dbms_output.put_line('cannot even insert first entity');
1093 -- dbms_output.put_line('sum score is ' || srt.sum_score );
1094 -- dbms_output.put_line('threshold' || threshold );
1095 -- dbms_output.put_line('sum - threshold is ' || srt.sum_score - threshold );
1096 null;
1097 return ;
1098 END IF;
1099 END IF;
1100
1101 IF row_count = 2
1102 THEN
1103
1104 IF (srt.sum_score - srt.max_score - threshold) >= 0
1105 THEN
1106 l('union all');
1107 gen_insert_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1108 match_all_flag);
1109 ELSE
1110 IF insert_stmt_is_open
1111 THEN
1112 gen_insert_footer_tca(p_match_rule_id);
1113 insert_stmt_is_open := false;
1114 END IF;
1115 gen_update_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1116 match_all_flag);
1117 END IF;
1118 END IF;
1119
1120 IF row_count = 3
1121 THEN
1122 IF no_of_entities = 3
1123 THEN
1124 IF (entity_cur_rec.sc - threshold) >= 0
1125 THEN
1126 l('union all');
1127 gen_insert_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1128 match_all_flag);
1129 ELSE
1130 IF insert_stmt_is_open
1131 THEN
1132 gen_insert_footer_tca(p_match_rule_id);
1133 insert_stmt_is_open := false;
1134 END IF;
1135 gen_update_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1136 match_all_flag);
1137 END IF;
1138
1139 ELSE
1140 IF ( entity_cur_rec.sc + srt.min_score - threshold) >= 0
1141 THEN
1142 l('union all');
1143 gen_insert_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1144 match_all_flag);
1145 ELSE
1146 IF insert_stmt_is_open
1147 THEN
1148 gen_insert_footer_tca(p_match_rule_id);
1149 insert_stmt_is_open := false;
1150 END IF;
1151 gen_update_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1152 match_all_flag);
1153 END IF;
1154 END IF;
1155 END IF;
1156
1157 IF row_count = 4
1158 THEN
1159 IF (entity_cur_rec.sc - threshold) >= 0
1160 THEN
1161 l('union all');
1162 gen_insert_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1163 match_all_flag);
1164 ELSE
1165 IF insert_stmt_is_open
1166 THEN
1167 gen_insert_footer_tca(p_match_rule_id);
1168 insert_stmt_is_open := false;
1169 END IF;
1170 gen_update_template_tca(entity_cur_rec.entity_table_name, p_match_rule_id, entity_cur_rec.entity_name,
1171 match_all_flag);
1172 END IF;
1173 END IF;
1174
1175 END LOOP;
1176
1177 -- Just to make sure that the insert statement is not open, after all the entity queries
1178 -- have been generated
1179 IF insert_stmt_is_open
1180 THEN
1181 gen_insert_footer_tca(p_match_rule_id);
1182 insert_stmt_is_open := false;
1183 END IF;
1184
1185 -- generate the footer for the package
1186 gen_footer_tca(p_pkg_name) ;
1187
1188 END;
1189
1190 PROCEDURE gen_pkg_body_tca_join (
1191 p_pkg_name IN VARCHAR2,
1192 p_match_rule_id IN NUMBER
1193 )
1194 IS
1195 BEGIN
1196 IF has_scoring_attributes(p_match_rule_id)
1197 THEN
1198 gen_pkg_body_tca_join(p_pkg_name, p_match_rule_id, 'S');
1199 ELSE
1200 gen_pkg_body_tca_join(p_pkg_name, p_match_rule_id, 'P');
1201 END IF;
1202 END ;
1203
1204 -----------------------------------------------------------------------------------------------------------
1205 -- MATCH RULE GENERATION FOR THE INTERFACE TCA JOIN
1206 -----------------------------------------------------------------------------------------------------------
1207
1208
1209 -------------------------------------------------------------------------
1210 -- gen_header_int_tca :
1211 -------------------------------------------------------------------------
1212 PROCEDURE gen_header_int_tca (
1213 p_pkg_name IN VARCHAR2,
1214 p_match_rule_id IN NUMBER
1215 )
1216 IS
1217 temp number;
1218 BEGIN
1219 l('');
1220 l('');
1221 l('');
1222 l('');
1223 l('---------------------------------------------------------------');
1224 l('-------------------- INTERFACE TCA JOIN BEGINS --------------------------');
1225 l('---------------------------------------------------------------');
1226 l('PROCEDURE interface_tca_join_entities( p_batch_id in number, from_osr in varchar2, to_osr in varchar2,');
1227 l(' p_threshold in number, p_auto_merge_threshold in number)');
1228 l('IS');
1229 l('x_ent_cur HZ_DQM_DUP_ID_PKG.EntityCur;');
1230 temp := get_insert_threshold(p_match_rule_id);
1231 l('x_insert_threshold number := ' || temp || ';');
1232 l('BEGIN');
1233 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
1234 l('FND_FILE.put_line(FND_FILE.log,''WU: ''||from_osr||'' to ''||to_osr);');
1235 l('FND_FILE.put_line(FND_FILE.log,''Start time of insert of Parties ''||to_char(sysdate,''hh24:mi:ss''));');
1236 l('insert into hz_imp_dup_parties(party_id,dup_party_id, score, party_osr, party_os, batch_id, auto_merge_flag');
1237 l(',created_by,creation_date,last_update_login,last_update_date,last_updated_by)');
1238 l('select f, t, sum(score) sc, party_osr, party_os, p_batch_id, ''N'' ');
1239 l(',hz_utility_v2pub.created_by,hz_utility_v2pub.creation_date,hz_utility_v2pub.last_update_login');
1240 l(',hz_utility_v2pub.last_update_date,hz_utility_v2pub.last_updated_by');
1241 l('from (');
1242 END;
1243
1244
1245 -------------------------------------------------------------------------
1246 -- gen_footer_int_tca:
1247 -------------------------------------------------------------------------
1248 PROCEDURE gen_footer_int_tca(p_pkg_name VARCHAR2)
1249 IS
1250 BEGIN
1251 l('');
1252 l('---------- exception block ---------------');
1253 l('EXCEPTION');
1254 l('WHEN OTHERS THEN');
1255 l(' FND_MESSAGE.SET_NAME(''AR'', ''HZ_DQM_API_ERROR'');');
1256 l(' FND_MESSAGE.SET_TOKEN(''PROC'',''' || p_pkg_name || '.interface_tca_join_entities'');');
1257 l(' FND_MESSAGE.SET_TOKEN(''ERROR'' ,SQLERRM );');
1258 l(' FND_MSG_PUB.ADD;');
1259 l(' RAISE FND_API.G_EXC_UNEXPECTED_ERROR;');
1260 l('END interface_tca_join_entities;');
1261 END;
1262
1263
1264
1265
1266
1267 -------------------------------------------------------------------------
1268 -- gen_insert_template_int_tca :
1269 -------------------------------------------------------------------------
1270 PROCEDURE gen_insert_template_int_tca(
1271 s_table VARCHAR2,
1272 p_table VARCHAR2,
1273 p_match_rule_id NUMBER,
1274 p_entity VARCHAR2,
1275 p_match_all_flag VARCHAR2
1276 )
1277 IS
1278 FIRST BOOLEAN ;
1279 FIRST1 BOOLEAN;
1280 outer_row_count number := 0 ;
1281 inner_row_counter number := 0;
1282 outer_row_counter number := 0;
1283
1284 BEGIN
1285 -- finding the max, applies only to detail information viz., to non-party entities.
1286 IF p_entity <> 'PARTY'
1287 THEN
1288 l('select f, t, max(score) score, party_osr, party_os from (');
1289 END IF;
1290
1291 l('select /*+ USE_CONCAT */ s1.party_id f, s2.party_id t,');
1292
1293 l('-------' || p_entity || ' ENTITY: SCORING SECTION ---------');
1294
1295 SELECT count(1) into outer_row_count
1296 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1297 where a.attribute_id=s.attribute_id
1298 and s.match_rule_id=p_match_rule_id
1299 and a.entity_name = p_entity;
1300
1301 IF has_scoring_attributes(p_match_rule_id, p_entity)
1302 THEN
1303 -- Generate the Secondary Attribute section of the query for the passed in entity
1304 FOR attrs in (
1305 SELECT score,s.attribute_id , secondary_attribute_id
1306 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1307 where a.attribute_id=s.attribute_id
1308 and s.match_rule_id=p_match_rule_id
1309 and a.entity_name = p_entity)
1310 LOOP
1311 outer_row_counter := outer_row_counter + 1;
1312 inner_row_counter := 0;
1313
1314 FOR trans in (
1315 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
1316 FROM hz_secondary_trans st, hz_trans_functions_vl f
1317 where f.function_id=st.function_id
1318 and st.secondary_attribute_id = attrs.secondary_attribute_id
1319 order by transformation_weight desc)
1320 LOOP
1321 inner_row_counter := inner_row_counter + 1;
1322 l('decode(instrb(s2.'||trans.staged_attribute_column
1323 || ',s1.'||trans.staged_attribute_column||
1324 '),1,'|| trans.score||',');
1325
1326 END LOOP;
1327
1328 l('0');
1329
1330 -- Need to have as many right parentheses as inner_row_counter
1331 FOR I IN 1 .. inner_row_counter
1332 LOOP
1333 l(')');
1334 END LOOP;
1335
1336 IF outer_row_counter < outer_row_count
1337 THEN
1338 l('+');
1339 END IF;
1340 END LOOP;
1341 ELSE
1342 l('0 ');
1343 END IF;
1344
1345
1346 l('score , s1.party_osr party_osr, s1.party_os party_os');
1347
1348
1349 -- if the passed in entity is a detail level entity, then we need to make sure
1350 -- that the party level filters ( if any), participate in the join
1351 -- for the detail
1352 IF p_entity <> 'PARTY' AND has_party_filter_attributes(p_match_rule_id)= 'Y'
1353 THEN
1354 l('from '||s_table||' s1, '||p_table||' s2');
1355 ELSE
1356 l('from '||s_table||' s1, '||p_table||' s2 ');
1357 END IF;
1358
1359 -- for the detail
1360
1361 IF p_entity <> 'PARTY'
1362 THEN
1363 l('where s1.party_id is not null and s1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr and s1.new_party_flag = ''I''');
1364 ELSE
1365 l('where s1.party_id is not null and s1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr');
1366 END IF;
1367
1368 --Adding the condition of 'Status = A' below, to fix bug 4669400.
1369 --This will make sure that the Merged and Inactive Parties (with status as 'M' and 'I')
1370 --will not be considered for duplicate idenfication.
1371
1372 -- Status flag should be checked only for Party entity
1373 IF p_entity = 'PARTY' THEN
1374 l('and nvl(s2.status,''A'') = ''A'' ');
1375 END IF;
1376
1377 -- To make sure that the detail records (party sites, contacts and contact points) are
1378 -- are considered for duplicate indentification, only if the parent party is Active.
1379 IF p_entity <> 'PARTY' THEN
1380 l('and exists(SELECT 1 from hz_staged_parties q where q.party_id = s2.party_id and nvl(q.status,''A'') = ''A'') ');
1381 END IF;
1382
1383
1384 l('and ( ');
1385
1386
1387 -- Generate the Primary Attribute section of the query for the passed in entity
1388 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
1389 FIRST1 := TRUE;
1390 -- Generate the Primary Attribute section of the query for the passed in entity
1391 FOR attrs in (
1392 SELECT primary_attribute_id
1393 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1394 where p.match_rule_id=p_match_rule_id
1395 and p.attribute_id=a.attribute_id
1396 and a.entity_name = p_entity
1397 and nvl(p.filter_flag,'N') = 'N' )
1398 LOOP
1399 -- between attributes
1400 IF FIRST1
1401 THEN
1402 FIRST1 := FALSE;
1403 l('-------' || p_entity || ' ENTITY: ACQUISITION ON NON-FILTER ATTRIBUTES ---------');
1404 ELSE
1405 IF p_match_all_flag = 'Y'
1406 THEN
1407 l('and');
1408 ELSE
1409 l('or');
1410 END IF;
1411
1412 END IF;
1413
1414 FIRST := TRUE;
1415 FOR trans in ( SELECT staged_attribute_column
1416 FROM hz_primary_trans pt, hz_trans_functions_vl f
1417 where f.function_id = pt.function_id
1418 and pt.primary_attribute_id = attrs.primary_attribute_id
1419 )
1420 LOOP
1421 IF FIRST
1422 THEN
1423 l('-- do an or between all the transformations of an attribute -- ');
1424 l('(');
1425 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1426 's2.'|| trans.staged_attribute_column || ' like s1.'||
1427 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1428 FIRST := FALSE;
1429 ELSE
1430 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1431 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
1432 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1433 END IF;
1434
1435 END LOOP;
1436 l(')');
1437
1438 END LOOP;
1439 l(')');
1440
1441 -- NOW, TAKE CARE OF ENTITY FILTER ATTRIBUTES FOR ALL ENTITIES
1442 -- OTHER THAN PARTIES
1443 IF p_entity <> 'PARTY' AND has_entity_filter_attributes(p_match_rule_id,p_entity)= 'Y'
1444 THEN
1445 -- NOW TAKE CARE OF FILTER ATTRIBUTES
1446 FIRST1 := TRUE;
1447 FOR attrs in (
1448 SELECT primary_attribute_id
1449 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1450 where p.match_rule_id=p_match_rule_id
1451 and p.attribute_id=a.attribute_id
1452 and a.entity_name = p_entity
1453 and nvl(p.filter_flag,'N') = 'Y' )
1454 LOOP
1455 -- between attributes
1456 IF FIRST1
1457 THEN
1458 FIRST1 := FALSE;
1459 l('-------' || p_entity || ' ENTITY: ACQUISITION ON FILTER ATTRIBUTES ---------');
1460 END IF;
1461
1462 -- between attributes
1463 l('and ');
1464
1465 FIRST := TRUE;
1466 FOR trans in ( SELECT staged_attribute_column
1467 FROM hz_primary_trans pt, hz_trans_functions_vl f
1468 where f.function_id = pt.function_id
1469 and pt.primary_attribute_id = attrs.primary_attribute_id
1470 )
1471 LOOP
1472 IF FIRST
1473 THEN
1474 l('-- do an or between all the transformations of an attribute -- ');
1475 l('(');
1476 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1477 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1478 's2.'|| trans.staged_attribute_column || ' = s1.'||
1479 trans.staged_attribute_column || ' || '' '' )' );
1480 FIRST := FALSE;
1481 ELSE
1482 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1483 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1484 's2.'|| trans.staged_attribute_column || ' = s1.'||
1485 trans.staged_attribute_column || ' || '' '' )' );
1486 END IF;
1487
1488 END LOOP;
1489 l(')');
1490 END LOOP;
1491 END IF;
1492
1493 -- complete the insert statement for non-party entities
1494 IF p_entity <> 'PARTY'
1495 THEN
1496 l(')');
1497 l('group by f, t, party_osr, party_os');
1498 END IF;
1499
1500 END;
1501
1502 -------------------------------------------------------------------------
1503 -- gen_dl_insert_template_int_tca :
1504 -------------------------------------------------------------------------
1505 PROCEDURE gen_dl_insert_template_int_tca(
1506 s_table VARCHAR2,
1507 p_table VARCHAR2,
1508 p_match_rule_id NUMBER,
1509 p_entity VARCHAR2,
1510 p_entity_id_name VARCHAR2,
1511 p_entity_osr_name VARCHAR2,
1512 p_entity_os_name VARCHAR2,
1513 p_match_all_flag VARCHAR2
1514 )
1515 IS
1516 FIRST BOOLEAN ;
1517 FIRST1 BOOLEAN ;
1518 outer_row_count number := 0 ;
1519 inner_row_counter number := 0;
1520 outer_row_counter number := 0;
1521
1522 BEGIN
1523 l('');
1524 l('-------------' || p_entity || ' LEVEL DUPLICATE IDENTIFICATION BEGINS ------------------------');
1525 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
1526 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Beginning insert of ' || p_entity || ''''|| ');');
1527 l('FND_FILE.put_line(FND_FILE.log,''Start time of insert ''||to_char(sysdate,''hh24:mi:ss''));');
1528
1529 -- BUG FIX FOR 4750317, CHANGED ORDER OF INSERTS
1530 l('insert into hz_imp_dup_details(party_id, score, party_osr, party_os, batch_id, entity, record_id, record_osr, record_os, dup_record_id');
1531 l(',created_by,creation_date,last_update_login,last_update_date,last_updated_by)');
1532 l('select /*+ USE_CONCAT */ s1.party_id f,');
1533
1534 SELECT count(1) into outer_row_count
1535 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1536 where a.attribute_id=s.attribute_id
1537 and s.match_rule_id=p_match_rule_id
1538 and a.entity_name = p_entity;
1539
1540 IF has_scoring_attributes(p_match_rule_id, p_entity)
1541 THEN
1542 -- Generate the Secondary Attribute section of the query for the passed in entity
1543 FOR attrs in (
1544 SELECT score,s.attribute_id , secondary_attribute_id
1545 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1546 where a.attribute_id=s.attribute_id
1547 and s.match_rule_id=p_match_rule_id
1548 and a.entity_name = p_entity)
1549 LOOP
1550 outer_row_counter := outer_row_counter + 1;
1551 inner_row_counter := 0;
1552
1553 FOR trans in (
1554 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
1555 FROM hz_secondary_trans st, hz_trans_functions_vl f
1556 where f.function_id=st.function_id
1557 and st.secondary_attribute_id = attrs.secondary_attribute_id
1558 order by transformation_weight desc)
1559 LOOP
1563 '),1,'|| trans.score||',');
1560 inner_row_counter := inner_row_counter + 1;
1561 l('decode(instrb(s2.'||trans.staged_attribute_column
1562 || ',s1.'||trans.staged_attribute_column||
1564
1565 END LOOP;
1566
1567 l('0');
1568
1569 -- Need to have as many right parentheses as inner_row_counter
1570 FOR I IN 1 .. inner_row_counter
1571 LOOP
1572 l(')');
1573 END LOOP;
1574
1575 IF outer_row_counter < outer_row_count
1576 THEN
1577 l('+');
1578 END IF;
1579 END LOOP;
1580 ELSE
1581 l('0 ');
1582 END IF;
1583
1584 l('score , s1.party_osr, s1.party_os, p_batch_id,' || ''''|| p_entity ||'''' ||', s1.' || p_entity_id_name || ', s1.' || p_entity_osr_name || ', s1.' || p_entity_os_name || ',');
1585 l(' s2.' || p_entity_id_name );
1586 l(',hz_utility_v2pub.created_by,hz_utility_v2pub.creation_date,hz_utility_v2pub.last_update_login');
1587 l(',hz_utility_v2pub.last_update_date,hz_utility_v2pub.last_updated_by');
1588 l('from '||s_table||' s1, '||p_table||' s2 ');
1589 l('where s1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr and s1.new_party_flag = ''U''');
1590 l('and s1.party_id = s2.party_id');
1591 l('and ( ');
1592
1593 -- Generate the Primary Attribute section of the query for the passed in entity
1594 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
1595 FIRST1 := TRUE;
1596 -- Generate the Primary Attribute section of the query for the passed in entity
1597 FOR attrs in (
1598 SELECT primary_attribute_id
1599 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1600 where p.match_rule_id=p_match_rule_id
1601 and p.attribute_id=a.attribute_id
1602 and a.entity_name = p_entity
1603 and nvl(p.filter_flag,'N') = 'N' )
1604 LOOP
1605 -- between attributes
1606 IF FIRST1
1607 THEN
1608 FIRST1 := FALSE;
1609 l('------------ NON FILTER ATTRIBUTES SECTION ------------------------');
1610 ELSE
1611 IF p_match_all_flag = 'Y'
1612 THEN
1613 l('and');
1614 ELSE
1615 l('or');
1616 END IF;
1617
1618 END IF;
1619
1620 FIRST := TRUE;
1621 FOR trans in ( SELECT staged_attribute_column
1622 FROM hz_primary_trans pt, hz_trans_functions_vl f
1623 where f.function_id = pt.function_id
1624 and pt.primary_attribute_id = attrs.primary_attribute_id
1625 )
1626 LOOP
1627 IF FIRST
1628 THEN
1629 l('-- do an or between all the transformations of an attribute -- ');
1630 l('(');
1631 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1632 's2.'|| trans.staged_attribute_column || ' like s1.'||
1633 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1634 FIRST := FALSE;
1635 ELSE
1636 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1637 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
1638 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1639 END IF;
1640
1641 END LOOP;
1642 l(')');
1643
1644 END LOOP;
1645 l(')');
1646
1647 -- NOW TAKE CARE OF FILTER ATTRIBUTES
1648 FIRST1 := TRUE;
1649 FOR attrs in (
1650 SELECT primary_attribute_id
1651 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1652 where p.match_rule_id=p_match_rule_id
1653 and p.attribute_id=a.attribute_id
1654 and a.entity_name = p_entity
1655 and nvl(p.filter_flag,'N') = 'Y'
1656 and HZ_IMP_DQM_STAGE.EXIST_COL(a.attribute_name, a.entity_name ) = 'Y'
1657 )
1658 LOOP
1659 -- between attributes
1660 IF FIRST1
1661 THEN
1662 FIRST1 := FALSE;
1663 l('------------ FILTER ATTRIBUTES SECTION ------------------------');
1664 END IF;
1665
1666 l('and ');
1667
1668 FIRST := TRUE;
1669 FOR trans in ( SELECT staged_attribute_column
1670 FROM hz_primary_trans pt, hz_trans_functions_vl f
1671 where f.function_id = pt.function_id
1672 and pt.primary_attribute_id = attrs.primary_attribute_id
1673 )
1674 LOOP
1675 IF FIRST
1676 THEN
1677 l('-- do an or between all the transformations of an attribute -- ');
1678 l('(');
1679 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1680 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1681 's2.'|| trans.staged_attribute_column || ' = s1.'||
1682 trans.staged_attribute_column || ' || '' '' )' );
1683 FIRST := FALSE;
1684 ELSE
1685 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1686 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1687 's2.'|| trans.staged_attribute_column || ' = s1.'||
1688 trans.staged_attribute_column || ' || '' '' )' );
1689 END IF;
1690
1691 END LOOP;
1692 l(')');
1693 END LOOP;
1694
1695 -- IF THE ENTITY IS NOT A PARTY THEN WE NEED TO MAKE SURE THAT ALL PARTY LEVEL
1696 -- ACQUISTION ATTRIBUTES (IF ANY), THAT SERVE AS FILTERS ARE MATCHED.
1697
1698
1699 l(';');
1700 l('');
1701 l('');
1702 l('--------UPDATE DQM ACTION FLAG IN ' || p_entity ||' INTERFACE/STAGING TABLES --------------');
1703 l('open x_ent_cur for');
1704 l('select distinct a.record_osr, a.record_os');
1705 l('from hz_imp_dup_details a');
1706 l('where a.batch_id = p_batch_id');
1707 l('and a.party_osr between from_osr and to_osr and a.entity =''' || p_entity || ''';') ;
1708 l('HZ_DQM_DUP_ID_PKG.update_detail_dqm_action_flag(''' ||p_entity ||''',p_batch_id, x_ent_cur);');
1709 l('-------------' || p_entity || ' LEVEL DUPLICATE IDENTIFICATION ENDS ------------------------');
1710 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Ending insert of ' || p_entity || ''''|| ');');
1711 l('FND_FILE.put_line(FND_FILE.log,''Number of records inserted ''||SQL%ROWCOUNT);');
1712 l('FND_FILE.put_line(FND_FILE.log,''End time to insert ''||to_char(sysdate,''hh24:mi:ss''));');
1713 l('');
1714 l('');
1715
1716 END;
1717
1718 -------------------------------------------------------------------------
1719 -- gen_insert_footer_int_tca :
1720 -------------------------------------------------------------------------
1721 PROCEDURE gen_insert_footer_int_tca(p_match_rule_id number)
1722 IS
1723 FIRST1 boolean;
1724 FIRST boolean;
1725 BEGIN
1726 l(')');
1727
1728 -- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES
1729 IF has_party_filter_attributes(p_match_rule_id)= 'Y'
1730 THEN
1731 l('------- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES---------');
1732 l('where EXISTS (');
1733 l('SELECT 1 FROM HZ_SRCH_PARTIES p1, HZ_STAGED_PARTIES p2');
1734 l('WHERE p1.batch_id = p_batch_id and p1.party_osr = party_osr and p1.party_os = party_os');
1735 l('and p2.party_id = t');
1736 FIRST1 := TRUE;
1737 FOR attrs in (
1738 SELECT primary_attribute_id
1739 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1740 where p.match_rule_id=p_match_rule_id
1741 and p.attribute_id=a.attribute_id
1742 and a.entity_name = 'PARTY'
1743 and nvl(p.filter_flag,'N') = 'Y'
1744 and HZ_IMP_DQM_STAGE.EXIST_COL(a.attribute_name, a.entity_name ) = 'Y'
1745 )
1746 LOOP
1747 IF FIRST1
1748 THEN
1749 FIRST1 := FALSE;
1750 END IF;
1751
1752 -- between attributes
1753 l('and');
1754
1755 FIRST := TRUE;
1756 FOR trans in ( SELECT staged_attribute_column
1757 FROM hz_primary_trans pt, hz_trans_functions_vl f
1758 where f.function_id = pt.function_id
1759 and pt.primary_attribute_id = attrs.primary_attribute_id
1760 )
1761 LOOP
1762 IF FIRST
1763 THEN
1764 l('-- do an or between all the transformations of an attribute -- ');
1765 l('(');
1766 l('((p1.'|| trans.staged_attribute_column || ' is null and ' ||
1767 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
1768 'p2.'|| trans.staged_attribute_column || ' = p1.'||
1769 trans.staged_attribute_column || ' || '' '' )');
1770 FIRST := FALSE;
1771 ELSE
1772 l('or ((p1.'|| trans.staged_attribute_column || ' is null and ' ||
1773 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
1774 'p2.'|| trans.staged_attribute_column || ' = p1.'||
1775 trans.staged_attribute_column || ' || '' '' )');
1776 END IF;
1777
1778 END LOOP;
1779 l(')');
1780 END LOOP;
1781 l(')');
1782 END IF;
1783
1784 l('group by f, t, party_osr, party_os');
1785
1786 -- having clause should exist only if x_insert_threshold
1787 -- is positive
1788 IF get_insert_threshold(p_match_rule_id) > 0
1789 THEN
1790 l('having sum(score) >= x_insert_threshold');
1791 END IF;
1792
1793 l(';');
1794 l('FND_FILE.put_line(FND_FILE.log,''Number of parties inserted ''||SQL%ROWCOUNT);');
1795 l('FND_FILE.put_line(FND_FILE.log,''End time of insert ''||to_char(sysdate,''hh24:mi:ss''));');
1796 END;
1797
1798
1799 -------------------------------------------------------------------------
1800 -- gen_update_template_int_tca :
1801 -------------------------------------------------------------------------
1802 PROCEDURE gen_update_template_int_tca (
1803 s_table VARCHAR2,
1804 p_table VARCHAR2,
1805 p_match_rule_id NUMBER,
1806 p_entity VARCHAR2,
1807 p_match_all_flag VARCHAR2
1808 )
1809 IS
1810 FIRST BOOLEAN ;
1811 FIRST1 BOOLEAN;
1812 outer_row_count number := 0 ;
1813 inner_row_counter number := 0;
1814 outer_row_counter number := 0;
1815
1816 BEGIN
1817
1818 l('');
1819 l('');
1820 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
1821 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Beginning update of Parties on the basis of ' || p_entity || ''''|| ');');
1822 l('FND_FILE.put_line(FND_FILE.log,''Start time of update ''||to_char(sysdate,''hh24:mi:ss''));');
1823
1824 l('open x_ent_cur for');
1825 l('select f,t,max(score) from (');
1826 l(' select /*+ USE_CONCAT */ s1.party_id f, s2.party_id t,');
1827
1828 -- Generate the Secondary Attribute section of the query for the passed in entity
1829 SELECT count(1) into outer_row_count
1830 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1831 where a.attribute_id=s.attribute_id
1832 and s.match_rule_id=p_match_rule_id
1833 and a.entity_name = p_entity;
1834
1835
1836 IF has_scoring_attributes(p_match_rule_id, p_entity)
1837 THEN
1838
1839 FOR attrs in (
1840 SELECT score,s.attribute_id , secondary_attribute_id
1841 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
1842 where a.attribute_id=s.attribute_id
1843 and s.match_rule_id=p_match_rule_id
1844 and a.entity_name = p_entity)
1845 LOOP
1846 outer_row_counter := outer_row_counter + 1;
1847 inner_row_counter := 0;
1848
1849 FOR trans in (
1850 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
1851 FROM hz_secondary_trans st, hz_trans_functions_vl f
1852 where f.function_id=st.function_id
1853 and st.secondary_attribute_id = attrs.secondary_attribute_id
1854 order by transformation_weight desc)
1855 LOOP
1856 inner_row_counter := inner_row_counter + 1;
1857 l('decode(instrb(s2.'||trans.staged_attribute_column
1858 || ',s1.'||trans.staged_attribute_column||
1859 '),1,'|| trans.score||',');
1860
1861 END LOOP;
1862
1863 l('0');
1864
1865 -- Need to have as many right parentheses as inner_row_counter
1866 FOR I IN 1 .. inner_row_counter
1867 LOOP
1868 l(')');
1869 END LOOP;
1870
1871 IF outer_row_counter < outer_row_count
1872 THEN
1873 l('+');
1874 END IF;
1875 END LOOP;
1876 ELSE
1877 l('0 ');
1878 END IF;
1879
1880 l('score');
1881 l('from hz_imp_dup_parties h1, '||s_table||' s1, '||p_table||' s2');
1885 -- Generate the Primary Attribute section of the query for the passed in entity
1882 l('where h1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr');
1883 l('and s1.batch_id = h1.batch_id and s1.party_osr = h1.party_osr and s1.party_os = h1.party_os and s2.party_id = h1.dup_party_id');
1884 l('and ( ');
1886 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
1887 FIRST1 := TRUE;
1888 -- Generate the Primary Attribute section of the query for the passed in entity
1889 FOR attrs in (
1890 SELECT primary_attribute_id
1891 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1892 where p.match_rule_id=p_match_rule_id
1893 and p.attribute_id=a.attribute_id
1894 and a.entity_name = p_entity
1895 and nvl(p.filter_flag,'N') = 'N' )
1896 LOOP
1897 -- between attributes
1898 IF FIRST1
1899 THEN
1900 FIRST1 := FALSE;
1901 l('------------ NON FILTER ATTRIBUTES SECTION ------------------------');
1902 ELSE
1903 IF p_match_all_flag = 'Y'
1904 THEN
1905 l('and');
1906 ELSE
1907 l('or');
1908 END IF;
1909
1910 END IF;
1911
1912 FIRST := TRUE;
1913 FOR trans in ( SELECT staged_attribute_column
1914 FROM hz_primary_trans pt, hz_trans_functions_vl f
1915 where f.function_id = pt.function_id
1916 and pt.primary_attribute_id = attrs.primary_attribute_id
1917 )
1918 LOOP
1919 IF FIRST
1920 THEN
1921 l('-- do an or between all the transformations of an attribute -- ');
1922 l('(');
1923 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1924 's2.'|| trans.staged_attribute_column || ' like s1.'||
1925 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1926 FIRST := FALSE;
1927 ELSE
1928 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
1929 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
1930 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
1931 END IF;
1932
1933 END LOOP;
1934 l(')');
1935
1936 END LOOP;
1937 l(')');
1938
1939 -- NOW TAKE CARE OF FILTER ATTRIBUTES
1940 FIRST1 := TRUE;
1941 FOR attrs in (
1942 SELECT primary_attribute_id
1943 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
1944 where p.match_rule_id=p_match_rule_id
1945 and p.attribute_id=a.attribute_id
1946 and a.entity_name = p_entity
1947 and nvl(p.filter_flag,'N') = 'Y'
1948 and HZ_IMP_DQM_STAGE.EXIST_COL(a.attribute_name, a.entity_name ) = 'Y'
1949 )
1950 LOOP
1951 -- between attributes
1952 IF FIRST1
1953 THEN
1954 FIRST1 := FALSE;
1955 l('------------ FILTER ATTRIBUTES SECTION ------------------------');
1956 END IF;
1957
1958 l('and ');
1959
1960 FIRST := TRUE;
1961 FOR trans in ( SELECT staged_attribute_column
1962 FROM hz_primary_trans pt, hz_trans_functions_vl f
1963 where f.function_id = pt.function_id
1964 and pt.primary_attribute_id = attrs.primary_attribute_id
1965 )
1966 LOOP
1967 IF FIRST
1968 THEN
1969 l('-- do an or between all the transformations of an attribute -- ');
1970 l('(');
1971 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1972 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1973 's2.'|| trans.staged_attribute_column || ' = s1.'||
1974 trans.staged_attribute_column || ' || '' '' )' );
1975 FIRST := FALSE;
1976 ELSE
1977 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
1978 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
1979 's2.'|| trans.staged_attribute_column || ' = s1.'||
1980 trans.staged_attribute_column || ' || '' '' )' );
1981 END IF;
1982
1983 END LOOP;
1984 l(')');
1985 END LOOP;
1986 l(') group by f,t ;');
1987 l('HZ_DQM_DUP_ID_PKG.update_hz_imp_dup_parties(p_batch_id, x_ent_cur);');
1988 l('close x_ent_cur;');
1989 l('FND_FILE.put_line(FND_FILE.log,''Number of parties updated ''||SQL%ROWCOUNT);');
1990 l('FND_FILE.put_line(FND_FILE.log,''End time to update ''||to_char(sysdate,''hh24:mi:ss''));');
1991 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Ending update of Parties on the basis of ' || p_entity || ''''|| ');');
1992 END;
1993
1997 -- apply threshold to hz_imp_dup_parties
1994 PROCEDURE gen_thr_check_int_tca
1995 IS
1996 BEGIN
1998 l('');
1999 l('--------DELETE ON THRESHOLD AND REMOVE INDIRECT TRANSITIVITY ---------------------');
2000 l('');
2001 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
2002 l('FND_FILE.put_line(FND_FILE.log,''DELETE ON THRESHOLD AND INDIRECT TRANSITIVITY '');');
2003 l('FND_FILE.put_line(FND_FILE.log,''Begin time to delete ''||to_char(sysdate,''hh24:mi:ss''));');
2004 l('');
2005 l('delete from hz_imp_dup_parties a');
2006 l('where (a.party_osr >= from_osr and a.party_osr <= to_osr');
2007 l('and a.batch_id = p_batch_id)');
2008 l('and (');
2009 l('a.score < p_threshold');
2010 l('or');
2011 l('-- delete the party id whose duplicate is a bigger number, when scores are same');
2012 l('exists');
2013 l(' (Select 1 from hz_imp_dup_parties b');
2014 l(' where b.batch_id=p_batch_id and a.party_id=b.party_id and a.dup_party_id > b.dup_party_id and a.score = b.score)');
2015 l('or');
2016 l('-- delete the party id with least score, if scores are different');
2017 l('exists');
2018 l(' (Select 1 from hz_imp_dup_parties b');
2019 l(' where b.batch_id=p_batch_id and a.party_id=b.party_id and a.score < b.score)');
2020 l(');');
2021 l('');
2022 l('FND_FILE.put_line(FND_FILE.log,''Number of records deleted from hz_imp_dup_parties ''||SQL%ROWCOUNT);');
2023 l('FND_FILE.put_line(FND_FILE.log,''End time to delete ''||to_char(sysdate,''hh24:mi:ss''));');
2024
2025 l('--------UPDATE AUTO MERGE FLAG --------------');
2026 l('update hz_imp_dup_parties a');
2027 l('set a.auto_merge_flag = ''Y''');
2028 l('where a.score >= p_auto_merge_threshold');
2029 l('and a.party_osr >= from_osr and a.party_osr <= to_osr');
2030 l('and a.batch_id = p_batch_id ;');
2031 l('--------UPDATE DQM ACTION FLAG IN INTERFACE/STAGING TABLES --------------');
2032 l('');
2033 l('open x_ent_cur for');
2034 l('select a.party_osr, a.party_os, a.auto_merge_flag');
2035 l('from hz_imp_dup_parties a');
2036 l('where a.batch_id = p_batch_id');
2037 l('and a.party_osr between from_osr and to_osr ;');
2038 l('HZ_DQM_DUP_ID_PKG.update_party_dqm_action_flag(p_batch_id, x_ent_cur);');
2039 l('----------------------PARTY LEVEL DUPLICATE IDENTIFICATION ENDS --------------------');
2040 l('');
2041 END ;
2042 -------------------------------------------------------------------------
2043 -- gen_pkg_body_int_tca_join : A Private procedure that will generate the package body
2044 -- of the match rule
2045 -------------------------------------------------------------------------
2046
2047
2048 PROCEDURE gen_pkg_body_int_tca_join (
2049 p_pkg_name IN VARCHAR2,
2050 p_match_rule_id IN NUMBER,
2051 p_att_flag IN VARCHAR2
2052 )
2053 IS
2054
2055 CURSOR entity_cur IS
2056
2057 select entity_name, search_table_name, entity_table_name, entity_id_name, entity_osr_name,
2058 entity_os_name, sc, att_flag
2059 from
2060 ( select entity_name, decode(entity_name,
2061 'PARTY','HZ_SRCH_PARTIES',
2062 'PARTY_SITES', 'HZ_SRCH_PSITES',
2063 'CONTACTS','HZ_SRCH_CONTACTS',
2064 'CONTACT_POINTS', 'HZ_SRCH_CPTS') search_table_name,
2065 decode(entity_name,
2066 'PARTY','HZ_STAGED_PARTIES',
2067 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
2068 'CONTACTS','HZ_STAGED_CONTACTS',
2069 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
2070 decode(entity_name,
2071 'PARTY','PARTY_ID',
2072 'PARTY_SITES', 'PARTY_SITE_ID',
2073 'CONTACTS','ORG_CONTACT_ID',
2074 'CONTACT_POINTS', 'CONTACT_POINT_ID') entity_id_name,
2075 decode(entity_name,
2076 'PARTY','PARTY_OSR',
2077 'PARTY_SITES', 'PARTY_SITE_OSR',
2078 'CONTACTS','CONTACT_OSR',
2079 'CONTACT_POINTS', 'CONTACT_PT_OSR') entity_osr_name,
2080 decode(entity_name,
2081 'PARTY','PARTY_OS',
2082 'PARTY_SITES', 'PARTY_SITE_OS',
2083 'CONTACTS','CONTACT_OS',
2084 'CONTACT_POINTS', 'CONTACT_PT_OS') entity_os_name,
2085 sum(score) sc, 'S' att_flag
2086 from hz_trans_attributes_vl a, hz_match_rule_secondary s
2087 where s.match_rule_id = p_match_rule_id
2088 and s.attribute_id = a.attribute_id
2089 group by entity_name
2090 union all
2091 select entity_name, decode(entity_name,
2092 'PARTY','HZ_SRCH_PARTIES',
2093 'PARTY_SITES', 'HZ_SRCH_PSITES',
2094 'CONTACTS','HZ_SRCH_CONTACTS',
2095 'CONTACT_POINTS', 'HZ_SRCH_CPTS') search_table_name,
2096 decode(entity_name,
2097 'PARTY','HZ_STAGED_PARTIES',
2098 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
2099 'CONTACTS','HZ_STAGED_CONTACTS',
2100 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
2101 decode(entity_name,
2102 'PARTY','PARTY_ID',
2103 'PARTY_SITES', 'PARTY_SITE_ID',
2104 'CONTACTS','ORG_CONTACT_ID',
2105 'CONTACT_POINTS', 'CONTACT_POINT_ID') entity_id_name,
2106 decode(entity_name,
2107 'PARTY','PARTY_OSR',
2108 'PARTY_SITES', 'PARTY_SITE_OSR',
2109 'CONTACTS','CONTACT_OSR',
2110 'CONTACT_POINTS', 'CONTACT_PT_OSR') entity_osr_name,
2111 decode(entity_name,
2112 'PARTY','PARTY_OS',
2113 'PARTY_SITES', 'PARTY_SITE_OS',
2114 'CONTACTS','CONTACT_OS',
2115 'CONTACT_POINTS', 'CONTACT_PT_OS') entity_os_name,
2116 0 sc, 'P' att_flag
2117 from hz_trans_attributes_vl a, hz_match_rule_primary p
2118 where p.match_rule_id = p_match_rule_id
2119 and p.attribute_id = a.attribute_id
2120 group by entity_name
2121 ) where att_flag = p_att_flag
2122 order by sc desc ;
2123 srt score_rec_type;
2124 threshold number;
2125 match_all_flag varchar2(1);
2126 row_count number;
2127 no_of_entities number;
2128 template varchar2(30);
2129 insert_stmt_is_open boolean;
2130 BEGIN
2131
2132 -- Get the threshold and match_all_flag
2133 select match_score, match_all_flag into threshold, match_all_flag
2134 from hz_match_rules_vl
2135 where match_rule_id = p_match_rule_id;
2136
2137 -- Get the different aggregates that would help in determining the template
2138 -- that need to be used -- UNION/UPDATE for the corresponding entity.
2139
2140 -- If attribute flag is 'P', make the threshold 0
2141 -- This signifies that the match rule has no scoring attributes
2142 IF p_att_flag = 'P'
2143 THEN
2144 threshold := 0;
2145 srt.sum_score := 0;
2146 srt.min_score := 0;
2147 srt.max_score := 0;
2148 ELSE
2149 srt := get_misc_scores(p_match_rule_id);
2150 END IF;
2151
2152
2153 -- Initialize the number of entities
2154 no_of_entities := 0;
2155
2156 -- Get the number of entities
2157 FOR c0 in entity_cur
2158 LOOP
2159 no_of_entities := no_of_entities + 1;
2160 END LOOP;
2161
2162
2163 -- Before generating the code for the given match rule, we look at the
2164 -- match_all_flag to determine, the structure of the code that needs
2165 -- to go into the generated match rule package.
2166 -- The flag is always assumed to be 'N' by default ie., a match on ANY of the
2167 -- entities, would be given consideration.
2168 -- If flag = 'Y', then we need to make sure that every query after the first
2169 -- one is an update. We make this happen by manually setting the threshold.
2170 IF match_all_flag = 'Y'
2171 THEN
2172 threshold := srt.sum_score;
2173 END IF;
2174
2175 -- Generate the Header
2176 gen_header_int_tca (p_pkg_name, p_match_rule_id);
2177
2178 l('------------------ PARTY LEVEL DUPLICATE IDENTIFICATION BEGINS --------------------');
2179
2180 -- Open the entity cursor, determine the templates (INSERT/UPDATE) for each
2181 -- and call the appropriate function to add lines to the generated package
2182 -- for the corresponding entity
2183 row_count := 0;
2184 insert_stmt_is_open := false;
2185
2186 -- some basic observations that would help in this logic
2187 -- 1. There will always be atleast one insert statement
2188 -- 2. all insert templates would come under the insert statement
2189 -- 3. all update templates are modular and do not need any special treatment for opening and closing.
2190 -- 4. all update templates would be together
2191 -- 5. when gnerating an update template, we need to make sure that the insert statement is closed.
2192 -- 6. in the event that we never have an update template, we close the insert statement, outside the loop.
2193 FOR entity_cur_rec in entity_cur
2194 LOOP
2195 row_count := row_count + 1;
2196
2197
2198
2199 -- First row, is always an insert, unless the match rule returns nothing due
2200 -- to an erroneous combination of the threshold/match rule configuration.
2201 -- If that happnes we , get the hell out of here.
2202 IF row_count = 1
2203 THEN
2204 -- pass the first entity forcefully
2205 IF (srt.sum_score - threshold) >= 0
2206 THEN
2207 gen_insert_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
2208 entity_cur_rec.entity_name, match_all_flag);
2209 insert_stmt_is_open := true;
2210 ELSE
2211 -- need to handle this by reporting an error and getting the hell out of here.
2212 null;
2213 return ;
2214 END IF;
2215 END IF;
2216
2217 IF row_count = 2
2218 THEN
2219
2220 IF (srt.sum_score - srt.max_score - threshold) >= 0
2221 THEN
2222 l('union all');
2223 gen_insert_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
2224 entity_cur_rec.entity_name, match_all_flag);
2225 ELSE
2226 IF insert_stmt_is_open
2227 THEN
2228 gen_insert_footer_int_tca(p_match_rule_id) ;
2229 insert_stmt_is_open := false;
2230 END IF;
2231 gen_update_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
2232 entity_cur_rec.entity_name, match_all_flag);
2233 END IF;
2234 END IF;
2235
2236 IF row_count = 3
2237 THEN
2238 IF no_of_entities = 3
2239 THEN
2240 IF (entity_cur_rec.sc - threshold) >= 0
2241 THEN
2242 l('union all');
2243 gen_insert_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
2244 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
2245 ELSE
2246 IF insert_stmt_is_open
2247 THEN
2248 gen_insert_footer_int_tca(p_match_rule_id) ;
2249 insert_stmt_is_open := false;
2250 END IF;
2251 gen_update_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
2252 entity_cur_rec.entity_name, match_all_flag);
2253 END IF;
2254
2255 ELSE
2256 IF ( entity_cur_rec.sc + srt.min_score - threshold) >= 0
2257 THEN
2258 l('union all');
2259 gen_insert_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
2260 entity_cur_rec.entity_name, match_all_flag);
2261 ELSE
2262 IF insert_stmt_is_open
2263 THEN
2264 gen_insert_footer_int_tca(p_match_rule_id) ;
2265 insert_stmt_is_open := false;
2266 END IF;
2267 gen_update_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
2268 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
2269 END IF;
2270 END IF;
2271 END IF;
2272
2273 IF row_count = 4
2274 THEN
2275 IF (entity_cur_rec.sc - threshold) >= 0
2276 THEN
2277 l('union all');
2278 gen_insert_template_int_tca(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
2279 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
2280 ELSE
2281 IF insert_stmt_is_open
2282 THEN
2283 gen_insert_footer_int_tca(p_match_rule_id);
2284 insert_stmt_is_open := false;
2285 END IF;
2286 gen_update_template_int_tca(entity_cur_rec.search_table_name, entity_cur_rec.entity_table_name,
2287 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
2288 END IF;
2289 END IF;
2290
2291 END LOOP;
2292
2293 -- Just to make sure that the insert statement is not open, after all the entity queries
2294 -- have been generated
2295 IF insert_stmt_is_open
2296 THEN
2297 gen_insert_footer_int_tca(p_match_rule_id) ;
2298 insert_stmt_is_open := false;
2299 END IF;
2300
2301 -- generate threshold check
2302 gen_thr_check_int_tca ;
2303
2304 -- generate code for detail level duplicate identification
2305 FOR entity_cur_rec in entity_cur
2306 LOOP
2307 IF entity_cur_rec.entity_name <> 'PARTY'
2308 THEN
2309 gen_dl_insert_template_int_tca(entity_cur_rec.search_table_name,
2310 entity_cur_rec.entity_table_name,
2311 p_match_rule_id,
2312 entity_cur_rec.entity_name,
2313 entity_cur_rec.entity_id_name,
2314 entity_cur_rec.entity_osr_name,
2315 entity_cur_rec.entity_os_name,
2316 match_all_flag );
2317 END IF;
2318
2319 END LOOP;
2320 -- generate the footer for the package
2321 gen_footer_int_tca(p_pkg_name) ;
2322
2323 END;
2324
2325 PROCEDURE gen_pkg_body_int_tca_join (
2326 p_pkg_name IN VARCHAR2,
2327 p_match_rule_id IN NUMBER
2328 )
2329 IS
2330 BEGIN
2331 IF has_scoring_attributes(p_match_rule_id)
2332 THEN
2333 gen_pkg_body_int_tca_join(p_pkg_name, p_match_rule_id, 'S');
2334 ELSE
2335 gen_pkg_body_int_tca_join(p_pkg_name, p_match_rule_id, 'P');
2336 END IF;
2337 END ;
2338
2339
2340 ------------------------------------------------------------------------
2341 -- MATCH RULE GENERATION FOR INTERFACE JOIN
2342 ------------------------------------------------------------------------
2343
2344
2345
2346 -------------------------------------------------------------------------
2347 -- gen_header_int :
2348 -------------------------------------------------------------------------
2349 PROCEDURE gen_header_int (
2350 p_pkg_name IN VARCHAR2,
2351 p_match_rule_id IN NUMBER
2352 )
2353 IS
2354 temp number;
2355 BEGIN
2356 l('');
2357 l('');
2358 l('');
2359 l('');
2360 l('---------------------------------------------------------------');
2361 l('-------------------- INTERFACE JOIN BEGINS --------------------------');
2362 l('---------------------------------------------------------------');
2363 l('PROCEDURE interface_join_entities(p_batch_id in number,');
2364 l(' from_osr in varchar2, to_osr in varchar2, p_threshold in number)');
2365 l('IS');
2366 l('x_ent_cur HZ_DQM_DUP_ID_PKG.EntityCur;');
2367 temp := get_insert_threshold(p_match_rule_id);
2368 l(' x_insert_threshold number := ' || temp || ';');
2369 l('BEGIN');
2370 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
2371 l('FND_FILE.put_line(FND_FILE.log,''WU: ''||from_osr||'' to ''||to_osr);');
2372 l('FND_FILE.put_line(FND_FILE.log,''Start time of insert of Parties ''||to_char(sysdate,''hh24:mi:ss''));');
2373 l('insert into hz_int_dup_results(batch_id, f_osr,t_osr,ord_f_osr,ord_t_osr,score,f_os, t_os)');
2374 l('select p_batch_id, f, t, least(f,t), greatest(f,t), sum(score) score, fos, tos from (');
2375 END;
2376
2377 -------------------------------------------------------------------------
2378 -- gen_insert_template_int :
2379 -------------------------------------------------------------------------
2380 PROCEDURE gen_insert_template_int(
2381 s_table VARCHAR2,
2382 p_table VARCHAR2,
2383 p_match_rule_id NUMBER,
2384 p_entity VARCHAR2,
2385 p_match_all_flag VARCHAR2
2386 )
2387 IS
2388 FIRST BOOLEAN ;
2389 FIRST1 BOOLEAN;
2390 outer_row_count number := 0 ;
2391 inner_row_counter number := 0;
2392 outer_row_counter number := 0;
2393
2394 BEGIN
2395 -- finding the max, applies only to detail information viz., to non-party entities.
2396 IF p_entity <> 'PARTY'
2397 THEN
2398 l('select f, t, max(score) score, fos, tos from (');
2399 END IF;
2400
2401 l('select /*+ USE_CONCAT */ s1.party_osr f, s2.party_osr t,');
2402
2403
2404 l('-------' || p_entity || ' ENTITY: SCORING SECTION ---------');
2405
2406 SELECT count(1) into outer_row_count
2407 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2408 where a.attribute_id=s.attribute_id
2409 and s.match_rule_id=p_match_rule_id
2410 and a.entity_name = p_entity;
2411
2412 IF has_scoring_attributes(p_match_rule_id, p_entity)
2413 THEN
2414 -- Generate the Secondary Attribute section of the query for the passed in entity
2415 FOR attrs in (
2416 SELECT score,s.attribute_id , secondary_attribute_id
2417 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2418 where a.attribute_id=s.attribute_id
2419 and s.match_rule_id=p_match_rule_id
2420 and a.entity_name = p_entity)
2421 LOOP
2422 outer_row_counter := outer_row_counter + 1;
2423 inner_row_counter := 0;
2424
2425 FOR trans in (
2426 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
2427 FROM hz_secondary_trans st, hz_trans_functions_vl f
2428 where f.function_id=st.function_id
2429 and st.secondary_attribute_id = attrs.secondary_attribute_id
2430 order by transformation_weight desc)
2431 LOOP
2432 inner_row_counter := inner_row_counter + 1;
2433 l('decode(instrb(s2.'||trans.staged_attribute_column
2434 || ',s1.'||trans.staged_attribute_column||
2435 '),1,'|| trans.score||',');
2436 END LOOP;
2437
2438 l('0');
2439
2440 -- Need to have as many right parentheses as inner_row_counter
2441 FOR I IN 1 .. inner_row_counter
2442 LOOP
2443 l(')');
2444 END LOOP;
2445
2446 IF outer_row_counter < outer_row_count
2447 THEN
2448 l('+');
2449 END IF;
2450 END LOOP;
2451 ELSE
2452 l('0 ');
2453 END IF;
2454
2455 l('score, s1.party_os fos, s2.party_os tos');
2456
2457
2458 -- if the passed in entity is a detail level entity, then we need to make sure
2459 -- that the party level filters ( if any), participate in the join
2460 -- for the detail
2461 IF p_entity <> 'PARTY' AND has_party_filter_attributes(p_match_rule_id)= 'Y'
2462 THEN
2463 l('from '||s_table||' s1, '||s_table||' s2');
2464 ELSE
2465 l('from '||s_table||' s1, '||s_table||' s2 ');
2466 END IF;
2467
2468 l('where s1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr and s1.party_osr <> s2.party_osr');
2469 l('and s2.batch_id = p_batch_id and not exists (select 1 from HZ_INT_DUP_RESULTS WHERE t_osr = s1.party_osr and batch_id = p_batch_id)');
2470 -- only for contact point types
2471 IF p_entity = 'CONTACT_POINTS'
2472 THEN
2473 l('and s1.contact_point_type = s2.contact_point_type');
2474 END IF;
2475
2476 l('and (');
2477
2478 -- Generate the Primary Attribute section of the query for the passed in entity
2479 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
2480 FIRST1 := TRUE;
2481 -- Generate the Primary Attribute section of the query for the passed in entity
2482 FOR attrs in (
2483 SELECT primary_attribute_id
2484 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2485 where p.match_rule_id=p_match_rule_id
2486 and p.attribute_id=a.attribute_id
2487 and a.entity_name = p_entity
2488 and nvl(p.filter_flag,'N') = 'N' )
2489 LOOP
2490 -- between attributes
2491 IF FIRST1
2492 THEN
2493 FIRST1 := FALSE;
2494 l('-------' || p_entity || ' ENTITY: ACQUISITION ON NON-FILTER ATTRIBUTES ---------');
2495 ELSE
2496 IF p_match_all_flag = 'Y'
2497 THEN
2498 l('and');
2499 ELSE
2500 l('or');
2501 END IF;
2502
2503 END IF;
2504
2505 FIRST := TRUE;
2506 FOR trans in ( SELECT staged_attribute_column
2507 FROM hz_primary_trans pt, hz_trans_functions_vl f
2508 where f.function_id = pt.function_id
2509 and pt.primary_attribute_id = attrs.primary_attribute_id
2510 )
2511 LOOP
2512 IF FIRST
2513 THEN
2514 l('-- do an or between all the transformations of an attribute -- ');
2515 l('(');
2516 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
2517 's2.'|| trans.staged_attribute_column || ' like s1.'||
2518 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
2519 FIRST := FALSE;
2520 ELSE
2521 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
2522 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
2523 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
2524 END IF;
2525
2526 END LOOP;
2527 l(')');
2528
2529 END LOOP;
2530 l(')');
2531
2532 -- NOW, TAKE CARE OF ENTITY FILTER ATTRIBUTES FOR ALL ENTITIES
2533 -- OTHER THAN PARTIES
2534 IF p_entity <> 'PARTY' AND has_entity_filter_attributes(p_match_rule_id, p_entity)= 'Y'
2535 THEN
2536
2537 FIRST1 := TRUE;
2538 FOR attrs in (
2539 SELECT primary_attribute_id
2540 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2541 where p.match_rule_id=p_match_rule_id
2542 and p.attribute_id=a.attribute_id
2543 and a.entity_name = p_entity
2544 and nvl(p.filter_flag,'N') = 'Y' )
2545 LOOP
2546 -- between attributes
2547 IF FIRST1
2548 THEN
2549 FIRST1 := FALSE;
2550 l('-------' || p_entity || ' ENTITY: ACQUISITION ON FILTER ATTRIBUTES ---------');
2551 END IF;
2552
2553 -- between attributes
2554 l('and ');
2555
2556 FIRST := TRUE;
2557 FOR trans in ( SELECT staged_attribute_column
2558 FROM hz_primary_trans pt, hz_trans_functions_vl f
2559 where f.function_id = pt.function_id
2560 and pt.primary_attribute_id = attrs.primary_attribute_id
2561 )
2562 LOOP
2563 IF FIRST
2564 THEN
2565 l('-- do an or between all the transformations of an attribute -- ');
2566 l('(');
2567 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
2568 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
2569 's2.'|| trans.staged_attribute_column || ' = s1.'||
2570 trans.staged_attribute_column || ')');
2571 FIRST := FALSE;
2572 ELSE
2573 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
2574 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
2575 's2.'|| trans.staged_attribute_column || ' = s1.'||
2576 trans.staged_attribute_column || ')');
2577 END IF;
2578
2579 END LOOP;
2580 l(')');
2581 END LOOP;
2582
2583 END IF;
2584
2585 -- complete the insert statement for non-party entities
2586 IF p_entity <> 'PARTY'
2587 THEN
2588 l(')');
2589 l('group by f, t, fos, tos');
2590 END IF;
2591
2592 END;
2593
2594 -------------------------------------------------------------------------
2595 -- gen_dl_insert_template_int :
2596 -------------------------------------------------------------------------
2597 PROCEDURE gen_dl_insert_template_int(
2598 s_table VARCHAR2,
2599 p_table VARCHAR2,
2600 p_match_rule_id NUMBER,
2601 p_entity VARCHAR2,
2602 p_entity_osr_name VARCHAR2,
2603 p_entity_os_name VARCHAR2,
2604 p_match_all_flag VARCHAR2
2605 )
2606 IS
2607 FIRST BOOLEAN ;
2608 FIRST1 BOOLEAN ;
2609 outer_row_count number := 0 ;
2610 inner_row_counter number := 0;
2611 outer_row_counter number := 0;
2612
2613 BEGIN
2614
2615 l('-------------' || p_entity || ' LEVEL DUPLICATE IDENTIFICATION BEGINS ------------------------');
2616 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
2617 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Beginning insert of ' || p_entity || ''''|| ');');
2618 l('FND_FILE.put_line(FND_FILE.log,''Start time of insert ''||to_char(sysdate,''hh24:mi:ss''));');
2619 l('insert into hz_imp_int_dedup_results(batch_id, winner_record_osr, winner_record_os,');
2620 l('dup_record_osr, dup_record_os, detail_party_osr, detail_party_os, entity, score,');
2621 l('dup_creation_date,dup_last_update_date');
2622 l(',created_by,creation_date,last_update_login,last_update_date,last_updated_by)');
2623 l('select /*+ USE_CONCAT */ p_batch_id, s1.' || p_entity_osr_name || ', s1.' || p_entity_os_name || ',');
2624 l('s2.' || p_entity_osr_name || ', s2.' || p_entity_os_name || ',');
2625 l('s1.party_osr, s2.party_os,' || '''' || p_entity || ''',');
2626 SELECT count(1) into outer_row_count
2627 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2628 where a.attribute_id=s.attribute_id
2629 and s.match_rule_id=p_match_rule_id
2630 and a.entity_name = p_entity;
2631
2632 IF has_scoring_attributes(p_match_rule_id, p_entity)
2633 THEN
2634 -- Generate the Secondary Attribute section of the query for the passed in entity
2635 FOR attrs in (
2636 SELECT score,s.attribute_id , secondary_attribute_id
2637 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2638 where a.attribute_id=s.attribute_id
2639 and s.match_rule_id=p_match_rule_id
2640 and a.entity_name = p_entity)
2641 LOOP
2642 outer_row_counter := outer_row_counter + 1;
2643 inner_row_counter := 0;
2644
2645 FOR trans in (
2646 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
2647 FROM hz_secondary_trans st, hz_trans_functions_vl f
2648 where f.function_id=st.function_id
2649 and st.secondary_attribute_id = attrs.secondary_attribute_id
2650 order by transformation_weight desc)
2651 LOOP
2652 inner_row_counter := inner_row_counter + 1;
2653 l('decode(nvl(s1.'||trans.staged_attribute_column||
2654 ',''N1''),nvl(substrb(s2.'||trans.staged_attribute_column||
2655 ',1,length(s1.'||trans.staged_attribute_column||')),''N2''),'||trans.score||', ');
2656
2657 END LOOP;
2658
2659 l('0');
2660
2661 -- Need to have as many right parentheses as inner_row_counter
2662 FOR I IN 1 .. inner_row_counter
2663 LOOP
2664 l(')');
2665 END LOOP;
2666
2667 IF outer_row_counter < outer_row_count
2668 THEN
2669 l('+');
2670 END IF;
2671 END LOOP;
2672 ELSE
2673 l('0 ');
2674 END IF;
2675
2676 l('score ,hz_utility_v2pub.creation_date, hz_utility_v2pub.last_update_date');
2677 l(',hz_utility_v2pub.created_by,hz_utility_v2pub.creation_date,hz_utility_v2pub.last_update_login');
2678 l(',hz_utility_v2pub.last_update_date,hz_utility_v2pub.last_updated_by');
2679 l('from '||s_table||' s1, '||s_table||' s2 ');
2680 l('where s1.batch_id = p_batch_id and s1.party_osr between from_osr and to_osr ');
2681 l(' and ( ( (s1.party_osr = s2.party_osr) and ( nvl(s1.party_id, 1) = nvl(s2.party_id,1) ) ) OR ( s1.party_id = s2.party_id) ) '); -- bug 5393826
2682 l('and s2.batch_id = p_batch_id and s1.' || p_entity_osr_name || ' < ' || 's2.' || p_entity_osr_name );
2683
2684 -- only for contact point types
2685 IF p_entity = 'CONTACT_POINTS'
2686 THEN
2687 l('and s1.contact_point_type = s2.contact_point_type');
2688 END IF;
2689
2690 l('and ( ');
2691
2692 -- Generate the Primary Attribute section of the query for the passed in entity
2693 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
2694 FIRST1 := TRUE;
2695 -- Generate the Primary Attribute section of the query for the passed in entity
2696 FOR attrs in (
2697 SELECT primary_attribute_id
2698 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2699 where p.match_rule_id=p_match_rule_id
2700 and p.attribute_id=a.attribute_id
2701 and a.entity_name = p_entity
2702 and nvl(p.filter_flag,'N') = 'N' )
2703 LOOP
2704 -- between attributes
2705 IF FIRST1
2706 THEN
2707 FIRST1 := FALSE;
2708 l('------------ NON FILTER ATTRIBUTES SECTION ------------------------');
2709 ELSE
2710 IF p_match_all_flag = 'Y'
2711 THEN
2712 l('and');
2713 ELSE
2714 l('or');
2715 END IF;
2716
2717 END IF;
2718
2719 FIRST := TRUE;
2720 FOR trans in ( SELECT staged_attribute_column
2721 FROM hz_primary_trans pt, hz_trans_functions_vl f
2722 where f.function_id = pt.function_id
2723 and pt.primary_attribute_id = attrs.primary_attribute_id
2724 )
2725 LOOP
2726 IF FIRST
2727 THEN
2728 l('-- do an or between all the transformations of an attribute -- ');
2729 l('(');
2730 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
2731 's2.'|| trans.staged_attribute_column || ' like s1.'||
2732 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
2733 FIRST := FALSE;
2734 ELSE
2735 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
2736 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
2737 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
2738 END IF;
2739
2740 END LOOP;
2741 l(')');
2742
2743 END LOOP;
2744 l(')');
2745
2746 -- NOW TAKE CARE OF FILTER ATTRIBUTES
2747 FIRST1 := TRUE;
2748 FOR attrs in (
2749 SELECT primary_attribute_id
2750 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2751 where p.match_rule_id=p_match_rule_id
2752 and p.attribute_id=a.attribute_id
2753 and a.entity_name = p_entity
2754 and nvl(p.filter_flag,'N') = 'Y'
2755 and HZ_IMP_DQM_STAGE.EXIST_COL(a.attribute_name, a.entity_name ) = 'Y'
2756 )
2757 LOOP
2758 -- between attributes
2759 IF FIRST1
2760 THEN
2761 FIRST1 := FALSE;
2762 l('------------ FILTER ATTRIBUTES SECTION ------------------------');
2763 END IF;
2764
2765 l('and ');
2766
2767 FIRST := TRUE;
2768 FOR trans in ( SELECT staged_attribute_column
2769 FROM hz_primary_trans pt, hz_trans_functions_vl f
2770 where f.function_id = pt.function_id
2771 and pt.primary_attribute_id = attrs.primary_attribute_id
2772 )
2773 LOOP
2774 IF FIRST
2775 THEN
2776 l('-- do an or between all the transformations of an attribute -- ');
2777 l('(');
2778 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
2779 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
2780 's2.'|| trans.staged_attribute_column || ' = s1.'||
2781 trans.staged_attribute_column || ')');
2782 FIRST := FALSE;
2783 ELSE
2784 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
2785 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
2786 's2.'|| trans.staged_attribute_column || ' = s1.'||
2787 trans.staged_attribute_column || ')');
2788 END IF;
2789
2790 END LOOP;
2791 l(')');
2792 END LOOP;
2793
2794 -- IF THE ENTITY IS NOT A PARTY THEN WE NEED TO MAKE SURE THAT ALL PARTY LEVEL
2795 -- ACQUISTION ATTRIBUTES (IF ANY), THAT SERVE AS FILTERS ARE MATCHED.
2796
2797
2798 l(';');
2799 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Ending insert of ' || p_entity || ''''|| ');');
2800 l('FND_FILE.put_line(FND_FILE.log,''Number of records inserted ''||SQL%ROWCOUNT);');
2801 l('FND_FILE.put_line(FND_FILE.log,''End time to insert ''||to_char(sysdate,''hh24:mi:ss''));');
2802 l('FND_CONCURRENT.AF_Commit;');
2803 END;
2804
2805 -------------------------------------------------------------------------
2806 -- gen_insert_footer_int :
2807 -------------------------------------------------------------------------
2808 PROCEDURE gen_insert_footer_int(p_match_rule_id number)
2809 IS
2810 FIRST1 boolean;
2811 FIRST boolean;
2812 BEGIN
2813 l(')');
2814
2815 -- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES
2816 IF has_party_filter_attributes(p_match_rule_id)= 'Y'
2817 THEN
2818 l('------- ONE TIME CHECK FOR PARTY LEVEL FILTER ATTRIBUTES---------');
2819 l('where EXISTS (');
2820 l('SELECT 1 FROM HZ_SRCH_PARTIES p1, HZ_SRCH_PARTIES p2');
2821 l('WHERE p1.batch_id = p_batch_id and p1.party_osr = f and p1.party_os = fos');
2822 l('and p2.batch_id = p_batch_id and p2.party_osr = t and p2.party_os = tos');
2823 FIRST1 := TRUE;
2824 FOR attrs in (
2825 SELECT primary_attribute_id
2826 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2827 where p.match_rule_id=p_match_rule_id
2828 and p.attribute_id=a.attribute_id
2829 and a.entity_name = 'PARTY'
2830 and nvl(p.filter_flag,'N') = 'Y'
2831 and HZ_IMP_DQM_STAGE.EXIST_COL(a.attribute_name, a.entity_name ) = 'Y'
2832 )
2833 LOOP
2834 IF FIRST1
2835 THEN
2836 FIRST1 := FALSE;
2837 END IF;
2838
2839 -- between attributes
2840 l('and');
2841
2842 FIRST := TRUE;
2843 FOR trans in ( SELECT staged_attribute_column
2844 FROM hz_primary_trans pt, hz_trans_functions_vl f
2845 where f.function_id = pt.function_id
2846 and pt.primary_attribute_id = attrs.primary_attribute_id
2847 )
2848 LOOP
2849 IF FIRST
2850 THEN
2851 l('-- do an or between all the transformations of an attribute -- ');
2852 l('(');
2853 l('((p1.'|| trans.staged_attribute_column || ' is null and ' ||
2854 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
2855 'p2.'|| trans.staged_attribute_column || ' = p1.'||
2856 trans.staged_attribute_column || ')');
2857 FIRST := FALSE;
2858 ELSE
2859 l('or ((p1.'|| trans.staged_attribute_column || ' is null and ' ||
2860 'p2.'|| trans.staged_attribute_column || ' is null) or ' ||
2861 'p2.'|| trans.staged_attribute_column || ' = p1.'||
2862 trans.staged_attribute_column || ')');
2863 END IF;
2864
2865 END LOOP;
2866 l(')');
2867 END LOOP;
2868 l(')');
2869 END IF;
2870
2871 l('group by f, t, fos, tos');
2872
2873 -- having clause should exist only if x_insert_threshold
2874 -- is positive
2875 IF get_insert_threshold(p_match_rule_id) > 0
2876 THEN
2877 l('having sum(score) >= x_insert_threshold');
2878 END IF;
2879
2880 l(';');
2881 l('FND_FILE.put_line(FND_FILE.log,''Number of parties inserted ''||SQL%ROWCOUNT);');
2882 l('FND_FILE.put_line(FND_FILE.log,''End time of insert ''||to_char(sysdate,''hh24:mi:ss''));');
2883 l('FND_CONCURRENT.AF_Commit;');
2884 END;
2885
2886
2887 -------------------------------------------------------------------------
2888 -- gen_update_template_int :
2889 -------------------------------------------------------------------------
2890 PROCEDURE gen_update_template_int (
2891 s_table VARCHAR2,
2892 p_table VARCHAR2,
2893 p_match_rule_id NUMBER,
2894 p_entity VARCHAR2,
2895 p_match_all_flag VARCHAR2
2896 )
2897 IS
2898 FIRST BOOLEAN ;
2899 FIRST1 BOOLEAN;
2900 outer_row_count number := 0 ;
2901 inner_row_counter number := 0;
2902 outer_row_counter number := 0;
2903
2904 BEGIN
2905
2906 l('');
2907 l('');
2908 l('FND_FILE.put_line(FND_FILE.log,''------------------------------------------------'');');
2909 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Beginning update of Parties on the basis of ' || p_entity || ''''|| ');');
2910 l('FND_FILE.put_line(FND_FILE.log,''Start time of update ''||to_char(sysdate,''hh24:mi:ss''));');
2911 l('open x_ent_cur for');
2912 l('select f,t,max(score) from (');
2913 l(' select /*+ USE_CONCAT */ s1.party_osr f, s2.party_osr t,');
2914
2915 -- Generate the Secondary Attribute section of the query for the passed in entity
2916 SELECT count(1) into outer_row_count
2917 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2918 where a.attribute_id=s.attribute_id
2919 and s.match_rule_id=p_match_rule_id
2920 and a.entity_name = p_entity;
2921
2922 IF has_scoring_attributes(p_match_rule_id, p_entity)
2923 THEN
2924
2925 FOR attrs in (
2926 SELECT score,s.attribute_id , secondary_attribute_id
2927 FROM HZ_MATCH_RULE_SECONDARY s, HZ_TRANS_ATTRIBUTES_VL a
2928 where a.attribute_id=s.attribute_id
2929 and s.match_rule_id=p_match_rule_id
2930 and a.entity_name = p_entity)
2931 LOOP
2932 outer_row_counter := outer_row_counter + 1;
2933 inner_row_counter := 0;
2934
2935 FOR trans in (
2936 SELECT round(transformation_weight/100*attrs.score) score, staged_attribute_column
2937 FROM hz_secondary_trans st, hz_trans_functions_vl f
2938 where f.function_id=st.function_id
2939 and st.secondary_attribute_id = attrs.secondary_attribute_id
2940 order by transformation_weight desc)
2941 LOOP
2942 inner_row_counter := inner_row_counter + 1;
2943 l('decode(instrb(s2.'||trans.staged_attribute_column
2944 || ',s1.'||trans.staged_attribute_column||
2945 '),1,'|| trans.score||',');
2946
2947 END LOOP;
2948
2949 l('0');
2950
2951 -- Need to have as many right parentheses as inner_row_counter
2952 FOR I IN 1 .. inner_row_counter
2953 LOOP
2954 l(')');
2955 END LOOP;
2956
2957 IF outer_row_counter < outer_row_count
2958 THEN
2959 l('+');
2960 END IF;
2961 END LOOP;
2962 ELSE
2963 l('0 ');
2964 END IF;
2965
2966 l('score');
2967 l('from hz_int_dup_results h1, '||s_table||' s1, '||s_table||' s2');
2968 l('where');
2969 l('s1.party_osr = h1.f_osr and s2.party_osr = h1.t_osr and h1.batch_id = p_batch_id');
2970 l('and s1.party_osr between from_osr and to_osr');
2971
2972 -- only for contact point types
2973 IF p_entity = 'CONTACT_POINTS'
2974 THEN
2975 l('and s1.contact_point_type = s2.contact_point_type');
2976 END IF;
2977
2978
2979 l('and ( ');
2980
2981 -- Generate the Primary Attribute section of the query for the passed in entity
2982 -- TAKE CARE OF NON-FILTER ATTRIBUTES FIRST
2983 FIRST1 := TRUE;
2984 -- Generate the Primary Attribute section of the query for the passed in entity
2985 FOR attrs in (
2986 SELECT primary_attribute_id
2987 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
2988 where p.match_rule_id=p_match_rule_id
2989 and p.attribute_id=a.attribute_id
2990 and a.entity_name = p_entity
2991 and nvl(p.filter_flag,'N') = 'N' )
2992 LOOP
2993 -- between attributes
2994 IF FIRST1
2995 THEN
2996 FIRST1 := FALSE;
2997 l('------------ NON FILTER ATTRIBUTES SECTION ------------------------');
2998 ELSE
2999 IF p_match_all_flag = 'Y'
3000 THEN
3001 l('and');
3002 ELSE
3003 l('or');
3004 END IF;
3005
3006 END IF;
3007
3008 FIRST := TRUE;
3009 FOR trans in ( SELECT staged_attribute_column
3010 FROM hz_primary_trans pt, hz_trans_functions_vl f
3011 where f.function_id = pt.function_id
3012 and pt.primary_attribute_id = attrs.primary_attribute_id
3013 )
3014 LOOP
3015 IF FIRST
3016 THEN
3017 l('-- do an or between all the transformations of an attribute -- ');
3018 l('(');
3019 l('(s1.'|| trans.staged_attribute_column || ' is not null and ' ||
3020 's2.'|| trans.staged_attribute_column || ' like s1.'||
3021 trans.staged_attribute_column || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
3022 FIRST := FALSE;
3023 ELSE
3024 l(' or (s1.'|| trans.staged_attribute_column || ' is not null and ' ||
3025 's2.'|| trans.staged_attribute_column || ' '|| ' like s1.'||
3026 trans.staged_attribute_column || ' ' || ' || decode(sign(lengthb(s1.' || trans.staged_attribute_column || ')-'|| HZ_DQM_DUP_ID_PKG.l_like_comparison_min_length || '),1,''%'',''''))');
3027 END IF;
3028
3029 END LOOP;
3030 l(')');
3031
3032 END LOOP;
3033 l(')');
3034
3035 -- NOW TAKE CARE OF FILTER ATTRIBUTES
3036 FIRST1 := TRUE;
3037 FOR attrs in (
3038 SELECT primary_attribute_id
3039 FROM HZ_MATCH_RULE_PRIMARY p, HZ_TRANS_ATTRIBUTES_VL a
3040 where p.match_rule_id=p_match_rule_id
3041 and p.attribute_id=a.attribute_id
3042 and a.entity_name = p_entity
3043 and nvl(p.filter_flag,'N') = 'Y' )
3044 LOOP
3045 -- between attributes
3046 IF FIRST1
3047 THEN
3048 FIRST1 := FALSE;
3049 l('------------ FILTER ATTRIBUTES SECTION ------------------------');
3050 END IF;
3051
3052 l('and ');
3053
3054 FIRST := TRUE;
3055 FOR trans in ( SELECT staged_attribute_column
3056 FROM hz_primary_trans pt, hz_trans_functions_vl f
3057 where f.function_id = pt.function_id
3058 and pt.primary_attribute_id = attrs.primary_attribute_id
3059 )
3060 LOOP
3061 IF FIRST
3062 THEN
3063 l('-- do an or between all the transformations of an attribute -- ');
3064 l('(');
3065 l('((s1.'|| trans.staged_attribute_column || ' is null and ' ||
3066 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
3067 's2.'|| trans.staged_attribute_column || ' = s1.'||
3068 trans.staged_attribute_column || ')');
3069 FIRST := FALSE;
3070 ELSE
3071 l('or ((s1.'|| trans.staged_attribute_column || ' is null and ' ||
3072 's2.'|| trans.staged_attribute_column || ' is null) or ' ||
3073 's2.'|| trans.staged_attribute_column || ' = s1.'||
3074 trans.staged_attribute_column || ')');
3075 END IF;
3076
3077 END LOOP;
3078 l(')');
3079 END LOOP;
3080 l(') group by f,t ;');
3081 l('HZ_DQM_DUP_ID_PKG.update_hz_int_dup_results(p_batch_id,x_ent_cur);');
3082 l('close x_ent_cur;');
3083 l('FND_FILE.put_line(FND_FILE.log,''Number of parties updated ''||SQL%ROWCOUNT);');
3084 l('FND_FILE.put_line(FND_FILE.log,''End time to update ''||to_char(sysdate,''hh24:mi:ss''));');
3085 l('FND_FILE.put_line(FND_FILE.log,'||''''|| 'Ending update of Parties on the basis of ' || p_entity || ''''|| ');');
3086 l('FND_CONCURRENT.AF_Commit;');
3087
3088 END;
3089
3090 -------------------------------------------------------------------------
3091 -- gen_footer_int :
3092 -------------------------------------------------------------------------
3093 PROCEDURE gen_footer_int(p_pkg_name VARCHAR2)
3094 IS
3095 BEGIN
3096 l('');
3097 l('---------- exception block ---------------');
3098 l('EXCEPTION');
3099 l('WHEN OTHERS THEN');
3100 l(' FND_MESSAGE.SET_NAME(''AR'', ''HZ_DQM_API_ERROR'');');
3101 l(' FND_MESSAGE.SET_TOKEN(''PROC'',''' || p_pkg_name || '.interface_join_entities'');');
3102 l(' FND_MESSAGE.SET_TOKEN(''ERROR'' ,SQLERRM );');
3103 l(' FND_MSG_PUB.ADD;');
3104 l(' RAISE FND_API.G_EXC_UNEXPECTED_ERROR;');
3105 l('END interface_join_entities;');
3106 END;
3107
3108
3109
3110 -------------------------------------------------------------------------
3111 -- gen_pkg_body_int_join : A Private procedure that will generate the package body
3112 -- of the match rule
3113 -------------------------------------------------------------------------
3114
3115 PROCEDURE gen_pkg_body_int_join(
3116 p_pkg_name IN VARCHAR2,
3117 p_match_rule_id IN NUMBER,
3118 p_att_flag IN VARCHAR2
3119 )
3120 IS
3121 CURSOR entity_cur IS
3122 select entity_name, search_table_name, entity_table_name, entity_osr_name, entity_os_name, sc, att_flag
3126 'PARTY_SITES', 'HZ_SRCH_PSITES',
3123 from
3124 (select entity_name, decode(entity_name,
3125 'PARTY','HZ_SRCH_PARTIES',
3127 'CONTACTS','HZ_SRCH_CONTACTS',
3128 'CONTACT_POINTS', 'HZ_SRCH_CPTS') search_table_name,
3129 decode(entity_name,
3130 'PARTY','HZ_STAGED_PARTIES',
3131 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
3132 'CONTACTS','HZ_STAGED_CONTACTS',
3133 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
3134 decode(entity_name,
3135 'PARTY','PARTY_OSR',
3136 'PARTY_SITES', 'PARTY_SITE_OSR',
3137 'CONTACTS','CONTACT_OSR',
3138 'CONTACT_POINTS', 'CONTACT_PT_OSR') entity_osr_name,
3139 decode(entity_name,
3140 'PARTY','PARTY_OS',
3141 'PARTY_SITES', 'PARTY_SITE_OS',
3142 'CONTACTS','CONTACT_OS',
3143 'CONTACT_POINTS', 'CONTACT_PT_OS') entity_os_name,
3144 sum(score) sc, 'S' att_flag
3145 from hz_trans_attributes_vl a, hz_match_rule_secondary s
3146 where s.match_rule_id = p_match_rule_id
3147 and s.attribute_id = a.attribute_id
3148 group by entity_name
3149 union all
3150 select entity_name, decode(entity_name,
3151 'PARTY','HZ_SRCH_PARTIES',
3152 'PARTY_SITES', 'HZ_SRCH_PSITES',
3153 'CONTACTS','HZ_SRCH_CONTACTS',
3154 'CONTACT_POINTS', 'HZ_SRCH_CPTS') search_table_name,
3155 decode(entity_name,
3156 'PARTY','HZ_STAGED_PARTIES',
3157 'PARTY_SITES', 'HZ_STAGED_PARTY_SITES',
3158 'CONTACTS','HZ_STAGED_CONTACTS',
3159 'CONTACT_POINTS', 'HZ_STAGED_CONTACT_POINTS') entity_table_name,
3160 decode(entity_name,
3161 'PARTY','PARTY_OSR',
3162 'PARTY_SITES', 'PARTY_SITE_OSR',
3163 'CONTACTS','CONTACT_OSR',
3164 'CONTACT_POINTS', 'CONTACT_PT_OSR') entity_osr_name,
3165 decode(entity_name,
3166 'PARTY','PARTY_OS',
3167 'PARTY_SITES', 'PARTY_SITE_OS',
3168 'CONTACTS','CONTACT_OS',
3169 'CONTACT_POINTS', 'CONTACT_PT_OS') entity_os_name,
3170 0 sc, 'P' att_flag
3171 from hz_trans_attributes_vl a, hz_match_rule_primary p
3172 where p.match_rule_id = p_match_rule_id
3173 and p.attribute_id = a.attribute_id
3174 group by entity_name
3175 ) where att_flag = p_att_flag
3176 order by sc desc ;
3177 srt score_rec_type;
3178 threshold number;
3179 match_all_flag varchar2(1);
3180 row_count number;
3181 no_of_entities number;
3182 template varchar2(30);
3183 insert_stmt_is_open boolean;
3184 BEGIN
3185
3186 -- Get the threshold and match_all_flag
3187 select match_score, match_all_flag into threshold, match_all_flag
3188 from hz_match_rules_vl
3189 where match_rule_id = p_match_rule_id;
3190
3191 -- Get the different aggregates that would help in determining the template
3192 -- that need to be used -- UNION/UPDATE for the corresponding entity.
3193
3194 -- If attribute flag is 'P', make the threshold 0
3195 -- This signifies that the match rule has no scoring attributes
3196 IF p_att_flag = 'P'
3197 THEN
3198 threshold := 0;
3199 srt.sum_score := 0;
3200 srt.min_score := 0;
3201 srt.max_score := 0;
3202 ELSE
3203 srt := get_misc_scores(p_match_rule_id);
3204 END IF;
3205
3206
3207 -- Initialize the number of entities
3208 no_of_entities := 0;
3209
3210 -- Get the number of entities
3211 FOR c0 in entity_cur
3212 LOOP
3213 no_of_entities := no_of_entities + 1;
3214 END LOOP;
3215
3216
3217 -- Before generating the code for the given match rule, we look at the
3218 -- match_all_flag to determine, the structure of the code that needs
3219 -- to go into the generated match rule package.
3220 -- The flag is always assumed to be 'N' by default ie., a match on ANY of the
3221 -- entities, would be given consideration.
3222 -- If flag = 'Y', then we need to make sure that every query after the first
3223 -- one is an update. We make this happen by manually setting the threshold.
3224 IF match_all_flag = 'Y'
3225 THEN
3226 threshold := srt.sum_score;
3227 END IF;
3228
3229 -- Generate the Header
3230 gen_header_int(p_pkg_name, p_match_rule_id);
3231
3232 l('------------------ PARTY LEVEL DUPLICATE IDENTIFICATION BEGINS --------------------');
3233
3234 -- Open the entity cursor, determine the templates (INSERT/UPDATE) for each
3235 -- and call the appropriate function to add lines to the generated package
3236 -- for the corresponding entity
3237 row_count := 0;
3238 insert_stmt_is_open := false;
3239
3243 -- 3. all update templates are modular and do not need any special treatment for opening and closing.
3240 -- some basic observations that would help in this logic
3241 -- 1. There will always be atleast one insert statement
3242 -- 2. all insert templates would come under the insert statement
3244 -- 4. all update templates would be together
3245 -- 5. when gnerating an update template, we need to make sure that the insert statement is closed.
3246 -- 6. in the event that we never have an update template, we close the insert statement, outside the loop.
3247 FOR entity_cur_rec in entity_cur
3248 LOOP
3249 row_count := row_count + 1;
3250
3251
3252
3253 -- First row, is always an insert, unless the match rule returns nothing due
3254 -- to an erroneous combination of the threshold/match rule configuration.
3255 -- If that happnes we , get the hell out of here.
3256 IF row_count = 1
3257 THEN
3258 -- pass the first entity forcefully
3259 IF (srt.sum_score - threshold) >= 0
3260 THEN
3261 gen_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
3262 entity_cur_rec.entity_name, match_all_flag);
3263 insert_stmt_is_open := true;
3264 ELSE
3265 -- need to handle this by reporting an error and getting the hell out of here.
3266 null;
3267 return ;
3268 END IF;
3269 END IF;
3270
3271 IF row_count = 2
3272 THEN
3273
3274 IF (srt.sum_score - srt.max_score - threshold) >= 0
3275 THEN
3276 l('union all');
3277 gen_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
3278 entity_cur_rec.entity_name, match_all_flag);
3279 ELSE
3280 IF insert_stmt_is_open
3281 THEN
3282 gen_insert_footer_int(p_match_rule_id) ;
3283 insert_stmt_is_open := false;
3284 END IF;
3285 gen_update_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
3286 entity_cur_rec.entity_name, match_all_flag);
3287 END IF;
3288 END IF;
3289
3290 IF row_count = 3
3291 THEN
3292 IF no_of_entities = 3
3293 THEN
3294 IF (entity_cur_rec.sc - threshold) >= 0
3295 THEN
3296 l('union all');
3297 gen_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
3298 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
3299 ELSE
3300 IF insert_stmt_is_open
3301 THEN
3302 gen_insert_footer_int(p_match_rule_id) ;
3303 insert_stmt_is_open := false;
3304 END IF;
3305 gen_update_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
3306 entity_cur_rec.entity_name, match_all_flag);
3307 END IF;
3308
3309 ELSE
3310 IF ( entity_cur_rec.sc + srt.min_score - threshold) >= 0
3311 THEN
3312 l('union all');
3313 gen_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name, p_match_rule_id,
3314 entity_cur_rec.entity_name, match_all_flag);
3315 ELSE
3316 IF insert_stmt_is_open
3317 THEN
3318 gen_insert_footer_int(p_match_rule_id) ;
3319 insert_stmt_is_open := false;
3320 END IF;
3321 gen_update_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
3322 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
3323 END IF;
3324 END IF;
3325 END IF;
3326
3327 IF row_count = 4
3328 THEN
3329 IF (entity_cur_rec.sc - threshold) >= 0
3330 THEN
3331 l('union all');
3332 gen_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
3333 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
3334 ELSE
3335 IF insert_stmt_is_open
3336 THEN
3337 gen_insert_footer_int(p_match_rule_id);
3338 insert_stmt_is_open := false;
3339 END IF;
3340 gen_update_template_int(entity_cur_rec.search_table_name, entity_cur_rec.entity_table_name,
3341 p_match_rule_id, entity_cur_rec.entity_name, match_all_flag);
3342 END IF;
3343 END IF;
3344
3345 END LOOP;
3346
3347 -- Just to make sure that the insert statement is not open, after all the entity queries
3348 -- have been generated
3349 IF insert_stmt_is_open
3350 THEN
3351 gen_insert_footer_int(p_match_rule_id) ;
3352 insert_stmt_is_open := false;
3353 END IF;
3354
3355 -- generate code for detail level duplicate identification
3356 FOR entity_cur_rec in entity_cur
3357 LOOP
3358 IF entity_cur_rec.entity_name <> 'PARTY'
3359 THEN
3360 gen_dl_insert_template_int(entity_cur_rec.search_table_name,entity_cur_rec.entity_table_name,
3361 p_match_rule_id, entity_cur_rec.entity_name, entity_cur_rec.entity_osr_name,
3362 entity_cur_rec.entity_os_name, match_all_flag );
3363 END IF;
3364
3365 END LOOP;
3366 -- generate the footer for the package
3367 gen_footer_int(p_pkg_name) ;
3368
3369 END;
3370
3371
3372 PROCEDURE gen_pkg_body_int_join (
3373 p_pkg_name IN VARCHAR2,
3374 p_match_rule_id IN NUMBER
3375 )
3376 IS
3377 BEGIN
3378 IF has_scoring_attributes(p_match_rule_id)
3379 THEN
3380 gen_pkg_body_int_join(p_pkg_name, p_match_rule_id, 'S');
3381 ELSE
3382 gen_pkg_body_int_join(p_pkg_name, p_match_rule_id, 'P');
3383 END IF;
3384 END ;
3385
3386
3387
3388 END;