1 package body hr_dm_gen_tds as
2 /* $Header: perdmgnd.pkb 120.0 2005/05/31 17:08:28 appldev noship $ */
3
4
5 --type t_varchar2_tbl is table of varchar2(32767) index by binary_integer;
6 type t_varchar2_32k_tbl is table of varchar2(32767) index by binary_integer;
7
8
9 g_table_info hr_dm_gen_main.t_table_info;
10 g_columns_tbl hr_dm_library.t_varchar2_tbl;
11 g_parameters_tbl hr_dm_library.t_varchar2_tbl;
12 g_hier_columns_tbl hr_dm_library.t_varchar2_tbl;
13 g_hier_parameters_tbl hr_dm_library.t_varchar2_tbl;
14 g_resolve_pk_columns_tbl hr_dm_gen_main.t_fk_to_aol_columns_tbl;
15 g_surrogate_pk_col_param varchar2(30);
16
17 -- to store the package body in to array so as to overcome the limit of 32767
18 -- character the global variable is defined.
19 g_package_body dbms_sql.varchar2s;
20 g_package_index number := 0;
21
22 --c_newline constant varchar(1) default '
23 --';
24
25 --
26 -- Exception for generated text exceeding the maximum allowable buffer size.
27 --
28 plsql_value_error exception;
29 pragma exception_init(plsql_value_error, -6502);
30
31 -- ----------------------- indent -----------------------------------------
32 -- Description:
33 -- returns the 'n' blank spaces on a newline.used to indent the procedure
34 -- statements.
35 -- if newline parameter is 'Y' then start the indentation from new line.
36 -- ------------------------------------------------------------------------
37
38 function indent
39 (
40 p_indent_spaces in number default 0,
41 p_newline in varchar2 default 'Y'
42 ) return varchar2 is
43 l_spaces varchar2(100);
44 begin
45
46 l_spaces := hr_dm_library.indent(p_indent_spaces => p_indent_spaces,
47 p_newline => p_newline);
48 return l_spaces;
49 exception
50 when others then
51 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tups.indent',
52 '(p_indent_spaces - ' || p_indent_spaces ||
53 ')(p_newline - ' || p_newline || ')',
54 'R');
55 end indent;
56
57 -- ----------------------- format_comment ---------------------------------
58 -- Description:
59 -- formats the comments to be written into the procedure body
60 -- e.g comment string ' This is a example comment text' will be converted t
61 -- --
62 -- -- This is a example comment text.
63 -- --
64 -- ------------------------------------------------------------------------
65
66 function format_comment
67 (
68 p_comment_text in varchar2,
69 p_indent_spaces in number default 0,
70 p_ins_blank_lines in varchar2 default 'Y'
71 ) return varchar2 is
72
73 l_comment_text varchar2(20000);
74 l_comment_length number := length(p_comment_text);
75
76 --
77 -- maximum chracters for single comment text line ensuring the single
78 -- comment line cannot be more than 77 characters long excluding 3
79 -- characters ('-- ') at the begning of comment.
80 --
81
82 l_max_comment_line_len number := 77 - p_indent_spaces;
83 l_comment_line_len number;
84 l_comment_line_txt varchar2(80);
85
86 -- start and end pointer of comment line to be copied from comment text.
87 l_start_ptr number := 1;
88 l_end_ptr number;
89
90 -- used for wrapping
91 l_last_space_ptr number;
92 begin
93
94 if p_ins_blank_lines = 'Y' then
95 l_comment_text := indent(p_indent_spaces) || '--';
96 end if;
97
98 loop
99 l_end_ptr := l_start_ptr + l_max_comment_line_len - 1;
100
101 l_comment_line_txt := substr(p_comment_text,l_start_ptr,(l_end_ptr - l_start_ptr + 1));
102
103 l_comment_line_len := length(l_comment_line_txt);
104
105 -- comment line is less than the maximum text that come then it is ok,
106 -- otherwise do word wrapping.If the next character is a space there is
107 -- no need for wrapping
108
109 if l_comment_line_len >= l_max_comment_line_len and
110 substr(p_comment_text,l_end_ptr + 1,1) <> ' '
111 then
112
113 -- this function ensures the wrapping of the word. last word will come
114 -- either full or move to the next line.This gives the position of the
115 -- last space in the comment line text.
116
117 l_last_space_ptr := instr(l_comment_line_txt,' ',-1);
118
119 -- adjust the end pointer as we want to copy the string upto the last
120 -- space only, the remaining word should go into next line.
121
122 l_end_ptr := l_end_ptr - (length(l_comment_line_txt) - l_last_space_ptr);
123
124 end if;
125
126 -- now the end_ptr gives the length of the comment line that can be copied
127 -- with a space in the end.
128
129 l_comment_text := l_comment_text || indent(p_indent_spaces) || '-- ';
130
131
132 l_comment_text := l_comment_text || substr(p_comment_text,l_start_ptr,
133 (l_end_ptr - l_start_ptr + 1));
134
135 l_start_ptr := l_end_ptr +1;
136
137 if l_start_ptr > l_comment_length then
138 exit;
139 end if;
140 end loop;
141
142
143 if p_ins_blank_lines = 'Y' then
144 l_comment_text := l_comment_text || indent(p_indent_spaces) || '--';
145 end if;
146 return l_comment_text;
147 exception
148 when others then
149 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.format_comment',
150 '(p_ins_blank_lines - ' || p_ins_blank_lines ||
151 ')(p_indent_spaces - ' || p_indent_spaces ||
152 ')(p_comment_text - ' || p_comment_text || ')'
153 ,'R');
154 end format_comment;
155
156 --------------------- init_package_body----------------------------------------
157 -- This package will delete all the elements from the package body pl/sql table.
158 -------------------------------------------------------------------------------
159 procedure init_package_body is
160 l_index number := g_package_body.first;
161 begin
162 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.init_package_body', 5);
163
164 -- delete all elements from package body pl/sql table.
165 while l_index is not null loop
166 g_package_body.delete(l_index);
167 l_index := g_package_body.next(l_index);
168 end loop;
169 --initialize the index
170 g_package_index := 0;
171 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.init_package_body',
172 25);
173 exception
174 when others then
175 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.init_package_body',
176 '(none)','R');
177 raise;
178 end init_package_body;
179 -- -----------------------add_debug_messages ---------------------------------
180 -- Description:
181 -- This procedure will add the debug messages to the generated procedures.
182 -- Debug messages are added depending upon the procedure and location.
183 -- Debug messages are added at the start of the procedure body or at the end.
184 -- Input Parameter :
185 -- p_procedure_name : procedure name of the TDS package. e.g 'DOWNLOAD',
186 -- 'CALCULATE_RANGES', 'DELETE_SOURCE', e.t.c.
187 -- p_message_location : it can have following two values
188 -- 'START' - to put the debug message at start
189 -- 'END' - to put the debug message at end.
190 -- ------------------------------------------------------------------------
191 procedure add_debug_messages
192 (
193 p_table_info in hr_dm_gen_main.t_table_info,
194 p_procedure_name in varchar2,
195 p_message_location in varchar2,
196 p_proc_body in out nocopy varchar2
197 ) is
198 l_package_name varchar2(30) := 'hrdmd_' || p_table_info.short_name;
199 l_parameter_string varchar2(1000);
200 l_local_variable_string varchar2(1000);
201 l_indent number;
202 begin
203
204
205 if upper(p_procedure_name) in ('DOWNLOAD', 'DOWNLOAD_HIERARCHY') then
206 l_indent := 4;
207 l_parameter_string := '''(p_migration_type - '' || p_migration_type || ' ||
208 indent(l_indent + 29) || ''')(p_business_group_id - '' || p_business_group_id ||' ||
209 indent(l_indent + 29) || ''')(p_last_migration_date - '' || p_last_migration_date ||' ||
210 indent(l_indent + 29) || ''')(p_start_id - '' || p_start_id ||' ||
211 indent(l_indent + 29) || ''')(p_end_id - '' || p_end_id ||' ||
212 indent(l_indent + 29) || ''')(p_batch_id - '' || p_batch_id || ' ||
213 indent(l_indent + 29) || ''')(p_chunk_size - '' || p_chunk_size ||' ||
214 indent(l_indent + 29) || ''')''';
215
216 l_local_variable_string :=
217 ' || ' || '''(l_rec_inserted_cnt - '' || l_rec_inserted_cnt ||' ||
218 indent(l_indent + 29) || ''')''';
219
220 elsif upper(p_procedure_name) = 'CALCULATE_RANGES' then
221 l_indent := 2;
222 l_parameter_string := '''(p_business_group_id - '' || p_business_group_id || ' ||
223 indent(l_indent + 29) || ''')(p_last_migration_date - '' || p_last_migration_date ||' ||
224 indent(l_indent + 29) || ''')(p_phase_item_id - '' || p_phase_item_id ||' ||
225 indent(l_indent + 29) || ''')(p_no_of_threads - '' || p_no_of_threads ||' ||
226 indent(l_indent + 29) || ''')''';
227
228 if p_table_info.surrogate_primary_key = 'Y' then
229 l_local_variable_string :=
230 ' || ' || '''(l_max_key_value - '' || l_max_key_value ||' ||
231 indent(l_indent + 29) || ''')(l_min_key_value - '' || l_min_key_value ||' ||
232 indent(l_indent + 29) || ''')(l_starting_process_sequence - '' || l_starting_process_sequence ||' ||
233 indent(l_indent + 29) || ''')(l_ending_process_sequence - '' || l_ending_process_sequence ||' ||
234 indent(l_indent + 29) || ''')l_range_value - '' || l_range_value ||' ||
235 indent(l_indent + 29) || ''')''';
236 end if;
237
238 elsif upper(p_procedure_name) = 'DELETE_DATAPUMP' then
239 l_indent := 2;
240 l_parameter_string := '''(p_start_id - '' || p_start_id || ' ||
241 indent(l_indent + 29) || ''')(p_end_id - '' || p_end_id ||' ||
242 indent(l_indent + 29) || ''')(p_batch_id - '' || p_batch_id ||' ||
243 indent(l_indent + 29) || ''')(p_chunk_size - '' || p_chunk_size ||' ||
244 indent(l_indent + 29) || ''')''';
245
246 l_local_variable_string :=
247 ' || ' || '''(l_rec_deleted_cnt - '' || l_rec_deleted_cnt ||' ||
248 indent(l_indent + 29) || ''')''';
249
250 elsif upper(p_procedure_name) = 'DELETE_SOURCE' then
251 l_indent := 2;
252 l_parameter_string := '''(p_business_group_id - '' || p_business_group_id || ' ||
253 indent(l_indent + 29) || '''(p_start_id - '' || p_start_id || ' ||
254 indent(l_indent + 29) || ''')(p_end_id - '' || p_end_id ||' ||
255 indent(l_indent + 29) || ''')(p_chunk_size - '' || p_chunk_size ||' ||
256 indent(l_indent + 29) || ''')''';
257
258 l_local_variable_string :=
259 ' || ' || '''(l_rec_deleted_cnt - '' || l_rec_deleted_cnt ||' ||
260 indent(l_indent + 29) || ''')''';
261
262 end if;
263
264 if p_message_location = 'START' then
265 p_proc_body := indent(l_indent) || '-- debug messages ';
266 p_proc_body := p_proc_body || indent(l_indent) ||
267 'hr_dm_utility.message(''ROUT'',''entry:' || l_package_name ||
268 '.' || p_procedure_name || ''', 5);' || indent(l_indent);
269
270 p_proc_body := p_proc_body || 'hr_dm_utility.message(''PARA'','
271 || l_parameter_string || ', 10);';
272
273 end if;
274
275
276 if p_message_location = 'END' then
277 p_proc_body := indent(2) || '-- debug messages ';
278
279 -- procedure specific debug messages.
280
281 if upper(p_procedure_name) in ('DOWNLOAD', 'DOWNLOAD_HIERARCHY') then
282 p_proc_body := p_proc_body ||indent(2) ||
283 'hr_dm_utility.message(''INFO'',''Number Of records downloaded '' || ' ||
284 indent( l_indent + 27) ||'''(l_rec_inserted_cnt) : '' || ' ||
285 'l_rec_inserted_cnt , 15);';
286
287 elsif upper(p_procedure_name) = 'CALCULATE RANGES' then
288 p_proc_body := p_proc_body ||indent(2) ||
289 'hr_dm_utility.message(''INFO'',''Range Value '' || ' ||
290 indent( l_indent + 27) ||'''(l_range_value) : '' || ' ||
291 'l_range_value , 15);';
292
293 elsif upper(p_procedure_name) in ('DELETE_SOURCE', 'DELETE_DATAPUMP') then
294 p_proc_body := p_proc_body ||indent(2) ||
295 'hr_dm_utility.message(''INFO'',''Number Of records deleted '' || ' ||
296 indent( l_indent + 27) ||'''(l_rec_deleted_cnt) : '' || ' ||
297 'l_rec_deleted_cnt , 15);';
298 end if;
299
300 p_proc_body := p_proc_body ||indent(2) ||
301 'hr_dm_utility.message(''ROUT'',''exit:' || l_package_name ||
302 '.' || p_procedure_name || ''', 25);';
303
304 p_proc_body := p_proc_body || indent || 'exception' ||
305 indent(2) || 'when others then ' || indent(4) ||
306 'hr_dm_utility.error(SQLCODE,''' || l_package_name || '.' ||
307 p_procedure_name || ''', ' || indent(l_indent + 29) || l_parameter_string ||
308 l_local_variable_string || ',''R'');' || indent(2) || ' raise;' ||
309 indent || 'end ' || p_procedure_name|| ';';
310 end if;
311
312 hr_dm_utility.message('PARA','(p_proc_body_tbl - table of varchar2' ,10);
313
314 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.add_debug_messages',
315 25);
316 exception
317 when others then
318 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.add_debug_messages',
319 '(none)','R');
320 raise;
321 end add_debug_messages;
322 -- -----------------------add_to_package_body; ---------------------------------
323 -- Description:
324 -- This procedure will be called by each procedure to be created by TUPS.
325 -- Each procedure will be stored in the array of varchar2(32767).
326 -- The input to this procedure is pl/sql table i.e array of string.
327 -- Now the task of this procedure is to split the above array elements into
328 -- array elements of size 256. This is required so as to the package body
329 -- of more than 32 K size can be parsed using dbms_sql procedure.
330 --
331 -- ------------------------------------------------------------------------
332
333 procedure add_to_package_body
334 (
335 p_proc_body_tbl t_varchar2_32k_tbl
336 ) is
337
338 l_proc_index number := p_proc_body_tbl.first;
339 l_string_index number; -- variable to read the string characters
340 l_loop_cnt number;
341 begin
342
343 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.add_to_package_body-1', 5);
344 hr_dm_utility.message('PARA','(p_proc_body_tbl - table of varchar2' ,10);
345
346 while l_proc_index is not null loop
347
348 l_string_index := 1;
349 l_loop_cnt := 1;
350 -- read the string of the procedure body and chop it into the array element
351 -- size of 256 and store it into the global package body. Each looping will
352 -- will read the 256 characters from the procedure body and it will go on
353 -- until no more characters to read.
354 loop
355 if substr(p_proc_body_tbl(l_proc_index),l_string_index,256) is null
356 then
357 exit;
358 end if;
359 g_package_index := g_package_index + 1;
360
361 -- add the procedure body to
362 g_package_body (g_package_index) :=
363 substr(p_proc_body_tbl(l_proc_index),
364 l_string_index ,256);
365 l_string_index := 256*l_loop_cnt + 1;
366 l_loop_cnt := l_loop_cnt + 1;
367 end loop;
368
369 l_proc_index := p_proc_body_tbl.next(l_proc_index);
370 end loop;
371 hr_dm_utility.message('INFO',
372 '(l_loop_cnt - ' || l_loop_cnt ||
373 ')(l_string_index - ' ||l_string_index ||
374 ')( g_package_index - ' || g_package_index || ')'
375 ,15);
376 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.add_to_package_body -1',
377 25);
378 exception
379 when others then
380 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.add_to_package_body-1',
381 '(l_loop_cnt - ' || l_loop_cnt ||
382 ')(l_string_index - ' ||l_string_index ||
383 ')( g_package_index - ' || g_package_index || ')'
384 ,'R');
385 raise;
386 end add_to_package_body;
387 -- ----------------------- get_derive_from_clause -------------------------
388 -- Description:
389 -- Uses the derive_sql_source_tables info stored in HR_DM_TABLES to form the
390 -- 'from clause'.
391 -- The from clause stored in each derive field will be in the following format :
392 -- table1 tbl,:table2 tbl2, :table3 tbl3
393 -- where ':' is the next line indicator i.e : will be replaced with new line.
394 -- o If 'from' string is not there it puts the from string.
395 -- ------------------------------------------------------------------------------
396 procedure get_derive_from_clause
397 (
398 p_table_info in hr_dm_gen_main.t_table_info,
399 p_from_clause in out nocopy varchar2,
400 p_lpad_spaces in number default 2
401 ) is
402 l_derive_sql hr_dm_tables.derive_sql_download_full%type;
403 l_start_ptr number;
404 l_end_ptr number;
405 l_where_string varchar2(25) := 'where';
406 l_terminator varchar2(5) := ';';
407 begin
408 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.get_derive_from_clause', 5);
409 hr_dm_utility.message('PARA','(p_from_clause - ' || p_from_clause ||
410 ')(p_lpad_spaces - ' || p_lpad_spaces ||
411 ')', 10);
412 l_derive_sql := p_table_info.derive_sql_source_tables;
413
414
415 -- if 'where' string is not there then add the where string.
416 if instr(lower(l_derive_sql),'from') <= 0 then
417 p_from_clause := ' from ';
418 end if;
419
420 l_end_ptr := instr(l_derive_sql,':') - 1;
421 -- read the where clause string until first ':' . add the new line and chop
422 -- the where clause string upto ':' character. Continue this process until
423 -- full where clause is formatted.
424 loop
425
426 p_from_clause := p_from_clause || substr(l_derive_sql,1,
427 l_end_ptr) || indent(p_lpad_spaces + 5);
428 -- remove the characters from where clause which have been appended in
429 -- the where clause.
430 l_derive_sql := substr(l_derive_sql,l_end_ptr + 2);
431 --
432 l_end_ptr := instr(l_derive_sql,':') - 1;
433
434 if l_end_ptr <= 0 or l_end_ptr is null then
435 p_from_clause := p_from_clause || l_derive_sql;
436 exit;
437 end if;
438 end loop;
439
440 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_derive_from_clause',
441 25);
442 hr_dm_utility.message('PARA','(p_from_clause - ' || p_from_clause || ')',30);
443 exception
444 when others then
445 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_derive_from_clause',
446 '(l_derive_sql - ' || l_derive_sql ||
447 ')(l_end_ptr - ' || l_end_ptr ||
448 ')(p_from_clause - ' || p_from_clause || ')'
449 ,'R');
450 raise;
451 end get_derive_from_clause;
452 ---
453 -- ----------------------- get_cursor_from_clause -------------------------
454 -- Description:
455 -- Get the list of all the tables required to get the download from clause.
456 -- if the business group_id field does not exist in the table to be downloaded
457 -- then it is derived from the table hierarchy table.
458 -- ------------------------------------------------------------------------
459 procedure get_cursor_from_clause
460 (
461 p_table_info in hr_dm_gen_main.t_table_info,
462 p_from_clause out nocopy varchar2 ,
463 p_lpad_spaces in number default 2
464 ) is
465
466 l_parent_table_info hr_dm_gen_main.t_table_info;
467
468 -- get all parent tables required to get the business group id, if business
469 -- group id is not there in the table to be downloaded.
470
471 cursor csr_get_table is
472
473 select distinct parent_table_id
474 from (select table_id,parent_table_id
475 from hr_dm_hierarchies
476 where hierarchy_type = 'PC')
477 start with table_id = p_table_info.table_id
478 connect by prior parent_table_id = table_id;
479 begin
480
481 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.get_cursor_from_clause', 5);
482
483 -- check if the from clause is defined for this table i.e
484 -- derive_sql_source_tables field is not null. If yes then
485 -- call get_derive_from_clause procedure to format the from
486 -- clause defined in the table.
487
488 if p_table_info.derive_sql_source_tables is not null then
489 get_derive_from_clause ( p_table_info => p_table_info,
490 p_from_clause => p_from_clause,
491 p_lpad_spaces => p_lpad_spaces);
492 return;
493 end if;
494
495 p_from_clause := lpad(' ',p_lpad_spaces) ||'from ' ||
496 p_table_info.table_name || ' ' || p_table_info.alias;
497
498 -- if the table to be downloaded has table hierarchy i.e business group id
499 -- has to be derived from table hierarchy i.e parent tables.
500 if p_table_info.table_hierarchy = 'Y' and p_table_info.global_data = 'N' then
501 for cst_get_table_rec in csr_get_table loop
502 -- get the parent table name
503 hr_dm_library.get_table_info (cst_get_table_rec.parent_table_id,
504 l_parent_table_info);
505 p_from_clause := p_from_clause || indent(p_lpad_spaces + 5) || ',' ||
506 l_parent_table_info.table_name ||' ' || l_parent_table_info.alias;
507 end loop;
508 end if;
509 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_cursor_from_clause',
510 25);
511 hr_dm_utility.message('PARA','(p_from_clause - ' || p_from_clause,30);
512 exception
513 when others then
514 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_cursor_from_clause',
515 '(none)','R');
516 p_from_clause := null;
517 raise;
518 end get_cursor_from_clause;
519
520 -- ----------------------- get_derive_where_clause -------------------------
521 -- Description:
522 -- Uses the derive_sql info stored in HR_DM_TABLES for each type of cursors.
523 -- The where clause stored in each derive field will
524 -- example derive where clause :
525 -- where tbl.col1 = tbl2.col1 : and tbl.col2 = tbl1.col2 : and tbl.col3 = tbl3.col3
526 -- Above derive where clause will be converted as
527 -- where tbl.col1 = tbl2.col1
528 -- and tbl.col2 = tbl1.col2
529 -- and tbl.col3 = tbl3.col3
530 -- by this procedure. replace ':' by newline feed.
531 -- o may or may not include the 'where' string. If the 'where' string is not
532 -- there this procedure will put the 'where' string
533 -- o may or may not have the where clause terminator ';'. If it is not there
534 -- it will add it.
535 -- o the next line indicator will be ':' i.e : will be replaced with new line.
536 -- p_cursor_type :- 'DOWNLOAD' - where clause for full download
537 -- 'DOWNLOAD_DT' - where clause for date track table additive
538 -- download
539 -- 'CALCULATE_RANGES' - where clause for calculated ranges
540 -- 'DELETE_SOURCE' - where clause for delete source
541 -- ------------------------------------------------------------------------------
542 procedure get_derive_where_clause
543 (
544 p_table_info in hr_dm_gen_main.t_table_info,
545 p_where_clause in out nocopy varchar2,
546 p_cursor_type in varchar2 default 'DOWNLOAD',
547 p_lpad_spaces in number default 2
548 ) is
549 l_derive_sql hr_dm_tables.derive_sql_download_full%type;
550 l_start_ptr number;
551 l_end_ptr number;
552 l_where_string varchar2(25) := 'where ';
553 l_terminator varchar2(5) := ';';
554 begin
555 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.get_derive_where_clause', 5);
556 hr_dm_utility.message('PARA','(p_cursor_type- ' || p_cursor_type ,10);
557
558 if p_cursor_type = 'DOWNLOAD' then
559 l_derive_sql := p_table_info.derive_sql_download_full;
560 elsif p_cursor_type = 'DOWNLOAD_DT' then
561 l_derive_sql := p_table_info.derive_sql_download_add;
562 elsif p_cursor_type = 'CALCULATE_RANGES' then
563 l_derive_sql := p_table_info.derive_sql_calc_ranges;
564 elsif p_cursor_type = 'DELETE_SOURCE' then
565 l_derive_sql := p_table_info.derive_sql_delete_source;
566 end if;
567
568 -- if terminator ';' is there in derive sql then set the terminator to null.
569 if instr(l_derive_sql,';') > 0 then
570 l_terminator := null;
571 end if;
572
573 -- if 'where' string is not there then add the where string.
574 if instr(lower(l_derive_sql),'where') <= 0 then
575 p_where_clause := ' where ';
576 end if;
577
578 l_end_ptr := instr(l_derive_sql,':') - 1;
579 -- read the where clause string until first ':' . add the new line and chop
580 -- the where clause string upto ':' character. Continue this process until
581 -- full where clause is formatted.
582 loop
583
584 p_where_clause := p_where_clause || substr(l_derive_sql,1,
585 l_end_ptr) || indent(p_lpad_spaces);
586 -- remove the characters from where clause which have been appended in
587 -- the where clause.
588 l_derive_sql := substr(l_derive_sql,l_end_ptr + 2);
589 --
590 l_end_ptr := instr(l_derive_sql,':') - 1;
591 if l_end_ptr <= 0 or l_end_ptr is null then
592 p_where_clause := p_where_clause || l_derive_sql;
593 exit;
594 end if;
595 end loop;
596
597 p_where_clause := p_where_clause || l_terminator;
598 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_derive_where_clause',
599 25);
600 hr_dm_utility.message('PARA','(p_where_clause - ' || p_where_clause,30);
601 exception
602 when others then
603 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_derive_where_clause',
604 '(none)','R');
605 raise;
606 end get_derive_where_clause;
607 -- ----------------------- format_selective_where_clause -------------------------
608 -- Description:
609 -- Selective criteria is entered by the user and stored in hr_dm_migrations table.
610 -- The selective string is stored in the following_format
611 -- A:B:C:D:E
612 -- The obejective is to to convert the above string as follows
613 -- 'A','B','C','D','E'
614 -- The above string will be used in the where clause to restrict the data.
615 -- ------------------------------------------------------------------------------
616 procedure format_selective_where_clause
617 (
618 p_text in out nocopy varchar2,
619 p_lpad_spaces in number default 25
620 ) is
621 l_in_str varchar2(32767);
622 l_out_str varchar2(32767);
623 l_start_ptr number;
624 l_end_ptr number;
625 begin
626 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.format_selective_where_clause', 5);
627 hr_dm_utility.message('PARA','(p_text - ' || p_text ,10);
628
629 l_in_str := p_text;
630 l_end_ptr := instr(l_in_str,':') - 1;
631
632 -- read the where clause string until first ':' . add the new line and chop
633 -- the where clause string upto ':' character. Continue this process until
634 -- full where clause is formatted.
635 loop
636
637 if l_end_ptr > 0 then
638 l_out_str := l_out_str ||',''' || substr(l_in_str,1,l_end_ptr) ||
639 '''' || indent(p_lpad_spaces);
640 -- remove the characters from where clause which have been appended in
641 -- the where clause.
642 l_in_str := substr(l_in_str,l_end_ptr + 2);
643 --
644 l_end_ptr := instr(l_in_str,':') - 1;
645 end if;
646
647 if l_end_ptr <= 0 or l_end_ptr is null then
648 l_out_str := l_out_str || ',''' || l_in_str || '''' || indent(p_lpad_spaces);
649 exit;
650 end if;
651 end loop;
652
653 -- the l_where_clause string contains ',' as the first character, hence
654 -- the need of using substr function.
655
656 p_text := '(' || ' ' || substr(l_out_str,2) || ')';
657 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.format_selective_where_clause',
658 25);
659 hr_dm_utility.message('PARA','(p_text - ' || p_text,30);
660 exception
661 when others then
662 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.format_selective_where_clause',
663 '(none)','R');
664 raise;
665 end format_selective_where_clause;
666 -- ----------------------- get_gen_cursor_where_clause -------------------------
667 -- Description:
668 -- prepares the where clause for the following data to be downloaded:
669 -- o non date track table data
670 -- o full migration of date track table data
671 -- if the business group_id field does not exist in the table to be downloaded
672 -- then complex joins are to be made with the parent tables. Information about
673 -- the join is stored in hr_dm_hierarchy table for a given table.
674 -- The where clause consist of three things
675 -- a) range of surrogate id b) last_update_date and c) business_group_id
676 -- Depending upon the cursor type the where clause will be formed with the above
677 -- components.
678 -- p_cursor_type :- 'DOWNLOAD' - where clause for download procedure
679 -- components : (a,b,c)
680 -- 'CALCULATE_RANGES' - where clause for calculated ranges
681 -- components : (b,c)
682 -- 'DELETE_SOURCE' - where clause for delete source
683 -- components : (a,c)
684 -- ------------------------------------------------------------------------------
685 procedure get_gen_cursor_where_clause
686 (
687 p_table_info in hr_dm_gen_main.t_table_info,
688 p_where_clause in out nocopy varchar2,
689 p_cursor_type in varchar2 default 'DOWNLOAD',
690 p_lpad_spaces in number default 2
691 ) is
692
693 l_parent_table_info hr_dm_gen_main.t_table_info;
694 l_selective_criteria varchar2(8000);
695
696 -- get the selective formula criteria
697 cursor get_sel_formula is
698 select selective_migration_criteria
699 from hr_dm_migrations
700 where migration_id = p_table_info.migration_id
701 and migration_type = 'SF'
702 and selective_migration_criteria is not null;
703
704 begin
705
706 /*
707 Following where clause stmt will be created by the assignment below e.g
708 where adr.address_id between p_start_id and p_end_id
709 and adr.last_update_date >= decode(p_migration_type, 'full',
710 adr.last_update_date,
711 p_last_update_date)
712 adr - table alias name, address_id - surrogate primary key.
713 Note: it does not have business group_id.
714
715 If cursor is for calculate range then the where clause will not contain
716 the first line of the where clause mentioned above.
717 */
718
719 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.get_gen_cursor_where_clause ', 5);
720 hr_dm_utility.message('PARA','(p_cursor_type - ' || p_cursor_type ||
721 ')', 10);
722
723 -- check if the where clause is defined for this table i.e
724 -- derive_sql_download_full field is not null.If yes then
725 -- call get_derive_where_clause procedure to format the where
726 -- clause defined in the table.
727
728 if p_table_info.derive_sql_download_full is not null then
729 get_derive_where_clause ( p_table_info => p_table_info,
730 p_where_clause => p_where_clause,
731 p_cursor_type => p_cursor_type,
732 p_lpad_spaces => p_lpad_spaces);
733 return;
734 end if;
735
736 --
737 -- if it is a table hierarchy then call the implicit business group where
738 -- clause package to prepare the where clause, otherwise, create the where
739 -- clause.
740 if p_table_info.table_hierarchy = 'Y' and p_table_info.global_data = 'N' then
741 hr_dm_imp_bg_where.main (p_table_info => p_table_info,
742 p_cursor_type => p_cursor_type,
743 p_query_type => 'MAIN_QUERY',
744 p_where_clause => p_where_clause);
745 else
746 -- preparing where clause for explicit business group id.
747
748 p_where_clause := lpad(' ',p_lpad_spaces) || 'where ';
749
750 -- component range_id and last update date of the where clause
751
752 if p_cursor_type = 'DOWNLOAD' THEN
753 --
754 -- put the search condition of id between start and end id if the
755 -- table has a surrogate id.
756 --
757 if p_table_info.surrogate_primary_key = 'Y'
758 then
759 p_where_clause := p_where_clause || p_table_info.alias || '.' ||
760 p_table_info.surrogate_pk_column_name || ' between p_start_id and ' ||
761 'p_end_id';
762
763 -- p_where_clause := p_where_clause || indent(p_lpad_spaces) || 'and ';
764 end if;
765
766 -- Add the last_update_date comparison in the where clause for non date
767 -- track table only.
768 -- if the table has a child table with 'L' type hierarchy then the
769 -- last_update_date clause is ommitted.
770
771 if (p_table_info.missing_who_info = 'N') and
772 (p_table_info.datetrack = 'N') and
773 (hr_dm_gen_main.chk_ins_resolve_pk(p_table_info.table_id) = 'N') then
774
775 -- add 'and' if the surrogate id criteria has been applied.
776
777 if p_table_info.surrogate_primary_key = 'Y' then
778 p_where_clause := p_where_clause || indent(p_lpad_spaces) || 'and ';
779 end if;
780
781 p_where_clause := p_where_clause || p_table_info.alias
782 || '.' || 'last_update_date >= nvl(p_last_migration_date,' ||
783 indent(38) || p_table_info.alias || '.last_update_date)';
784
785 end if;
786 elsif p_cursor_type = 'DELETE_SOURCE' THEN
787 --
788 -- put the search condition of id between start and end id if the
789 -- table has a surrogate id.
790 --
791 if p_table_info.surrogate_primary_key = 'Y'
792 then
793 p_where_clause := p_where_clause || p_table_info.alias || '.' ||
794 p_table_info.surrogate_pk_column_name || ' between p_start_id and ' ||
795 'p_end_id' ;
796
797 end if;
798
799 elsif p_cursor_type = 'CALCULATE_RANGES' THEN
800
801 -- Add the last_update_date comparison in the where clause, if table has
802 -- WHO columns.
803 if p_table_info.missing_who_info = 'N' and
804 (hr_dm_gen_main.chk_ins_resolve_pk(p_table_info.table_id) = 'N') then
805
806 p_where_clause := p_where_clause || p_table_info.alias || '.' ||
807 'last_update_date >= nvl(p_last_migration_date,' ||
808 indent(38) || p_table_info.alias || '.last_update_date)';
809 end if;
810 else
811 null;
812 end if;
813
814 -- component business_group_id of the where clause
815
816 -- put the business group search condition into where clause.
817 -- if business group exists in the table then it is simple and if not
818 -- then it hass to be derived from the parent table hierarchy information
819 -- stored in hierarchy table.
820
821 if p_table_info.table_hierarchy = 'N' then
822
823 -- for explicit business group id, the business group id will not be
824 -- in the sub query of date track cursor.
825
826 if p_table_info.global_data = 'N' then
827 -- check whether there is any selection criteria already added to this
828 -- where clause. If yes then only add the ' and '
829
830 if ltrim(rtrim(p_where_clause)) <> 'where' then
831 p_where_clause := p_where_clause || indent(p_lpad_spaces) || 'and ';
832 end if;
833
834 p_where_clause := p_where_clause || p_table_info.alias || '.' ||
835 'business_group_id = p_business_group_id' ;
836 else
837 -- if no criteria has been added to the where clause then remove the
838 -- where clause.
839 if ltrim(rtrim(p_where_clause)) = 'where' then
840 p_where_clause := null;
841 end if;
842 end if;
843 -- end if; -- not required.
844 end if;
845 end if;
846
847 -- add the selective migration clause for FF_FORMULAS table
848 if lower(p_table_info.table_name) = 'ff_formulas_f' then
849 open get_sel_formula;
850 fetch get_sel_formula into l_selective_criteria;
851 if get_sel_formula%found then
852 format_selective_where_clause (p_text => l_selective_criteria);
853 p_where_clause := p_where_clause || indent || ' and ' || p_table_info.alias
854 || '.formula_name in ' || l_selective_criteria;
855 end if;
856 close get_sel_formula;
857 end if;
858
859 -- add the order by clause for datetrack table
860 if p_table_info.datetrack = 'Y'
861 and p_cursor_type <> 'DELETE_SOURCE' then
862 p_where_clause := p_where_clause || indent(p_lpad_spaces) ||
863 'order by ' || p_table_info.alias || '.' ||
864 p_table_info.surrogate_pk_column_name ;
865 end if;
866
867 p_where_clause := p_where_clause || ';' ;
868
869 -- if the where clause is empty then remove it
870 if p_where_clause =' where ;' then
871 p_where_clause := ' ;';
872 end if;
873
874
875
876 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_gen_cursor_where_clause',
877 25);
878 hr_dm_utility.message('PARA','(p_where_clause - ' || p_where_clause || ')' ,30);
879 exception
880 when others then
881 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_gen_cursor_where_clause',
882 '(none)','R');
883 raise;
884 end get_gen_cursor_where_clause;
885
886 -- ----------------------- get_dt_subqry_where_clause -------------------------
887 -- Description:
888 -- prepares the where clause for the sub query of the date track table data to
889 -- be downloaded.
890 -- if the business group_id field does not exist in the table to be downloaded
891 -- then complex joins are to be made with the parent tables. Information about
892 -- the join is stored in hr_dm_hierarchy table for a given table.
893 -- The where clause consist of three things
894 -- a) range of surrogate id b) last_update_date and c) business_group_id
895 -- Depending upon the cursor type the where clause will be formed with the above
896 -- components.
897 -- p_cursor_type :- 'DOWNLOAD' - where clause for download procedure
898 -- components : (a,b,c)
899 -- 'CALCULATE_RANGES' - where clause for calculated ranges
900 -- components : (b,c)
901 -- 'DELETE_SOURCE' - where clause for delete source
902 -- components : (c)
903 -- ------------------------------------------------------------------------
904 procedure get_dt_subqry_where_clause
905 (
906 p_table_info in hr_dm_gen_main.t_table_info,
907 p_where_clause in out nocopy varchar2,
908 p_cursor_type in varchar2 default 'DOWNLOAD',
909 p_lpad_spaces in number default 2
910 ) is
911
912 l_parent_table_info hr_dm_gen_main.t_table_info;
913 begin
914
915 /*
916 Following where clause stmt will be created by the assignment below e.g
917 where adr.last_update_date >= nvl(p_migration_type,
918 adr.last_update_date)
919 adr - table alias name, address_id - surrogate primary key.
920 Note: it does not have business group_id.
921
922 If cursor is for calculate range then the where clause will not contain
923 the first line of the where clause mentioned above.
924 */
925
926 -- last update date comparison for additive migration of the where clause
927
928 if (p_table_info.missing_who_info = 'N') then
929 p_where_clause := p_where_clause || indent(17) || 'and ' ||
930 p_table_info.alias || '.' ||
931 'last_update_date >= nvl(p_last_migration_date,' ||
932 indent(50) || p_table_info.alias || '.last_update_date)';
933 end if;
934
935 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_dt_subqry_where_clause',
936 25);
937 hr_dm_utility.message('PARA','(p_where_clause - ' || p_where_clause
938 || ')' ,30);
939 exception
940 when others then
941 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_dt_subqry_where_clause',
942 '(none)','R');
943 raise;
944 end get_dt_subqry_where_clause;
945
946
947 -- ----------------------- get_dt_cursor_where_clause -------------------------
948 -- Description:
949 -- prepares the where clause for the date track table data to to be downloaded.
950 -- if the business group_id field does not exist in the table to be downloaded
951 -- then complex joins are to be made with the parent tables. Information about
952 -- the join is stored in hr_dm_hierarchy table for a given table.
953 -- The where clause consist of three things
954 -- a) range of surrogate id b) last_update_date and c) business_group_id
955 -- Depending upon the cursor type the where clause will be formed with the above
956 -- components.
957 -- p_cursor_type :- 'DOWNLOAD' - where clause for download procedure
958 -- components : (a,b,c)
959 -- ------------------------------------------------------------------------
960 procedure get_dt_cursor_where_clause
961 (
962 p_table_info in hr_dm_gen_main.t_table_info,
963 p_where_clause out nocopy varchar2,
964 p_cursor_type in varchar2 default 'DOWNLOAD',
965 p_lpad_spaces in number default 2
966 ) is
967
968 l_sub_from_clause varchar2(32767);
969 l_sub_where_clause varchar2(32767);
970 l_selective_criteria varchar2(32767);
971
972 -- get the selective formula criteria
973 cursor get_sel_formula is
974 select selective_migration_criteria
975 from hr_dm_migrations
976 where migration_id = p_table_info.migration_id
977 and migration_type = 'SF'
978 and selective_migration_criteria is not null;
979
980
981 begin
982
983 /*
984 Following where clause stmt will be created by the assignment below e.g
985 where ff1.formula_id between p_start_id and p_end_id
986 and ff1.business_group_id = p_business_group_id -- only if table has
987 -- explicit business_group_id
988 and exists ( select 1
989 from avt_ff_formulas ff
990 where ff.formula_id = ff1.formula_id
991 and ff.last_update_date >= NVL(p_last_migration_date,
992 ff1.last_update_date)
993 );
994 Note: it does not have business group_id.
995
996 If cursor is for calculate range then the where clause will not contain
997 the first line of the where clause mentioned above.
998 */
999
1000 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.get_dt_cursor_where_clause ', 5);
1001 hr_dm_utility.message('PARA','(p_cursor_type - ' || p_cursor_type ||
1002 ')', 10);
1003
1004 -- check if the where clause is defined for this table i.e
1005 -- derive_sql_download_full field is not null.If yes then
1006 -- call get_derive_where_clause procedure to format the where
1007 -- clause defined in the table.
1008
1009 if p_table_info.derive_sql_download_full is not null then
1010 get_derive_where_clause ( p_table_info => p_table_info,
1011 p_where_clause => p_where_clause,
1012 p_cursor_type => 'DOWNLOAD_DT',
1013 p_lpad_spaces => p_lpad_spaces);
1014 return;
1015 end if;
1016 --
1017 -- if it is a table hierarchy then call the implicit business group where
1018 -- clause package to prepare the where clause, otherwise, create the where
1019 -- clause.
1020 if p_table_info.table_hierarchy = 'Y' then
1021 hr_dm_imp_bg_where.main (p_table_info => p_table_info,
1022 p_cursor_type => p_cursor_type,
1023 p_query_type => 'SUB_QUERY',
1024 p_where_clause => p_where_clause);
1025 else
1026
1027 p_where_clause := lpad(' ',p_lpad_spaces) || 'where ';
1028
1029 -- put the search condition of id between start and end id.
1030
1031 if p_table_info.surrogate_primary_key = 'Y'
1032 then
1033 p_where_clause := p_where_clause || p_table_info.alias || '1.' ||
1034 p_table_info.surrogate_pk_column_name || ' between p_start_id and ' ||
1035 'p_end_id';
1036
1037 p_where_clause := p_where_clause || indent(p_lpad_spaces) || 'and ';
1038 end if;
1039
1040 -- if business group id field exists in the table then put the business
1041 -- group condition in the main query
1042
1043 if p_table_info.table_hierarchy = 'N' and
1044 p_table_info.global_data = 'N'
1045 then
1046 -- derive business group id search condition from parent tables.
1047 p_where_clause := p_where_clause || p_table_info.alias || '1.' ||
1048 'business_group_id = p_business_group_id';
1049
1050 p_where_clause := p_where_clause || indent(p_lpad_spaces) || 'and ';
1051 end if;
1052
1053
1054 -- add the selective migration clause for FF_FORMULAS table
1055 if lower(p_table_info.table_name) = 'ff_formulas_f' then
1056 open get_sel_formula;
1057 fetch get_sel_formula into l_selective_criteria;
1058 if get_sel_formula%found then
1059 format_selective_where_clause (p_text => l_selective_criteria);
1060 p_where_clause := p_where_clause || p_table_info.alias
1061 || '1.formula_name in ' || l_selective_criteria ||
1062 indent(p_lpad_spaces) || 'and ';
1063 end if;
1064 close get_sel_formula;
1065 end if;
1066
1067
1068 -- prepare the sub query.
1069 p_where_clause := p_where_clause || ' exists ( select 1';
1070
1071 -- get the from clause for sub query
1072 get_cursor_from_clause (p_table_info => p_table_info,
1073 p_from_clause => l_sub_from_clause,
1074 p_lpad_spaces => 17);
1075
1076 -- get the where clause for sub query
1077 l_sub_where_clause := lpad(' ',17) || 'where ';
1078
1079 l_sub_where_clause := l_sub_where_clause || p_table_info.alias || '1.'||
1080 p_table_info.surrogate_pk_column_name || ' = '|| p_table_info.alias
1081 || '.'|| p_table_info.surrogate_pk_column_name;
1082
1083
1084 -- get the where clause of sub query.
1085 get_dt_subqry_where_clause (p_table_info => p_table_info,
1086 p_where_clause => l_sub_where_clause,
1087 p_cursor_type => p_cursor_type,
1088 p_lpad_spaces => 17);
1089 /*
1090 p_where_clause := p_where_clause || indent ||
1091 l_sub_from_clause || indent ||
1092 l_sub_where_clause || indent(16) || ')' ||
1093 indent(2) || 'order by ' ||
1094 p_table_info.surrogate_pk_column_name || ';';
1095 p_cursor_type
1096 */
1097 p_where_clause := p_where_clause || indent ||
1098 l_sub_from_clause || indent ||
1099 l_sub_where_clause || indent(16) || ')';
1100
1101 if p_cursor_type <> 'DELETE_SOURCE' then
1102 p_where_clause := p_where_clause || indent(2) || 'order by ' ||
1103 p_table_info.surrogate_pk_column_name || ';';
1104 else
1105 p_where_clause := p_where_clause || ';';
1106 end if;
1107
1108
1109 end if;
1110 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.get_dt_cursor_where_clause',
1111 25);
1112 hr_dm_utility.message('PARA','(p_where_clause - ' || p_where_clause ||
1113 ')' ,30);
1114 exception
1115 when others then
1116 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.get_dt_cursor_where_clause',
1117 '(none)','R');
1118 raise;
1119 end get_dt_cursor_where_clause;
1120
1121
1122 -- ----------------------- prepare_download_cursor --------------------------------
1123 -- Description:
1124 -- Preapre the cursor for download data.
1125 -- The download cursor fall into two categories.
1126 -- o Non date track table download (Full and Additive migration) and
1127 -- Date Track Full migration. Cursor where clause is same for both types.
1128 -- o Date Track table Additive migration. In this type the objective is to
1129 -- fetch all the physical records of the logical record if one or more
1130 -- physical records matches the criteria. So subquery is used to achieve
1131 -- this objective.
1132 -- Input Parameters :
1133 -- p_cursor_type - It can have following values :
1134 -- FULL_BG_MIGRATION - full business group migration for date track
1135 -- and non date track table.
1136 -- ADDITIVE_BG_MIGRATION : Additive business group id for date track
1137 -- table only as for non date track the cursor for full or additive
1138 -- migration is same.
1139 -- ------------------------------------------------------------------------
1140 procedure prepare_download_cursor
1141 (
1142 p_table_info in hr_dm_gen_main.t_table_info,
1143 p_cursor out nocopy varchar2,
1144 p_cursor_type in varchar2 default 'FULL_BG_MIGRATION',
1145 p_hier_column in varchar2 default 'N'
1146 )
1147 is
1148 l_cursor_comment varchar2(2000);
1149 l_cursor_defination varchar2(2000);
1150 l_cursor_select_cols varchar2(32767);
1151 l_cursor_select_from varchar2(32767);
1152 l_cursor_select_where varchar2(32767);
1153 l_columns_tbl hr_dm_library.t_varchar2_tbl;
1154 l_prefix_col varchar2(30);
1155
1156 begin
1157
1158 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.prepare_download_cursor ', 5);
1159 hr_dm_utility.message('PARA','(p_cursor_type - ' || p_cursor_type ||
1160 ')(p_hier_column - ' || p_hier_column, 10);
1161 if p_hier_column = 'Y' then
1162 l_columns_tbl := g_hier_columns_tbl;
1163 else
1164 l_columns_tbl := g_columns_tbl;
1165 end if;
1166
1167 -- comments about the cursor
1168 l_cursor_comment := indent || '--' || indent ||
1169 '-- cursor to select the data from the ' ||
1170 p_table_info.table_name || ' table to be migrated.' ||
1171 indent || '--';
1172
1173 -- comment and definition of cursor
1174 if p_cursor_type = 'FULL_BG_MIGRATION' then
1175 if p_table_info.datetrack = 'Y' then
1176 l_cursor_comment := format_comment(' cursor to select the data from the '
1177 || p_table_info.table_name || ' for FULL business group migration.',2 );
1178 l_cursor_defination := ' cursor csr_full_mig_' || p_table_info.alias ||
1179 ' is ';
1180 else
1181 l_cursor_comment := format_comment(' cursor to select the data from the '
1182 || p_table_info.table_name || ' table to be migrated.',2);
1183 l_cursor_defination := ' cursor csr_mig_' || p_table_info.alias || ' is ';
1184 end if;
1185 else
1186 l_cursor_comment := format_comment(' cursor to select the data from the '
1187 || p_table_info.table_name || ' for ADDITIVE business group migration.',2 );
1188 l_cursor_defination := ' cursor csr_adt_mig_' || p_table_info.alias ||
1189 ' is ';
1190 end if;
1191 --
1192 -- for normal main query the column name will be alias.col1,alias.col2 but
1193 -- for sub query it will be alias1.col1,alias1.col2
1194 --
1195 if p_cursor_type = 'FULL_BG_MIGRATION' then
1196 l_prefix_col := p_table_info.alias || '.';
1197 else
1198 l_prefix_col := p_table_info.alias || '1.';
1199 end if;
1200
1201 -- select columns in the cursor. This will return the list of all columns
1202 -- of the table separated by comma's.
1203
1204
1205
1206 l_cursor_select_cols := hr_dm_library.conv_list_to_text( p_rpad_spaces => 8,
1207 p_columns_tbl => l_columns_tbl,
1208 p_prefix_col => l_prefix_col);
1209
1210 -- Key combination tables have foreign key on AOL table
1211 -- 'FND_ID_FLEX_STRUCTURES' i.e hierarchy_type = 'A'. To identify
1212 -- the business group for a row in these tables it is required to
1213 -- check whether the ID value of the row is used by any of the
1214 -- child tables. The 'Where' clause generated by this generator
1215 -- does not use the 'exists' clause which results in the same row
1216 -- being fetch equals to the number of child rows it matches. To
1217 -- avoid this ' distinct' clause is added for only these tables.
1218 -- If the 'distinct' clause causes the performance problem then
1219 -- remove it and seed the derive_sql columns in HR_DM_TABLES for
1220 -- these tables.
1221
1222 hr_dm_utility.message('INFO','Distinct form for ' || p_table_info.table_name, 25);
1223 hr_dm_utility.message('INFO','p_table_info.use_distinct - ' || p_table_info.use_distinct, 25);
1224 hr_dm_utility.message('INFO','p_table_info.use_distinct_download - ' || p_table_info.use_distinct_download, 25);
1225
1226 if (p_table_info.use_distinct = 'Y')
1227 or
1228 (p_table_info.use_distinct_download = 'Y') then
1229 l_cursor_select_cols := ' select distinct ' || l_cursor_select_cols;
1230 hr_dm_utility.message('INFO','Using distinct form', 25);
1231 else
1232 l_cursor_select_cols := ' select ' || l_cursor_select_cols;
1233 hr_dm_utility.message('INFO','Not using distinct form', 25);
1234 end if;
1235
1236
1237 if p_cursor_type = 'FULL_BG_MIGRATION' then
1238 -- get from clause
1239 get_cursor_from_clause (p_table_info => p_table_info,
1240 p_from_clause => l_cursor_select_from);
1241
1242 -- get where clause
1243 get_gen_cursor_where_clause (p_table_info => p_table_info,
1244 p_where_clause => l_cursor_select_where);
1245
1246
1247 else -- date track table additive migration cursor.
1248 -- get from clause
1249 l_cursor_select_from := ' from ' || p_table_info.table_name || ' ' ||
1250 p_table_info.alias || '1';
1251
1252 -- get where clause for date track
1253 get_dt_cursor_where_clause (p_table_info => p_table_info,
1254 p_where_clause => l_cursor_select_where);
1255
1256
1257 end if;
1258
1259 -- finally put the components of where clause together
1260 p_cursor := l_cursor_comment || indent ||
1261 l_cursor_defination || indent ||
1262 l_cursor_select_cols || indent ||
1263 l_cursor_select_from || indent ||
1264 l_cursor_select_where || indent;
1265
1266 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.prepare_download_cursor',
1267 25);
1268 hr_dm_utility.message('PARA','(p_cursor - ' || p_cursor || ')' ,30);
1269 exception
1270 when others then
1271 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.prepare_download_cursor',
1272 '(none)','R');
1273 raise;
1274 end prepare_download_cursor;
1275 -- ----------------------- prepare_dt_private_procedures ------------------
1276 -- Description:
1277 -- Define private procedures to open and fetch cursors depending
1278 -- upon the migration type i.e full or additive for datetrack tables.
1279 -- ------------------------------------------------------------------------
1280
1281 procedure prepare_dt_private_procedures
1282 (
1283 p_table_info in hr_dm_gen_main.t_table_info,
1284 p_body out nocopy varchar2
1285 ) is
1286 l_proc_body varchar2(32767) := null;
1287 l_indent number;
1288 l_full_mig_csr_name varchar2(30) := 'csr_full_mig_' || p_table_info.alias;
1289 l_adt_mig_csr_name varchar2(30) := 'csr_adt_mig_' || p_table_info.alias;
1290
1291 begin
1292 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.prepare_dt_private_procedures ', 5);
1293
1294 l_indent := 2;
1295
1296 -- write the code for privte procedure open_cursor.
1297 l_proc_body := format_comment('Private procedure to open the cursor depending '
1298 || 'upon the migration type i.e full or additive', l_indent);
1299
1300 --
1301 -- define the private procedure open_cursor
1302 --
1303 l_proc_body := l_proc_body || indent(l_indent) ||
1304 'procedure private_open_cursor is' || indent(l_indent) || 'begin';
1305
1306 --
1307 -- define the body of private procedure open_cursor.
1308 --
1309
1310 l_indent := 4;
1311 l_proc_body := l_proc_body || indent(l_indent) ||
1312 'if p_last_migration_date is null then ' ||
1313 format_comment('Open cursor for a Full Migration of a business group',
1314 l_indent + 2,'N') || indent(l_indent + 2) ||
1315 'open csr_full_mig_' || p_table_info.alias || ';' || indent(l_indent) ||
1316 'else -- additive migration' || indent(l_indent + 2) ||
1317 format_comment('Open cursor for a Additive Migration of a business group'
1318 , l_indent + 2, 'N') || indent(l_indent + 2) ||
1319 'open csr_adt_mig_' || p_table_info.alias || ';' || indent(l_indent) ||
1320 'end if;';
1321
1322 l_indent := 2;
1323 l_proc_body := l_proc_body || indent(l_indent) ||'end private_open_cursor;';
1324
1325 --
1326 -- define the private procedure fetch_cursor
1327 --
1328
1329 l_proc_body := l_proc_body || indent(l_indent) ||
1330 format_comment('Fetch another row from the cursor depending upon migration '
1331 || 'type.', l_indent);
1332
1333 l_proc_body := l_proc_body || indent(l_indent) ||
1334 'procedure private_fetch_cursor is' || indent(l_indent) || 'begin';
1335
1336 --
1337 -- define the body of private procedure fetch_cursor.
1338 --
1339
1340 l_indent := 4;
1341
1342 l_proc_body := l_proc_body || indent(l_indent) ||
1343 'if p_last_migration_date is null then ' ||
1344 format_comment('Fetch a row from the full migration cursor.', l_indent + 2) ||
1345 indent(l_indent + 2) ||
1346 'fetch '|| l_full_mig_csr_name || ' into l_table_rec;' || indent(l_indent +2) ||
1347 'if ' || l_full_mig_csr_name || '%found then' || indent(l_indent +4) ||
1348 'l_row_fetched := TRUE;' || indent(l_indent +2) ||
1349 'else -- no row fetched' || indent(l_indent +4) ||
1350 'l_row_fetched := FALSE;' || indent(l_indent +4) ||
1351 'close ' || l_full_mig_csr_name || ';' || indent(l_indent +2) || 'end if;' ||
1352 indent(l_indent) || 'else -- additive migration' || indent(l_indent + 2)
1353 || format_comment('Fetch a row from the additive migration cursor',
1354 l_indent + 2)|| indent(l_indent + 2) ||
1355 'fetch '|| l_adt_mig_csr_name || ' into l_table_rec;' || indent(l_indent +2) ||
1356 'if ' || l_adt_mig_csr_name || '%found then' || indent(l_indent +4) ||
1357 'l_row_fetched := TRUE;' || indent(l_indent +2) ||
1358 'else -- no row fetched' || indent(l_indent +4) ||
1359 'l_row_fetched := FALSE;' || indent(l_indent +4) ||
1360 'close ' || l_adt_mig_csr_name || ';' || indent(l_indent +2) || 'end if;' ||
1361 indent(l_indent) || 'end if;';
1362
1363 l_proc_body := l_proc_body|| indent(2) || 'end private_fetch_cursor;';
1364
1365 p_body := l_proc_body;
1366
1367 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.prepare_dt_private_procedures',
1368 25);
1369 exception
1370 when others then
1371 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.prepare_dt_private_procedures',
1372 '(none)','R');
1373 raise;
1374 end prepare_dt_private_procedures;
1375 -- ----------------------- nullify_hierarchical_cols -----------------------
1376 -- Description:
1377 -- Generates the text which assigns null values to the hierarchical columns.
1378 -- hier_col1 := null;
1379 -- hier_col2 := null;
1380 -- ------------------------------------------------------------------------
1381 procedure nullify_hierarchical_cols
1382 (
1383 p_table_info in hr_dm_gen_main.t_table_info,
1384 p_lpad_spaces in number,
1385 p_body out nocopy varchar2
1386 )
1387 is
1388 l_list_index number;
1389 l_count number;
1390
1391 begin
1392 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.nullify_hierarchical_cols ', 5);
1393
1394 -- initialise the variables
1395 l_list_index := g_hier_columns_tbl.first;
1396 l_count := 1;
1397
1398 p_body := rpad(' ', p_lpad_spaces) || indent ||
1399 format_comment('assign null values to hierarchical columns',p_lpad_spaces)
1400 || indent;
1401
1402 -- read the hierarchy columns one by one and set them to null except the
1403 -- surrogate id.
1404
1405 while l_list_index is not null loop
1406 --
1407 -- do not nullify the surrogate_id
1408 --
1409 if g_hier_columns_tbl(l_list_index) <> p_table_info.surrogate_pk_column_name
1410 then
1411 p_body := p_body || indent(p_lpad_spaces) || 'l_table_rec.' ||
1412 g_hier_columns_tbl(l_list_index) || ' := null;';
1413 end if;
1414
1415 l_list_index := g_hier_columns_tbl.next(l_list_index);
1416 l_count := l_count + 1;
1417 end loop;
1418 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.nullify_hierarchical_cols',
1419 25);
1420 exception
1421 when others then
1422 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.nullify_hierarchical_cols',
1423 '(none)','R');
1424 raise;
1425 end nullify_hierarchical_cols;
1426
1427 -- ----------------------- generate_get_link_value -----------------------
1428 -- Description:
1429 -- Generates the get link value from the sequence procedure of the TDS
1430 -- ------------------------------------------------------------------------
1431 procedure generate_get_link_value
1432 (
1433 p_table_info in hr_dm_gen_main.t_table_info
1434 )
1435 is
1436 l_interface varchar2(32767);
1437 l_locals varchar2(32767) := null;
1438 l_cursor varchar2(32767) := null;
1439 l_proc_comment varchar2(4000);
1440 l_cursor_name varchar2(30) := 'csr_get_link_value';
1441
1442 -- block body of the procedure i.e between begin and end.
1443 l_proc_body varchar2(32767) := null;
1444
1445 -- indentation for the statements.it specifies number of blank spaces
1446 -- after which the staement should start.
1447
1448 l_indent number;
1449 l_proc_body_tbl t_varchar2_32k_tbl;
1450 begin
1451 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_get_link_value ', 5);
1452 -- input parameters for the procedure
1453
1454 l_interface := indent || '(p_link_value out nocopy number)' || indent;
1455
1456 -- local variables of the procedure
1457
1458 l_locals := indent || ' --' || indent ||
1459 ' -- Declare cursors and local variables' || indent ||
1460 ' --' || indent ||
1461 ' l_proc varchar2(72) := g_package ' ||
1462 '|| ''get_link_value'';' || indent ||
1463 ' l_link_value number;' || indent;
1464
1465 -- cursor to get the link value from the sequence from the data pump table
1466 l_cursor := format_comment('Cursor to get the link value from the link '||
1467 'value sequence.');
1468
1469 l_cursor := l_cursor || indent || ' cursor csr_get_link_value is select '
1470 || 'hr_dm_link_value_s.nextval' || indent ||
1471 ' from dual;';
1472 -- add the logic of the body
1473
1474 l_indent := 2;
1475
1476 l_proc_body := l_proc_body || indent(l_indent) ||
1477 'open ' || l_cursor_name || ';' || indent(l_indent) || 'fetch ' ||
1478 l_cursor_name || ' into l_link_value;' || indent(l_indent) ||
1479 'close ' || l_cursor_name || ';' || indent(l_indent) ||
1480 ' p_link_value := l_link_value;';
1481
1482 l_proc_body := l_proc_body || indent || 'end get_link_value;';
1483
1484
1485 l_proc_comment := format_comment('procedure to get the link value from the '
1486 || 'link sequence. Physical records of a date track logical record will ' ||
1487 ' have same link value so as to enable the processing of logical record by '
1488 || 'single thread while uploading. Used by Data Pump.') || indent;
1489
1490
1491 -- add the procedure comment,local variables , cursor and procedure body to
1492 -- complete the procedure
1493
1494 l_proc_body_tbl(1) := l_proc_comment || 'procedure get_link_value' ||
1495 l_interface || ' is' || l_locals || l_cursor || indent ||
1496 'begin' || indent || l_proc_body;
1497
1498 -- add the body of this procedure to the package.
1499 add_to_package_body( l_proc_body_tbl );
1500 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_get_link_value',
1501 25);
1502
1503 exception
1504 when others then
1505 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_get_link_value',
1506 '(none)','R');
1507 raise;
1508 end generate_get_link_value;
1509
1510 -- ----------------------- generate_developer_key_func -----------------------
1511 -- Description:
1512 -- This function will
1513 -- - Generates the procedure which will get the developer key from the
1514 -- AOL table for the column which have a foreign key to AOL table.
1515 -- - Creates a call to the function to get the developer key
1516 -- for the column value which has a foreign key on AOL table.
1517 -- - Creates a local variable for the developer key.
1518 --
1519 -- This procedure will generate the function for each column which have a
1520 -- foreign key to AOL table.
1521 -- Assumption : Id value is assumed to be number and developer key is assumed
1522 -- to be varchar2.
1523 -- Input Parameters
1524 -- p_fk_to_aol_columns_tbl - Contains the information about all the columns
1525 -- which have foreign key to AOL table.
1526 -- p_table_info - Contains the info about the table to be
1527 -- downloaded
1528 -- Out Parameters
1529 -- p_body - returns the actual procedure body for getting
1530 -- the
1531 -- p_call_to_proc_body - returns the string for a call to the function
1532 -- p_dev_key_local_var_body - returns the string defining local var for
1533 -- developer key
1534 -- ------------------------------------------------------------------------
1535 procedure generate_developer_key_func
1536 (
1537 p_fk_to_aol_columns_tbl in hr_dm_gen_main.t_fk_to_aol_columns_tbl,
1538 p_table_info in hr_dm_gen_main.t_table_info,
1539 p_call_to_proc_body in out nocopy varchar2,
1540 p_dev_key_local_var_body in out nocopy varchar2
1541 )
1542 is
1543 l_interface varchar2(32767);
1544 l_locals varchar2(32767) := null;
1545 l_cursor varchar2(32767) := null;
1546 l_where_clause varchar2(32767) := null;
1547 l_proc_comment varchar2(4000);
1548 l_cursor_name varchar2(30) := 'csr_get_developer_key';
1549 l_proc_name varchar2(32767);
1550
1551 -- variables to store the information about p_fk_to_aol_columns_tbl elements.
1552 -- this is to reduce the variable name and add clarity.
1553
1554 l_column_name hr_dm_hierarchies.column_name%type;
1555 l_parent_table_id hr_dm_hierarchies.parent_table_id%type;
1556 l_parent_table_name hr_dm_tables.table_name%type;
1557 l_parent_table_alias hr_dm_tables.table_alias%type;
1558 l_parent_column_name hr_dm_hierarchies.parent_column_name%type;
1559 l_parent_id_column_name hr_dm_hierarchies.parent_id_column_name%type;
1560
1561
1562 -- block body of the procedure i.e between begin and end.
1563 l_proc_body varchar2(32767) := null;
1564
1565 -- indentation for the statements.it specifies number of blank spaces
1566 -- after which the staement should start.
1567
1568 l_indent number;
1569 l_index number := p_fk_to_aol_columns_tbl.first;
1570 l_proc_body_tbl t_varchar2_32k_tbl;
1571 l_code varchar2(4);
1572 l_table varchar2(30);
1573 begin
1574 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_developer_key_func ', 5);
1575 hr_dm_utility.message('PARA','(p_fk_to_aol_columns_tbl - table of varchar2)', 10);
1576
1577 -- generate the function to get the developer key for each of the column
1578 -- which has a foreign key on AOL table.
1579
1580 while l_index is not null loop
1581
1582 l_column_name :=
1583 p_fk_to_aol_columns_tbl(l_index).column_name;
1584 l_parent_table_id :=
1585 p_fk_to_aol_columns_tbl(l_index).parent_table_id;
1586 l_parent_table_name :=
1587 p_fk_to_aol_columns_tbl(l_index).parent_table_name;
1588 l_parent_table_alias :=
1589 p_fk_to_aol_columns_tbl(l_index).parent_table_alias;
1590 l_parent_column_name :=
1591 p_fk_to_aol_columns_tbl(l_index).parent_column_name;
1592 l_parent_id_column_name :=
1593 p_fk_to_aol_columns_tbl(l_index).parent_id_column_name;
1594
1595 l_where_clause := l_parent_id_column_name || ' = ' ||
1596 rpad('p_' || l_column_name, 30);
1597
1598 l_proc_name := 'get_developer_key_frm_' || l_parent_table_alias;
1599
1600 -- input parameters for the procedure
1601 l_interface := indent || '(' ||rpad('p_' || l_column_name, 30) ||
1602 ' in number,' || indent || ' ' ||
1603 rpad('p_'|| l_parent_column_name ,30) || ' out nocopy varchar2)';
1604
1605 -- local variables of the procedure
1606
1607 l_locals := indent || ' --' || indent ||
1608 ' -- Declare cursors and local variables' || indent ||
1609 ' --' || indent ||
1610 ' l_proc varchar2(72) := g_package ' ||
1611 '|| ''' || l_proc_name || ''';' || indent;
1612
1613 -- cursor to get the link value from the sequence from the data pump table
1614 l_cursor := format_comment('Cursor to get the developer key from the '||
1615 l_parent_table_name || ' table.',2);
1616
1617 if lower(l_parent_column_name) <> 'id_flex_structure_name' then
1618 l_cursor := l_cursor || indent(2) || 'cursor csr_get_developer_key is ' ||
1619 'select ' || l_parent_column_name || indent(33) ||
1620 'from ' || l_parent_table_name ||
1621 indent(33) || 'where ' || rtrim(l_where_clause) || ';';
1622 else
1623 -- for id_flex_num, we need both id_flex_structure_name and
1624 -- id_flex_code, so download both, concaternated with
1625 -- -dm-dev-key- as a seperator
1626 l_table := upper(p_table_info.table_name);
1627 if (l_table = 'HR_SOFT_CODING_KEYFLEX')
1628 or
1629 (l_table = 'HR_DMVP_HR_SOFT_CODING_KEYFLEX') then
1630 l_code := 'SCL';
1631 elsif (l_table = 'PAY_COST_ALLOCATION_KEYFLEX') then
1632 l_code := 'COST';
1633 elsif (l_table = 'PAY_EXTERNAL_ACCOUNTS') then
1634 l_code := 'BANK';
1635 elsif (l_table = 'PAY_PEOPLE_GROUPS') then
1636 l_code := 'GRP';
1637 elsif (l_table = 'PER_GRADE_DEFINITIONS') then
1638 l_code := 'GRD';
1639 elsif (l_table = 'PER_POSITION_DEFINITIONS') then
1640 l_code := 'POS';
1641 elsif (l_table = 'PER_PERSON_ANALYSES')
1642 or
1643 (l_table = 'PER_SPECIAL_INFO_TYPES')
1644 or
1645 (l_table = 'PER_ANALYSIS_CRITERIA') then
1646 l_code := 'PEA';
1647 elsif (l_table = 'PER_JOB_GROUPS')
1648 or
1649 (l_table = 'HR_DMV_PER_JOB_GROUPS')
1650 or
1651 (l_table = 'PER_JOB_DEFINITIONS') then
1652 l_code := 'JOB';
1653 end if;
1654
1655 l_cursor := l_cursor || indent(2) || 'cursor csr_get_developer_key is ' ||
1656 'select id_flex_structure_name' ||
1657 indent(33) || ' || ''-dm-dev-key-' || l_code || '''' ||
1658 indent(33) || 'from fnd_id_flex_structures_vl' ||
1659 indent(33) || 'where ' || rtrim(l_where_clause) ||
1660 indent(33) || ' and id_flex_code = ''' || l_code || ''';';
1661 end if;
1662
1663
1664 -- add the logic of the body
1665
1666 l_indent := 2;
1667
1668 l_proc_body := indent(l_indent) ||
1669 'open ' || l_cursor_name || ';' || indent(l_indent) || 'fetch ' ||
1670 l_cursor_name || ' into ' || rpad('p_'|| l_parent_column_name ,30) || ';' ||
1671 indent(l_indent) ||
1672 'if ' || l_cursor_name || '%notfound then' || indent(l_indent + 2) ||
1673 'close ' || l_cursor_name || ';' || indent(l_indent + 2) ||
1674 'hr_dm_utility.message(''FAIL'',''When obtaining the developer key'' || ' ||
1675 indent(l_indent + 2) ||
1676 ' '' from table / view ' || l_parent_table_name || ' no data was found.'' ||' ||
1677 indent(l_indent + 2) ||
1678 ' '' check for a null or orphaned data.'',10);' ||
1679 indent(l_indent + 2) ||
1680 'hr_utility.raise_error;' || indent(l_indent) || 'else' ||indent(l_indent + 2)
1681 ||'close ' || l_cursor_name || ';' || indent(l_indent) || 'end if;';
1682
1683
1684 l_proc_body := l_proc_body || indent || 'end ' || l_proc_name || ';';
1685
1686
1687 l_proc_comment := format_comment('procedure to get the the developer key '
1688 || 'from the '|| l_parent_table_name || ' table for ' ||
1689 l_column_name || ' column.' ) || indent;
1690
1691
1692 -- add the procedure commentlocal variables , cursor and procedure body to
1693 -- complete the procedure
1694
1695 l_proc_body_tbl(1) := l_proc_comment || 'procedure ' || l_proc_name ||
1696 l_interface || ' is' || l_locals || l_cursor || indent ||
1697 'begin' || indent || l_proc_body;
1698
1699 -- add the body of this procedure to the package.
1700 add_to_package_body( l_proc_body_tbl );
1701
1702 -- construct a call to the procedure created above.
1703 l_indent := 6;
1704 p_call_to_proc_body := p_call_to_proc_body || indent ||
1705 format_comment('Get the developer key for ' || l_column_name || '.',
1706 l_indent);
1707 p_call_to_proc_body := p_call_to_proc_body || indent(l_indent) ||
1708 l_proc_name || '(l_table_rec.' || rpad(l_column_name,28) || ',' ||
1709 indent(l_indent + 25) || 'l_' || rpad(l_parent_column_name,28) || ');';
1710
1711 -- construct the defination of local variable
1712 l_indent := 2;
1713
1714 -- for id_flex_structure_name of fnd_id_flex_structures_vl
1715 -- use varchar2(2000) as column type
1716 -- to allow for encoding of name plus code
1717 if (l_parent_table_name = 'fnd_id_flex_structures_vl')
1718 and
1719 (l_parent_column_name = 'id_flex_structure_name') then
1720 p_dev_key_local_var_body := p_dev_key_local_var_body || indent(l_indent)
1721 || 'l_' || rpad(l_parent_column_name,28) || ' varchar2(2000);';
1722 else
1723 p_dev_key_local_var_body := p_dev_key_local_var_body || indent(l_indent)
1724 || 'l_' || rpad(l_parent_column_name,28) || ' ' || l_parent_table_name
1725 || '.' || l_parent_column_name ||'%type;';
1726 end if;
1727 l_index := p_fk_to_aol_columns_tbl.next(l_index);
1728 end loop;
1729 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_developer_key_func',
1730 25);
1731 exception
1732 when others then
1733 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_developer_key_func',
1734 '(none)','R');
1735 raise;
1736 end generate_developer_key_func;
1737
1738 -- ----------------------- generate_download --------------------------------
1739 -- Description:
1740 -- Generates the download procedure of the TDS
1741 -- ------------------------------------------------------------------------
1742 procedure generate_download
1743 (
1744 p_table_info in hr_dm_gen_main.t_table_info,
1745 p_header in out nocopy varchar2,
1746 p_hier_column in varchar2 default 'N',
1747 p_call_to_proc_body in varchar2,
1748 p_dev_key_local_var_body in varchar2,
1749 p_fk_to_aol_columns_tbl in hr_dm_gen_main.t_fk_to_aol_columns_tbl
1750 )
1751 is
1752 l_interface varchar2(32767);
1753 l_locals varchar2(32767) := null;
1754 l_cursor varchar2(32767) := null;
1755 l_adt_cursor varchar2(32767) := null;
1756 l_comment varchar2(4000);
1757 l_proc_comment varchar2(4000);
1758 l_cursor_name varchar2(30) := 'csr_mig_' || p_table_info.alias;
1759 l_func_name varchar2(30) := 'download';
1760 l_dp_func_name varchar2(100);
1761 l_null_col varchar2(30);
1762
1763
1764 -- block body of the procedure i.e between begin and end.
1765 l_proc_body varchar2(32767) := null;
1766 l_debug_message_text varchar2(32767) := null;
1767 l_func_body varchar2(32767) := null;
1768
1769 -- block body to store private procedures
1770 l_prv_proc_body varchar2(32767) := null;
1771
1772 -- indentation for the statements.it specifies number of blank spaces
1773 -- after which the staement should start.
1774
1775 l_indent number;
1776 l_columns_tbl hr_dm_library.t_varchar2_tbl;
1777
1778 l_proc_body_tbl t_varchar2_32k_tbl;
1779 l_proc_index number := 1;
1780
1781 cursor csr_null_hierarchy is
1782 select h.column_name
1783 from hr_dm_hierarchies h,
1784 hr_dm_tables t
1785 where h.hierarchy_type = 'N'
1786 and h.table_id = t.table_id
1787 and t.table_name = upper(p_table_info.table_name);
1788
1789 begin
1790 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_download', 5);
1791 hr_dm_utility.message('PARA','( p_hier_column - ' || p_hier_column ||
1792 ')', 10);
1793 if p_hier_column = 'Y' then
1794 l_columns_tbl := g_hier_columns_tbl;
1795 l_func_name := 'download_hierarchy';
1796 l_dp_func_name := 'hrdpp_h' || p_table_info.short_name || '.insert_batch_lines';
1797 else
1798 l_columns_tbl := g_columns_tbl;
1799 l_func_name := 'download';
1800 l_dp_func_name := 'hrdpp_u' || p_table_info.short_name || '.insert_batch_lines';
1801 end if;
1802
1803 -- input parameters for the procedure
1804
1805 l_interface := indent ||
1806 '(p_migration_type in varchar2,' || indent ||
1807 ' p_business_group_id in number,' || indent ||
1808 ' p_last_migration_date in date,' || indent ||
1809 ' p_start_id in number,' || indent ||
1810 ' p_end_id in number,' || indent ||
1811 ' p_batch_id in number,' || indent ||
1812 ' p_chunk_size in number,' || indent ||
1813 ' p_rec_downloaded out nocopy number)' || indent;
1814
1815
1816 l_proc_body_tbl(l_proc_index) := l_interface;
1817 l_proc_index := l_proc_index + 1;
1818
1819 -- message (' l_interface = ' || l_interface);
1820 -- local variables of the procedure
1821
1822 l_locals := indent ||
1823 ' -- Declare local variables' || indent ||
1824 ' l_proc varchar2(72) := g_package ' ||
1825 '|| ''' || l_func_name || ''' ;' || indent ||
1826 ' l_link_value number;' || indent ||
1827 ' l_rec_inserted_cnt number := 0;' || indent ||
1828 ' l_row_fetched boolean := FALSE;' || indent;
1829
1830 -- if table has a column which have foreign key to the AOL table then create
1831 -- local variable for each corresponding developer key.
1832
1833 if p_table_info.fk_to_aol_table = 'Y' then
1834 l_locals := l_locals || p_dev_key_local_var_body || indent;
1835 end if;
1836
1837
1838 --
1839 -- if p_hier_column flag is set to 'Y' then prepare the download cursor to
1840 -- get only hierarchy cols only. If it is 'N' then prepare the download
1841 -- cursor to get all the columns.
1842 --
1843
1844 if p_table_info.datetrack = 'N' then
1845 -- call prepare_down_load procedure to create the cursor.
1846 prepare_download_cursor ( p_table_info => p_table_info,
1847 p_cursor => l_cursor,
1848 p_cursor_type => 'FULL_BG_MIGRATION',
1849 p_hier_column => p_hier_column);
1850 l_locals := l_locals ||
1851 ' l_table_rec ' || 'csr_mig_' ||
1852 lower(p_table_info.alias) ||'%rowtype;' || indent;
1853 else -- date track table
1854 --
1855 -- for datetrack table two cursors are required.
1856 -- o For FULL data migration of the business group.
1857 -- o For ADDITIVE migration of the business group.
1858 --
1859
1860 -- call prepare_down_load procedure to create the cursor for FULL data
1861 -- migration
1862 prepare_download_cursor ( p_table_info => p_table_info,
1863 p_cursor => l_cursor,
1864 p_cursor_type => 'FULL_BG_MIGRATION',
1865 p_hier_column => p_hier_column);
1866
1867 -- call prepare_down_load procedure to create the cursor for ADDITIVE
1868 -- data migration
1869
1870 prepare_download_cursor ( p_table_info => p_table_info,
1871 p_cursor => l_adt_cursor,
1872 p_cursor_type => 'ADDITIVE_BG_MIGRATION',
1873 p_hier_column => p_hier_column);
1874
1875 -- declare private procedures to open and fetch cursors depending
1876 -- upon the migration type i.e full or additive.
1877 prepare_dt_private_procedures (p_table_info => p_table_info,
1878 p_body => l_prv_proc_body);
1879
1880
1881 l_locals := l_locals ||
1882 ' l_table_rec ' || 'csr_full_mig_' ||
1883 lower(p_table_info.alias) ||'%rowtype;' || indent || ' ' ||
1884 rpad('l_prv_' || p_table_info.surrogate_pk_column_name,30)
1885 ||' number := -999;' || indent;
1886 end if;
1887
1888 -- message (' l_cursor = ' || l_cursor);
1889 -- add the body of the download procedure
1890
1891 l_indent := 2;
1892 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
1893 'l_rec_inserted_cnt := 0;' || indent(l_indent) || 'begin';
1894 l_proc_index := l_proc_index + 1;
1895
1896 add_debug_messages (p_table_info => p_table_info,
1897 p_procedure_name => l_func_name,
1898 p_message_location => 'START',
1899 p_proc_body => l_debug_message_text);
1900 l_proc_body_tbl(l_proc_index) := l_debug_message_text;
1901 l_proc_index := l_proc_index + 1;
1902 l_indent := 4;
1903
1904 if p_table_info.datetrack = 'N' then
1905
1906 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
1907 'open ' || l_cursor_name || ';' || indent(l_indent) || 'loop';
1908 l_proc_index := l_proc_index + 1;
1909
1910 l_indent := 6;
1911 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
1912 'fetch ' || l_cursor_name ||' into l_table_rec;' ||indent(l_indent) ||
1913 'if ' || l_cursor_name || '%notfound then' || indent(l_indent + 2) ||
1914 'close ' || l_cursor_name || ';' || indent(l_indent + 2) ||
1915 'l_row_fetched := FALSE;' || indent(l_indent) || 'else' ||
1916 indent(l_indent + 2) || 'l_row_fetched := TRUE;' || indent(l_indent) ||
1917 'end if;';
1918 l_proc_index := l_proc_index + 1;
1919 else -- datetrack
1920 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
1921 'private_open_cursor;' || indent(l_indent) || 'loop' || indent(l_indent + 2)
1922 || 'private_fetch_cursor;' ;
1923 l_proc_index := l_proc_index + 1;
1924 end if;
1925
1926 l_indent := 6;
1927
1928 l_comment := format_comment('if no row fetched then exit the loop',l_indent);
1929
1930
1931 l_proc_body_tbl(l_proc_index) := l_comment || indent(l_indent) ||
1932 'if not l_row_fetched then' ||indent(l_indent + 2) || 'exit;' ||
1933 indent(l_indent) || 'end if;';
1934 l_proc_index := l_proc_index + 1;
1935
1936
1937 --
1938 -- if it is a datetrack then add the code to get the link value from the
1939 -- sequence.
1940 --
1941 if p_table_info.datetrack = 'Y' then
1942 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
1943 'if ' || rpad('l_prv_' || p_table_info.surrogate_pk_column_name,30) ||
1944 ' <> '|| 'l_table_rec.' || p_table_info.surrogate_pk_column_name ||
1945 ' then' || indent(l_indent + 2) || 'get_link_value(l_link_value);' ||
1946 indent(l_indent) || 'end if;';
1947 l_proc_index := l_proc_index + 1;
1948 end if;
1949
1950 -- if p_hier_column is 'N' i.e this procedure is generated for download of
1951 -- all columns. If this table has a column hierarchy then set the hierarchy
1952 -- columns to null.
1953
1954 if p_hier_column = 'N' and p_table_info.column_hierarchy = 'Y' then
1955 nullify_hierarchical_cols ( p_table_info => p_table_info,
1956 p_lpad_spaces => l_indent,
1957 p_body => l_proc_body );
1958 end if;
1959
1960
1961 -- if table has a column which have foreign key to the AOL table then call
1962 -- procedures to get the developer key.
1963
1964 if p_table_info.fk_to_aol_table = 'Y' then
1965 l_proc_body := l_proc_body || p_call_to_proc_body ;
1966 end if;
1967
1968 l_comment := 'insert the data into batch_lines table of datapump for ' ||
1969 'all columns of ' ||p_table_info.table_name ||
1970 ' and assign null values to hierarchy columns.';
1971
1972 l_proc_body := l_proc_body || format_comment(l_comment,l_indent);
1973
1974 l_proc_body_tbl(l_proc_index) := l_proc_body;
1975 l_proc_index := l_proc_index + 1;
1976
1977
1978 -- nullify columns where an N hierarchy exists
1979 -- only for download procedure
1980
1981 if p_hier_column = 'N' then
1982 open csr_null_hierarchy;
1983 loop
1984 fetch csr_null_hierarchy into l_null_col;
1985 exit when csr_null_hierarchy%notfound;
1986 l_comment := 'Nullify column ' || l_null_col || ' for N hierarchy.';
1987 l_proc_body_tbl(l_proc_index) := format_comment(l_comment,l_indent) ||
1988 indent(l_indent) ||
1989 'l_table_rec.' ||
1990 lower(l_null_col) ||
1991 ' := null;' || indent(l_indent) ;
1992 l_proc_index := l_proc_index + 1;
1993 end loop;
1994 close csr_null_hierarchy;
1995 end if;
1996
1997 -- form a call to data pump function to insert data into batch_lines
1998 -- table.
1999
2000 l_proc_body_tbl(l_proc_index) := indent(l_indent) || l_dp_func_name ||
2001 indent(l_indent) ||
2002 '( p_batch_id => p_batch_id'|| indent(l_indent) ||
2003 ' ,p_user_sequence => l_link_value' || indent(l_indent) ||
2004 ' ,p_link_value => l_link_value' || indent(l_indent) ||
2005 ' ,p_last_migration_date => p_last_migration_date' || indent(l_indent) ||
2006 ' ,p_migration_type => p_migration_type' || indent;
2007 l_proc_index := l_proc_index + 1;
2008
2009 -- if the columns of the table have foreign key to AOL table then call
2010 -- call assignment function which replaces those columns with developer key.
2011 if p_table_info.fk_to_aol_table = 'N' then
2012
2013 l_proc_body_tbl(l_proc_index) := hr_dm_library.get_func_asg (
2014 p_rpad_spaces => l_indent +1,
2015 p_columns_tbl => l_columns_tbl,
2016 p_prefix_left_asg => 'p_',
2017 p_prefix_right_asg => 'l_table_rec.',
2018 p_right_asg_pad_len => 55);
2019 else
2020 l_proc_body_tbl(l_proc_index) := hr_dm_library.get_func_asg_with_dev_key (
2021 p_rpad_spaces => l_indent +1,
2022 p_columns_tbl => l_columns_tbl,
2023 p_prefix_left_asg => 'p_',
2024 p_prefix_right_asg => 'l_table_rec.',
2025 p_right_asg_pad_len => 55,
2026 p_prefix_left_asg_dev_key => 'p_',
2027 p_prefix_right_asg_dev_key => 'l_',
2028 p_use_aol_id_col => 'N',
2029 p_fk_to_aol_columns_tbl => p_fk_to_aol_columns_tbl,
2030 p_resolve_pk_columns_tbl => g_resolve_pk_columns_tbl );
2031
2032 end if;
2033
2034 l_proc_body_tbl(l_proc_index) := l_proc_body_tbl(l_proc_index) || ');';
2035 l_proc_index := l_proc_index + 1;
2036
2037 --
2038 l_indent := 6;
2039 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
2040 'l_rec_inserted_cnt := l_rec_inserted_cnt + 1;' || indent(l_indent) ||
2041 format_comment('commit after every chunk_size_value (e.g. 10) records.',
2042 l_indent) || indent(l_indent) || 'if mod (l_rec_inserted_cnt, ' ||
2043 'p_chunk_size) = 0 then ' || indent(l_indent + 2) || 'commit;' ||
2044 indent(l_indent) || 'end if;';
2045
2046 l_proc_index := l_proc_index + 1;
2047 --
2048 -- if it is a datetrack then store the id value.
2049 --
2050 if p_table_info.datetrack = 'Y' then
2051 l_proc_body_tbl(l_proc_index) := indent(l_indent) ||
2052 rpad('l_prv_' || p_table_info.surrogate_pk_column_name,30) || ' := ' ||
2053 'l_table_rec.' || p_table_info.surrogate_pk_column_name || ';';
2054 l_proc_index := l_proc_index + 1;
2055 end if;
2056
2057 l_proc_body_tbl(l_proc_index) := indent(l_indent - 2) ||
2058 'end loop;' || indent(l_indent - 2) || 'commit;' || indent(l_indent - 2) ||
2059 'p_rec_downloaded := l_rec_inserted_cnt;' || indent(l_indent - 4) ||
2060 'end;';
2061 l_proc_index := l_proc_index + 1;
2062
2063 -- if p_hier_column is 'N' i.e this procedure is generated for download of
2064 -- all columns. If this table has a column hierarchy then include a call to
2065 -- call the download hieararchy procedure.
2066
2067
2068 if p_hier_column = 'N' and p_table_info.column_hierarchy = 'Y' then
2069 l_indent := 22;
2070 l_proc_body_tbl(l_proc_index) := indent ||
2071 ' download_hierarchy (p_migration_type,' || indent(l_indent) ||
2072 'p_business_group_id,' || indent(l_indent) ||
2073 'p_last_migration_date,' || indent(l_indent) ||
2074 'p_start_id,' || indent(l_indent) ||
2075 'p_end_id ,' || indent(l_indent) ||
2076 'p_batch_id ,' || indent(l_indent) ||
2077 'p_chunk_size,' || indent(l_indent) ||
2078 'l_rec_inserted_cnt);' || indent;
2079 l_proc_index := l_proc_index + 1;
2080 end if;
2081
2082 l_indent := 4;
2083 add_debug_messages (p_table_info => p_table_info,
2084 p_procedure_name => l_func_name,
2085 p_message_location => 'END',
2086 p_proc_body => l_debug_message_text);
2087 l_proc_body_tbl(l_proc_index) := l_debug_message_text;
2088 l_proc_index := l_proc_index + 1;
2089
2090 l_proc_comment := format_comment('procedure to download all columns of '
2091 || upper(p_table_info.table_name) || ' data into datapump interface table.')
2092 || indent;
2093
2094 -- add the procedure comment defination to the package header and body
2095 p_header := p_header || l_proc_comment ||'procedure ' || l_func_name ||
2096 l_proc_body_tbl(1) || ';';
2097 l_proc_body_tbl(1) := l_proc_comment || 'procedure ' || l_func_name ||
2098 l_proc_body_tbl(1) || 'is';
2099
2100 -- add local variables , cursor and procedure body to complete the procedure
2101 l_proc_body_tbl(1) := l_proc_body_tbl(1) || l_cursor || l_adt_cursor ||
2102 l_locals || l_prv_proc_body || indent ||'begin' || indent ;
2103
2104 -- add the body of this procedure to the package.
2105 add_to_package_body( l_proc_body_tbl );
2106
2107 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_download',
2108 25);
2109 exception
2110 when others then
2111 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_download',
2112 '(none)','R');
2113 raise;
2114 end generate_download;
2115 -- ----------------------- prepare_calc_range_cursor ---------------------
2116 -- Description:
2117 -- Preapre the cursor for calculate ranges procedure
2118 -- ------------------------------------------------------------------------
2119 procedure prepare_calc_range_cursor
2120 (
2121 p_table_info in hr_dm_gen_main.t_table_info,
2122 p_cursor out nocopy varchar2
2123 )
2124 is
2125 l_cursor_comment varchar2(2000);
2126 l_cursor_defination varchar2(2000);
2127 l_cursor_select_cols varchar2(32767);
2128 l_cursor_select_from varchar2(32767);
2129 l_cursor_select_where varchar2(32767);
2130
2131 begin
2132
2133 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.prepare_calc_range_cursor'
2134 , 5);
2135
2136 -- comments about the cursor
2137 l_cursor_comment := format_comment('cursor to get the minimum and maximum' ||
2138 ' value of the primary key.');
2139
2140 -- defination of cursor
2141 l_cursor_defination := ' cursor csr_get_pk_min_max_val is ' || indent;
2142
2143 -- select columns in the cursor. This will return the list of all columns
2144 -- of the table separated by comma's.
2145
2146 l_cursor_select_cols := ' select min( ' || p_table_info.alias || '.' ||
2147 p_table_info.surrogate_pk_column_name || ')' || indent(10) || ',max( '||
2148 p_table_info.alias || '.' || p_table_info.surrogate_pk_column_name || ')';
2149
2150 -- get from clause
2151 get_cursor_from_clause (p_table_info => p_table_info,
2152 p_from_clause => l_cursor_select_from);
2153 -- get where clause
2154 get_gen_cursor_where_clause (p_table_info => p_table_info,
2155 p_where_clause => l_cursor_select_where,
2156 p_cursor_type => 'CALCULATE_RANGES');
2157
2158 -- finally put the components of where clause together
2159 p_cursor := l_cursor_comment || indent ||
2160 l_cursor_defination || indent ||
2161 l_cursor_select_cols || indent ||
2162 l_cursor_select_from || indent ||
2163 l_cursor_select_where || indent;
2164 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.prepare_calc_range_cursor',
2165 25);
2166 exception
2167 when others then
2168 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.prepare_calc_range_cursor',
2169 '(none)','R');
2170 raise;
2171 end prepare_calc_range_cursor;
2172
2173
2174 -- ----------------------- generate_calculate_ranges -----------------------
2175 -- Description:
2176 -- Generates the calculate_ranges procedure of the TDS
2177 -- ------------------------------------------------------------------------
2178 procedure generate_calculate_ranges
2179 (
2180 p_table_info in hr_dm_gen_main.t_table_info,
2181 p_header in out nocopy varchar2
2182 )
2183 is
2184 l_interface varchar2(32767);
2185 l_locals varchar2(32767) := null;
2186 l_cursor varchar2(32767) := null;
2187 l_comment varchar2(4000);
2188 l_proc_comment varchar2(4000);
2189 l_cursor_name varchar2(30) := 'csr_get_pk_min_max_val';
2190
2191 -- block body of the procedure i.e between begin and end.
2192 l_proc_body varchar2(32767) := null;
2193 l_func_body varchar2(32767) := null;
2194 l_debug_message_text varchar2(32767) := null;
2195 l_package_name varchar2(30) := 'hrdmd_' || p_table_info.short_name;
2196
2197 -- indentation for the statements.it specifies number of blank spaces
2198 -- after which the staement should start.
2199
2200 l_indent number;
2201 l_proc_body_tbl t_varchar2_32k_tbl;
2202 begin
2203 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_calculate_ranges', 5);
2204
2205 -- input parameters for the procedure
2206
2207 l_interface := indent ||
2208 '(p_business_group_id in number,' || indent ||
2209 ' p_last_migration_date in date,' || indent ||
2210 ' p_phase_item_id in number,' || indent ||
2211 ' p_no_of_threads in number)' || indent;
2212
2213 -- if the table has surrogate primary key then open up a cursor
2214 -- to get the minimum and maximum key value.
2215
2216 if p_table_info.surrogate_primary_key = 'Y' then
2217
2218 -- local variables of the procedure
2219
2220 l_locals := indent || '--' || indent ||
2221 '-- Declare cursors and local variables' || indent ||
2222 '--' || indent ||
2223 ' l_proc varchar2(72) := g_package ' ||
2224 '|| ''calculate_ranges'';' || indent ||
2225 ' l_max_key_value number := 0;' || indent ||
2226 ' l_min_key_value number := 0;' || indent ||
2227 ' l_starting_process_sequence number := 0;' || indent ||
2228 ' l_ending_process_sequence number := 0;' || indent ||
2229 ' l_range_value number := 0;' || indent ||
2230 ' l_row_fetched boolean := FALSE;' || indent;
2231 prepare_calc_range_cursor(p_table_info => p_table_info,
2232 p_cursor => l_cursor);
2233
2234 -- add the body of the download procedure
2235
2236 l_indent := 2;
2237
2238 l_proc_body := l_proc_body || indent|| 'begin';
2239
2240 add_debug_messages (p_table_info => p_table_info,
2241 p_procedure_name => 'calculate_ranges',
2242 p_message_location => 'START',
2243 p_proc_body => l_debug_message_text);
2244
2245 l_proc_body := l_proc_body || l_debug_message_text || indent;
2246
2247 -- open the cursor , fetch the data and close the cursor.
2248
2249 l_proc_body :=
2250 l_proc_body || indent(l_indent) ||
2251 'open ' || l_cursor_name || ';' || indent(l_indent) ||'fetch ' ||
2252 l_cursor_name ||' into l_min_key_value ,l_max_key_value;' ||
2253 indent(l_indent) || 'if l_min_key_value is null or l_max_key_value is null '
2254 || 'then' ||
2255 format_comment('No rows selected in this table for download.',l_indent + 2) ||
2256 indent(l_indent + 2) || 'close csr_get_pk_min_max_val;' ||
2257 indent(l_indent + 2) || 'hr_dm_utility.message(''ROUT'',''exit:' ||
2258 l_package_name || '.calculate_ranges (no rows found). '', 25);' ||
2259 indent(l_indent + 2) ||'return;' || indent(l_indent ) ||
2260 'end if;' || indent(l_indent) || 'close csr_get_pk_min_max_val;' || indent;
2261
2262 l_proc_body := l_proc_body || format_comment('find the first range',2);
2263
2264 l_proc_body := l_proc_body || indent(l_indent) ||
2265 'l_range_value := TRUNC ((l_max_key_value - l_min_key_value) / ' ||
2266 'p_no_of_threads);' || indent(l_indent) || 'l_starting_process_sequence :='
2267 ||' l_min_key_value;' || indent(l_indent) ||
2268 'l_ending_process_sequence := l_min_key_value + l_range_value;';
2269
2270 l_proc_body := l_proc_body || format_comment(
2271 'insert the range records equal to the number of threads available for' ||
2272 'processing',2);
2273
2274
2275 -- build up insert statement to insert data into migration range table.
2276 l_proc_body := l_proc_body || indent(l_indent) ||
2277 'for i in 1..p_no_of_threads loop '|| indent(l_indent + 2) ||
2278 'insert into hr_dm_migration_ranges ( range_id ' ;
2279 l_indent := 40;
2280
2281 l_proc_body := l_proc_body ||
2282 indent(l_indent) || ',phase_item_id' ||
2283 indent(l_indent) || ',status' || indent(l_indent) ||
2284 ',starting_process_sequence' || indent(l_indent) ||
2285 ',ending_process_sequence)' ||
2286 indent(l_indent - 7) || 'values ( ' ||
2287 'hr_dm_migration_ranges_s.nextval' ||
2288 indent(l_indent) || ',p_phase_item_id' ||
2289 indent(l_indent) || ',''NS''' || indent(l_indent) ||
2290 ',l_starting_process_sequence' || indent(l_indent) ||
2291 ',l_ending_process_sequence);' || indent;
2292
2293 l_indent := 4;
2294
2295 l_proc_body := l_proc_body || indent(l_indent) ||
2296 'l_starting_process_sequence := l_ending_process_sequence + 1;' ||
2297 format_comment('if it is a last thread then assign the maximum key value to end'
2298 || ' sequence.', l_indent) || indent(l_indent) ||
2299 'if i = p_no_of_threads then' || indent(l_indent+2) ||
2300 'l_ending_process_sequence := l_max_key_value;' || indent(l_indent) ||
2301 'else' || indent(l_indent + 2) ||
2302 'l_ending_process_sequence := l_starting_process_sequence + l_range_value;'
2303 || indent(l_indent) || 'end if;' || indent(l_indent -2) || 'end loop;' ||
2304 indent(l_indent -2) || 'commit;' ;
2305
2306
2307 else
2308 -- if the table does not have a surrogate primary key then insert a
2309 -- dummy row into migration_range table.
2310
2311 -- local variables of the procedure
2312
2313 l_locals := indent || ' --' || indent ||
2314 ' -- Declare cursors and local variables' || indent ||
2315 ' --' || indent ||
2316 ' l_proc varchar2(72) := g_package ' ||
2317 '|| ''calculate_ranges'';' ;
2318
2319 l_indent := 2;
2320
2321 l_proc_body := l_proc_body || indent|| 'begin';
2322
2323 add_debug_messages (p_table_info => p_table_info,
2324 p_procedure_name => 'calculate_ranges',
2325 p_message_location => 'START',
2326 p_proc_body => l_debug_message_text);
2327
2328 l_proc_body := l_proc_body || l_debug_message_text || indent;
2329
2330 -- build up insert statement to insert data into migration range table.
2331
2332 l_indent := 2;
2333 l_proc_body := l_proc_body || indent(l_indent) ||
2334 'insert into hr_dm_migration_ranges ( range_id ' ;
2335 l_indent := 38;
2336
2337 l_proc_body := l_proc_body ||
2338 indent(l_indent) || ',phase_item_id' ||
2339 indent(l_indent) || ',status' || indent(l_indent) ||
2340 ',starting_process_sequence' || indent(l_indent) ||
2341 ',ending_process_sequence)' ||
2342 indent(l_indent - 9) || 'values (' ||
2343 'hr_dm_migration_ranges_s.nextval' ||
2344 indent(l_indent) || ',p_phase_item_id' ||
2345 indent(l_indent) || ',''NS''' || indent(l_indent) ||
2346 ',-99' || indent(l_indent) ||
2347 ',-99);';
2348 end if;
2349
2350 -- add debug messages
2351 add_debug_messages (p_table_info => p_table_info,
2352 p_procedure_name => 'calculate_ranges',
2353 p_message_location => 'END',
2354 p_proc_body => l_debug_message_text);
2355 l_proc_body := l_proc_body || l_debug_message_text || indent;
2356
2357 l_proc_comment := format_comment('procedure to calculate ranges for '
2358 || upper(p_table_info.table_name) || ' data') ||
2359 indent;
2360
2361 -- add the procedure defination to the package header and body
2362 p_header := p_header || l_proc_comment ||'procedure calculate_ranges' ||
2363 l_interface || ';';
2364
2365 -- add the procedure comment defination,local variables , cursor and
2366 -- procedure body
2367
2368 l_proc_body_tbl(1) := l_proc_comment ||'procedure calculate_ranges' ||
2369 l_interface || ' is'|| l_locals || l_cursor || l_proc_body;
2370
2371 -- add the body of this procedure to the package.
2372 add_to_package_body( l_proc_body_tbl );
2373
2374 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_calculate_ranges',
2375 25);
2376 exception
2377 when others then
2378 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_calculate_ranges',
2379 '(none)','R');
2380 raise;
2381 end generate_calculate_ranges;
2382
2383 -- ----------------------- prepare_del_datapump_cursor ---------------------
2384 -- Description:
2385 -- Preapre the cursor for delete data pump procedure
2386 -- ------------------------------------------------------------------------
2387 procedure prepare_del_datapump_cursor
2388 (
2389 p_table_info in hr_dm_gen_main.t_table_info,
2390 p_cursor out nocopy varchar2
2391 )
2392 is
2393 l_cursor_comment varchar2(2000);
2394 l_cursor_defination varchar2(2000);
2395 l_cursor_select_cols varchar2(32767);
2396 l_cursor_select_from varchar2(32767);
2397 l_cursor_select_where varchar2(32767);
2398
2399 begin
2400 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.prepare_del_datapump_cursor', 5);
2401
2402 -- comments about the cursor
2403 l_cursor_comment := format_comment('cursor to get the '||
2404 p_table_info.table_name
2405 || ' data from data pump batch table for a given batch.');
2406 -- defination of cursor
2407 l_cursor_defination := ' cursor csr_' ||p_table_info.alias || ' is ';
2408
2409 -- select columns in the cursor. This will return the list of all columns
2410 -- of the table separated by comma's.
2411
2412 l_cursor_select_cols := ' select rowid row_id ' ;
2413
2414 -- get from clause. dtapump creates a view of the table to be uploaded.
2415 -- view is based on batch_lines table and TUPS load program parameters.
2416
2417 l_cursor_select_from := ' from hrdpv_u'|| p_table_info.short_name;
2418
2419 -- get where clause
2420 -- if the table has a surrogate primary key then a range of the surrogate
2421 -- primary key will be deleted, otherwise, full table will be deleted.
2422
2423 if p_table_info.surrogate_primary_key = 'Y' then
2424 l_cursor_select_where := ' where batch_id = p_batch_id ' || indent ||
2425 ' and p_start_id <= (select to_number(' || g_surrogate_pk_col_param ||
2426 ') from dual)' || indent ||
2427 ' and p_end_id >= (select to_number(' || g_surrogate_pk_col_param ||
2428 ') from dual);';
2429 else
2430 l_cursor_select_where := ' where batch_id = p_batch_id;';
2431 end if;
2432
2433 -- finally put the components of where clause together
2434 p_cursor := l_cursor_comment || indent ||
2435 l_cursor_defination || indent ||
2436 l_cursor_select_cols || indent ||
2437 l_cursor_select_from || indent ||
2438 l_cursor_select_where || indent;
2439
2440 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.prepare_del_datapump_cursor',
2441 25);
2442 exception
2443 when others then
2444 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.prepare_del_datapump_cursor',
2445 '(none)','R');
2446 raise;
2447 end prepare_del_datapump_cursor;
2448
2449
2450 -- ----------------------- generate_delete_datapump -----------------------
2451 -- Description:
2452 -- Generates the delete_datapump procedure of the TDS
2453 -- ------------------------------------------------------------------------
2454 procedure generate_delete_datapump
2455 (
2456 p_table_info in hr_dm_gen_main.t_table_info,
2457 p_header in out nocopy varchar2
2458 )
2459 is
2460 l_interface varchar2(32767);
2461 l_locals varchar2(32767) := null;
2462 l_cursor varchar2(32767) := null;
2463 l_comment varchar2(4000);
2464 l_proc_comment varchar2(4000);
2465 l_cursor_name varchar2(30) := 'csr_' || p_table_info.alias;
2466 l_cursor_rec varchar2(30) := 'csr_' || p_table_info.alias || '_rec';
2467
2468 -- block body of the procedure i.e between begin and end.
2469 l_proc_body varchar2(32767) := null;
2470 l_func_body varchar2(32767) := null;
2471 l_debug_message_text varchar2(32767) := null;
2472
2473 -- indentation for the statements.it specifies number of blank spaces
2474 -- after which the staement should start.
2475
2476 l_indent number;
2477 l_proc_body_tbl t_varchar2_32k_tbl;
2478 begin
2479
2480 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_delete_datapump', 5);
2481
2482 -- input parameters for the procedure
2483
2484 l_interface := indent ||
2485 '(p_start_id in number,' || indent ||
2486 ' p_end_id in number,' || indent ||
2487 ' p_batch_id in number,' || indent ||
2488 ' p_chunk_size in number)' || indent;
2489
2490 -- local variables of the procedure
2491
2492 l_locals := indent || '--' || indent ||
2493 '-- Declare cursors and local variables' || indent ||
2494 '--' || indent ||
2495 ' l_proc varchar2(72) := g_package ' ||
2496 '|| ''delete_datapump'';' || indent ||
2497 ' l_rec_deleted_cnt number := 0;' || indent;
2498
2499 -- cursor to get the data from the data pump table
2500 prepare_del_datapump_cursor (p_table_info,
2501 l_cursor);
2502 -- add the body of the download procedure
2503
2504 l_indent := 2;
2505 l_proc_body := l_proc_body || indent|| 'begin';
2506 l_proc_body := l_proc_body || indent(l_indent) ||
2507 'l_rec_deleted_cnt := 0;';
2508
2509 add_debug_messages (p_table_info => p_table_info,
2510 p_procedure_name => 'delete_datapump',
2511 p_message_location => 'START',
2512 p_proc_body => l_debug_message_text);
2513
2514 l_proc_body := l_proc_body || l_debug_message_text || indent;
2515
2516 l_proc_body :=
2517 l_proc_body || indent(l_indent) ||
2518 'for ' || l_cursor_rec || ' in ' || l_cursor_name || ' loop' ||indent(l_indent);
2519
2520 l_indent := l_indent + 2;
2521
2522 l_comment := format_comment('delete the data from the data pump view for this'
2523 || ' table.',l_indent);
2524
2525 l_proc_body := l_proc_body || l_comment;
2526
2527 l_proc_body := l_proc_body || indent(l_indent) ||
2528 'delete from hrdpv_u' || p_table_info.short_name || indent(l_indent) ||
2529 'where rowid = ' || l_cursor_rec || '.row_id;';
2530
2531 l_proc_body := l_proc_body || indent(l_indent) ||
2532 'l_rec_deleted_cnt := l_rec_deleted_cnt + 1;' || indent(l_indent) ||
2533 format_comment('commit after every chunk_size_value (e.g. 10) records.',
2534 l_indent) || indent(l_indent) || 'if mod (l_rec_deleted_cnt, ' ||
2535 'p_chunk_size) = 0 then ' || indent(l_indent + 2) || 'commit;' ||
2536 indent(l_indent) || 'end if;' || indent(l_indent - 2) || 'end loop;' ||
2537 indent(l_indent - 2) || 'commit;';
2538
2539 add_debug_messages (p_table_info => p_table_info,
2540 p_procedure_name => 'delete_datapump',
2541 p_message_location => 'END',
2542 p_proc_body => l_debug_message_text);
2543
2544 l_proc_body := l_proc_body || l_debug_message_text;
2545
2546 if p_table_info.surrogate_primary_key = 'Y' then
2547 l_proc_comment := format_comment('procedure to delete a range of '
2548 || upper(p_table_info.table_name) || ' data from datapump interface table.')||
2549 indent;
2550 else
2551 l_proc_comment := format_comment('procedure to delete data of '
2552 || upper(p_table_info.table_name) || ' from datapump interface table.')||
2553 indent;
2554 end if;
2555
2556 -- add the procedure comment defination to the package header and body
2557 p_header := p_header || l_proc_comment ||'procedure delete_datapump' ||
2558 l_interface || ';';
2559
2560
2561 -- add the procedure comment defination,local variables , cursor and
2562 -- procedure body
2563
2564 l_proc_body_tbl(1) := l_proc_comment || 'procedure delete_datapump' ||
2565 l_interface || ' is' || l_locals || l_cursor || l_proc_body;
2566
2567 -- add the body of this procedure to the package.
2568 add_to_package_body( l_proc_body_tbl );
2569
2570 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_delete_datapump',
2571 25);
2572 exception
2573 when others then
2574 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_delete_datapump',
2575 '(none)','R');
2576 raise;
2577 end generate_delete_datapump;
2578
2579 -- ----------------------- prepare_delete_source_cursor; ---------------------
2580 -- Description:
2581 -- Preapre the cursor for delete data from the table for a business group
2582 -- which has been migrated.
2583 -- ------------------------------------------------------------------------
2584 procedure prepare_delete_source_cursor
2585 (
2586 p_table_info in hr_dm_gen_main.t_table_info,
2587 p_cursor out nocopy varchar2
2588 )
2589 is
2590 l_cursor_comment varchar2(2000);
2591 l_cursor_defination varchar2(2000);
2592 l_cursor_select_cols varchar2(32767);
2593 l_cursor_select_from varchar2(32767);
2594 l_cursor_select_where varchar2(32767);
2595
2596 begin
2597 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.prepare_delete_source_cursor', 5);
2598
2599 -- comments about the cursor
2600 l_cursor_comment := format_comment('cursor to get the '||
2601 p_table_info.table_name
2602 || ' data for a given business group.');
2603 -- defination of cursor
2604 l_cursor_defination := ' cursor csr_' ||p_table_info.alias || ' is ';
2605
2606 -- select columns in the cursor. This will return the list of all columns
2607 -- of the table separated by comma's.
2608
2609 -- Key combination tables have foreign key on AOL table
2610 -- 'FND_ID_FLEX_STRUCTURES' i.e hierarchy_type = 'A'. To identify
2611 -- the business group for a row in these tables it is required to
2612 -- check whether the ID value of the row is used by any of the
2613 -- child tables. The 'Where' clause generated by this generator
2614 -- does not use the 'exists' clause which results in the same row
2615 -- being fetch equals to the number of child rows it matches. To
2616 -- avoid this ' distinct' clause is added for only these tables.
2617 -- If the 'distinct' clause causes the performance problem then
2618 -- remove it and seed the derive_sql columns in HR_DM_TABLES for
2619 -- these tables.
2620
2621 if p_table_info.use_distinct = 'Y' then
2622 l_cursor_select_cols := ' select distinct ' || p_table_info.alias ||
2623 '.rowid row_id ';
2624 else
2625 l_cursor_select_cols := ' select ' || p_table_info.alias ||
2626 '.rowid row_id ';
2627 end if;
2628
2629 -- get from clause
2630 get_cursor_from_clause (p_table_info => p_table_info,
2631 p_from_clause => l_cursor_select_from);
2632 -- get where clause
2633 get_gen_cursor_where_clause ( p_table_info => p_table_info ,
2634 p_where_clause => l_cursor_select_where,
2635 p_cursor_type => 'DELETE_SOURCE');
2636
2637 -- finally put the components of where clause together
2638 p_cursor := l_cursor_comment || indent ||
2639 l_cursor_defination || indent ||
2640 l_cursor_select_cols || indent ||
2641 l_cursor_select_from || indent ||
2642 l_cursor_select_where || indent;
2643
2644 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.prepare_delete_source_cursor',
2645 25);
2646 exception
2647 when others then
2648 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.prepare_delete_source_cursor',
2649 '(none)','R');
2650 raise;
2651 end prepare_delete_source_cursor;
2652
2653 -- ----------------------- generate_delete_source -----------------------
2654 -- Description:
2655 -- Generates the delete_source procedure of the TDS.
2656 -- ------------------------------------------------------------------------
2657 procedure generate_delete_source
2658 (
2659 p_table_info in hr_dm_gen_main.t_table_info,
2660 p_header in out nocopy varchar2
2661 )
2662 is
2663 l_interface varchar2(32767);
2664 l_locals varchar2(32767) := null;
2665 l_cursor varchar2(32767) := null;
2666 l_comment varchar2(4000);
2667 l_proc_comment varchar2(4000);
2668 l_cursor_name varchar2(30) := 'csr_' || p_table_info.alias;
2669 l_cursor_rec varchar2(30) := 'csr_' || p_table_info.alias || '_rec';
2670
2671 -- block body of the procedure i.e between begin and end.
2672 l_proc_body varchar2(32767) := null;
2673 l_func_body varchar2(32767) := null;
2674 l_debug_message_text varchar2(32767) := null;
2675
2676 -- indentation for the statements.it specifies number of blank spaces
2677 -- after which the staement should start.
2678
2679 l_indent number;
2680 l_proc_body_tbl t_varchar2_32k_tbl;
2681 begin
2682
2683 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.generate_delete_source', 5);
2684
2685 -- input parameters for the procedure
2686
2687 l_interface := indent ||
2688 '(p_business_group_id in number,' || indent ||
2689 ' p_start_id in number,' || indent ||
2690 ' p_end_id in number,' || indent ||
2691 ' p_chunk_size in number)' || indent;
2692
2693 -- message (' l_interface = ' || l_interface);
2694 -- local variables of the procedure
2695
2696 l_locals := indent || '--' || indent ||
2697 '-- Declare cursors and local variables' || indent ||
2698 '--' || indent ||
2699 ' l_proc varchar2(72) := g_package ' ||
2700 '|| ''delete_source'';' || indent ||
2701 ' l_rec_deleted_cnt number := 0;' || indent;
2702
2703 -- cursor to get the data from the data pump table
2704 prepare_delete_source_cursor (p_table_info,
2705 l_cursor);
2706
2707 -- add the body of the download procedure
2708
2709 l_indent := 2;
2710 l_proc_body := l_proc_body || indent|| 'begin';
2711 l_proc_body := l_proc_body || indent(l_indent) ||
2712 'l_rec_deleted_cnt := 0;';
2713
2714
2715
2716 add_debug_messages (p_table_info => p_table_info,
2717 p_procedure_name => 'delete_source',
2718 p_message_location => 'START',
2719 p_proc_body => l_debug_message_text);
2720
2721 l_proc_body := l_proc_body || l_debug_message_text || indent;
2722
2723 l_proc_body :=
2724 l_proc_body || indent(l_indent) ||
2725 'for ' || l_cursor_rec || ' in ' || l_cursor_name || ' loop' ||indent(l_indent);
2726
2727 l_indent := l_indent + 2;
2728
2729 l_comment := format_comment('delete the row read from the table.',l_indent);
2730
2731 l_proc_body := l_proc_body || l_comment;
2732
2733 l_proc_body := l_proc_body || indent(l_indent) ||
2734 'delete from ' || p_table_info.table_name || indent(l_indent) ||
2735 'where rowid = ' || l_cursor_rec || '.row_id;';
2736
2737
2738 l_proc_body := l_proc_body || indent(l_indent) ||
2739 'l_rec_deleted_cnt := l_rec_deleted_cnt + 1;' || indent(l_indent) ||
2740 format_comment('commit after every chunk_size_value (e.g. 10) records.',
2741 l_indent) || indent(l_indent) || 'if mod (l_rec_deleted_cnt, ' ||
2742 'p_chunk_size) = 0 then ' || indent(l_indent + 2) || 'commit;' ||
2743 indent(l_indent) || 'end if;' || indent(l_indent - 2) || 'end loop;' ||
2744 indent(l_indent - 2) || 'commit;';
2745
2746 add_debug_messages (p_table_info => p_table_info,
2747 p_procedure_name => 'delete_source',
2748 p_message_location => 'END',
2749 p_proc_body => l_debug_message_text);
2750
2751 l_proc_body := l_proc_body || l_debug_message_text;
2752
2753 l_proc_comment := format_comment('procedure to delete data of '
2754 || upper(p_table_info.table_name) || ' for a given business group.')||
2755 indent;
2756
2757 -- add the procedure comment defination to the package header and body
2758 p_header := p_header || l_proc_comment ||'procedure delete_source' ||
2759 l_interface || ';';
2760
2761 -- add the procedure comment defination,local variables , cursor and
2762 -- procedure body
2763
2764 l_proc_body_tbl(1) := l_proc_comment || 'procedure delete_source' ||
2765 l_interface || ' is' || l_locals || l_cursor || l_proc_body;
2766
2767 -- add the body of this procedure to the package.
2768 add_to_package_body( l_proc_body_tbl );
2769
2770
2771 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.generate_delete_source',
2772 25);
2773
2774 exception
2775 when others then
2776 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.generate_delete_source',
2777 '(none)','R');
2778 raise;
2779 end generate_delete_source;
2780
2781 -- ------------------------- create_tds_pacakge ------------------------
2782 -- Description: Create the TDS package and relevant procedures for the table.
2783 --
2784 -- Input Parameters :
2785 -- p_table_info - Information about table for which TDS to be generated. Info
2786 -- like Datetrack, Global Data, Surrogate Primary key etc about
2787 -- the table is passed as a record type.
2788 -- p_columns_tbl - All the columns of the table stored as a list.
2789 -- p_parameters_tbl - All the columns of the table stored with data type are
2790 -- stored as a list. e.g p_business_group_id number
2791 -- This is used to create the procedure parameter list for
2792 -- TDS procedure.
2793 -- p_aol_columns_tbl - All the columns of the table which have foreign key to
2794 -- AOL table are stored as a list.
2795 -- p_aol_parameters_tbl - All the columns of the table which have foreign key to
2796 -- AOL table are stored with data type as a list. This is
2797 -- used as a parameter list for the procedure generated to
2798 -- get the AOL developer key for the given ID value
2799 -- e.g p_user_id number
2800 -- p_fk_to_aol_columns_tbl - It stores the list of all the columns which have
2801 -- foreign on AOL table and corresponding name of the AOL
2802 -- table.
2803 -- ------------------------------------------------------------------------
2804 procedure create_tds_pacakge
2805 (
2806 p_table_info in hr_dm_gen_main.t_table_info,
2807 p_columns_tbl in hr_dm_library.t_varchar2_tbl,
2808 p_parameters_tbl in hr_dm_library.t_varchar2_tbl,
2809 p_aol_columns_tbl in hr_dm_library.t_varchar2_tbl,
2810 p_aol_parameters_tbl in hr_dm_library.t_varchar2_tbl,
2811 p_fk_to_aol_columns_tbl in hr_dm_gen_main.t_fk_to_aol_columns_tbl
2812 )
2813 is
2814 l_header varchar2(32767);
2815 l_body varchar2(32767);
2816 l_header_comment varchar2(2048);
2817 l_package_name varchar2(30) := 'hrdmd_' || p_table_info.short_name;
2818 l_generator_version hr_dm_tables.generator_version%type;
2819 l_package_version varchar2(200);
2820 l_index number := 1;
2821 l_call_to_aol_proc varchar2(32767);
2822 l_dev_key_local_var varchar2(32767);
2823 l_proc_body_tbl t_varchar2_32k_tbl;
2824 l_proc_index number := 1;
2825 begin
2826 hr_dm_utility.message('ROUT','entry:hr_dm_gen_tds.create_tds_pacakge', 5);
2827 hr_dm_utility.message('PARA','(Table Name - ' || p_table_info.table_name ||
2828 ')', 10);
2829
2830 g_table_info := p_table_info;
2831 g_columns_tbl := p_columns_tbl;
2832 g_parameters_tbl := p_parameters_tbl;
2833 g_surrogate_pk_col_param := 'p_' ||
2834 rpad(p_table_info.surrogate_pk_column_name,28);
2835
2836 -- inialize the global package body pl/sql table by deleting all elements.
2837 init_package_body;
2838
2839 -- Get the version of the generator to be appended to the TDS package
2840 -- generated for a table. This will help in finding out which version
2841 -- of Generator is used to generate the TDS package.
2842
2843 hr_dm_library.get_generator_version(p_generator_version => l_generator_version,
2844 p_format_output => 'Y');
2845
2846 -- Get the package version of this TDS package body.
2847 hr_dm_library.get_package_version ( p_package_name => 'HR_DM_GEN_TDS',
2848 p_package_version => l_package_version,
2849 p_version_type => 'FULL');
2850
2851
2852 -- if there is a column hirearchy then store the hierarchy columns list and
2853 -- parameter assignment in pl/sql variable.
2854
2855 if p_table_info.column_hierarchy = 'Y' then
2856 -- get the columns and parameter list. store in pl/sql table.
2857
2858 hr_dm_library.populate_hierarchy_cols_list
2859 (p_table_info => p_table_info,
2860 p_hier_columns_tbl => g_hier_columns_tbl,
2861 p_hier_parameter_tbl => g_hier_parameters_tbl,
2862 p_called_from => 'TDS' );
2863 end if;
2864
2865 -- Start the package header and body.
2866 begin
2867 --
2868 -- Set up initial parts of the package header and body.
2869 --
2870 l_header_comment := l_package_version || indent || '/*' || indent ||
2871 ' * Generated by hr_dm_gen_tds at: ' ||
2872 to_char( sysdate, 'YYYY/MM/DD HH24:MM:SS' ) || indent ||
2873 ' * Generated Data Migrator TDS for : ' || p_table_info.table_name || '.' ||
2874 indent ||
2875 ' * Generator Version Used to generate this TDS is : ' || indent ||
2876 l_generator_version || indent ||
2877 ' */' || indent || '--' || indent;
2878
2879 l_header :=
2880 'create or replace package ' || l_package_name || ' as' || indent ||
2881 l_header_comment ||
2882 'g_generator_version constant varchar2(128) default ' ||
2883 '''$Revision: 120.0 $'';' || indent || '--' || indent;
2884
2885 l_proc_body_tbl(1) :=
2886 'create or replace package body ' || l_package_name || ' as' || indent ||
2887 l_header_comment;
2888
2889 -- private package variable
2890 l_proc_body_tbl(1) := l_proc_body_tbl(1) || indent || '--' ||
2891 indent || '-- Package Variables' || indent ||
2892 '--' || indent ||
2893 'g_package varchar2(33) := ''' || l_package_name || ''';' ||
2894 indent;
2895
2896 -- add the body of this procedure to the package.
2897 add_to_package_body( l_proc_body_tbl );
2898 --
2899 -- Generate the procedures and functions.
2900 --
2901
2902 -- if it is a datetrack generate procedure to get link value.
2903 if p_table_info.datetrack = 'Y' then
2904
2905 -- create a procedure to get the link value to be used by data pump for
2906 -- uploading.
2907
2908 generate_get_link_value(p_table_info);
2909 end if;
2910
2911 -- if the table has a columns which have a foreign key to AOL table then
2912 -- generate the procedures so as to create the procedures to get the
2913 -- corresponding developer's key for those columns.
2914
2915 if p_table_info.fk_to_aol_table = 'Y' then
2916 generate_developer_key_func
2917 ( p_fk_to_aol_columns_tbl => p_fk_to_aol_columns_tbl,
2918 p_table_info => p_table_info,
2919 p_call_to_proc_body => l_call_to_aol_proc,
2920 p_dev_key_local_var_body => l_dev_key_local_var);
2921 end if;
2922
2923 l_body := l_body || indent || '--' || indent;
2924
2925 -- generate download procedure to download data into batch_lines.
2926 -- for column hierarchy.
2927 --
2928 -- for download of hierarchy columns, we are assuming that there
2929 -- will be no H hierarchy columns where the same column will also
2930 -- have an A hierarchy, ie there will be no A hierarchy calls and
2931 -- hence p_call_to_proc_body => '', instead of
2932 -- p_call_to_proc_body => l_call_to_aol_proc,
2933
2934 if p_table_info.column_hierarchy = 'Y' then
2935 l_body := l_body || indent || '--' || indent;
2936 generate_download(p_table_info => p_table_info,
2937 p_header => l_header,
2938 p_hier_column => 'Y',
2939 p_call_to_proc_body => '',
2940 p_dev_key_local_var_body => l_dev_key_local_var,
2941 p_fk_to_aol_columns_tbl => p_fk_to_aol_columns_tbl);
2942 end if;
2943
2944 -- down load procedure to download all columns.
2945 generate_download(p_table_info => p_table_info,
2946 p_header => l_header,
2947 p_hier_column => 'N',
2948 p_call_to_proc_body => l_call_to_aol_proc,
2949 p_dev_key_local_var_body => l_dev_key_local_var,
2950 p_fk_to_aol_columns_tbl => p_fk_to_aol_columns_tbl);
2951
2952
2953 l_header := l_header || indent || '--' || indent;
2954 l_body := l_body || indent || '--' || indent;
2955
2956 -- generate calculate_ranges procedure to download data into batch_lines.
2957
2958 l_body := l_body || indent || '--' || indent;
2959 generate_calculate_ranges(p_table_info,
2960 l_header);
2961
2962 -- generate delete_datapump procedure to delete data from batch_lines.
2963 -- table for the given table.
2964
2965 l_body := l_body || indent || '--' || indent;
2966 generate_delete_datapump(p_table_info,
2967 l_header );
2968
2969 -- generate delete_source procedure to delete data from batch_lines.
2970 -- table for the given table.
2971
2972 l_body := l_body || indent || '--' || indent;
2973 generate_delete_source(p_table_info,
2974 l_header);
2975
2976 l_header := l_header || indent || '--' || indent;
2977 l_body := l_body || indent || '--' || indent;
2978
2979 -- Terminate the package body and header.
2980 --
2981 l_header := l_header || 'end ' || l_package_name || ';';
2982 l_body := l_body || 'end ' || l_package_name || ';';
2983 exception
2984 when plsql_value_error then
2985 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.create_tds_pacakge',
2986 'Either TDS package code size is too big or ' ||
2987 ' a value error)',
2988 'R');
2989 raise;
2990 end;
2991
2992 g_package_index := g_package_index+1;
2993 g_package_body(g_package_index ) := indent || 'end ' ||
2994 l_package_name || ';';
2995
2996 --
2997 -- Compile the header and body.
2998 --
2999
3000 hr_dm_library.run_sql( l_header );
3001 hr_dm_library.run_sql( g_package_body,
3002 g_package_index);
3003
3004
3005 -- check the status of the package
3006
3007
3008 -- check the status of the package
3009 begin
3010 hr_dm_library.check_compile (p_object_name => l_package_name,
3011 p_object_type => 'PACKAGE BODY' );
3012 exception
3013 when others then
3014 hr_dm_utility.error(SQLCODE,'Error in compiling TDS for ' ||
3015 p_table_info.table_name ,'(none)','R');
3016 raise;
3017 end;
3018
3019 hr_dm_utility.message('ROUT','exit:hr_dm_gen_tds.create_tds_pacakge',
3020 25);
3021 exception
3022 when others then
3023 hr_dm_utility.error(SQLCODE,'hr_dm_gen_tds.create_tds_pacakge ',
3024 '(none)','R');
3025 raise;
3026 end create_tds_pacakge ;
3027
3028 end hr_dm_gen_tds;