1 PACKAGE BODY XDP_PURGE AS
2 /* $Header: XDPPRGB.pls 120.2 2006/08/09 13:47:15 dputhiye noship $ */
3
4 g_debug_level NUMBER := 4;
5
6 bAudit VARCHAR2(8) := 'FALSE';
7 g_purge_method VARCHAR2(8) := 'CM';
8
9 -- number of exceptions will be allowed before jumping out a loop.
10 g_max_exceptions NUMBER := 5;
11 -- commit every P_MSG_NAME g_max_rows_before_commit deletions
12 g_max_rows_before_commit NUMBER := 5000;
13
14 G_Total_WK_TIME NUMBER := 0;
15 G_PURGE_WORK_FLOW VARCHAR2(8) := 'FALSE';
16
17 PROCEDURE RECORDS_PURGED_MSGS(
18 p_no_records IN number DEFAULT 0,
19 p_table_name IN VARCHAR2 DEFAULT NULL,
20 p_msg_name IN VARCHAR2 DEFAULT 'XDP_PURGE_REC',
21 p_debug_level IN NUMBER DEFAULT 0 -- DEFAULT TO CONSICE MESSAGES
22 )
23 IS
24 l_error_msg VARCHAR2(2000);
25 BEGIN
26 IF p_debug_level >= g_debug_level THEN
27 RETURN;
28 END IF;
29 IF p_no_records > 1 THEN
30 FND_MESSAGE.SET_NAME('XDP',p_msg_name||'S');
31 FND_MESSAGE.SET_TOKEN('RECORDS',p_no_records);
32 FND_MESSAGE.SET_TOKEN('TABLE_NAME',p_table_name);
33 ELSIF (p_no_records = 0) THEN
34 RETURN; -- do not log anythig
35 FND_MESSAGE.SET_NAME('XDP',p_msg_name||'S');
36 FND_MESSAGE.SET_TOKEN('RECORDS','No');
37 FND_MESSAGE.SET_TOKEN('TABLE_NAME',p_table_name);
38 ELSE
39 FND_MESSAGE.SET_NAME('XDP',p_msg_name);
40 FND_MESSAGE.SET_TOKEN('TABLE_NAME',p_table_name);
41 END IF;
42 l_error_msg := SUBSTR(FND_MESSAGE.GET,0,1999);
43
44 -- IF CALLER IS CONCURRENT MANAGER, USE FND_FILE
45 -- OR ELSE USE DBMS_OUTPUT
46
47 IF g_purge_method = 'CM' THEN
48 FND_FILE.PUT_LINE(FND_FILE.LOG,l_error_msg);
49 ELSE
50 -- DBMS_OUTPUT.PUT_LINE(l_error_msg);
51 null;
52 END IF;
53 END;
54
55 --
56 -- Internal procedure for handling messages
57 -- Name PURGE_ERRORS
58 --
59
60 PROCEDURE PURGE_ERRORS(
61 p_msg IN VARCHAR2 DEFAULT NULL,
62 p_commit IN BOOLEAN DEFAULT FALSE,
63 p_abort IN BOOLEAN DEFAULT FALSE,
64 p_debug_level IN NUMBER DEFAULT 0 -- DEFAULT TO CONSICE MESSAGES
65 )
66 IS
67 BEGIN
68
69 IF g_purge_method = 'CM' THEN
70 FND_FILE.PUT_LINE(FND_FILE.LOG,P_MSG);
71 ELSE
72 -- DBMS_OUTPUT.PUT_LINE(P_MSG);
73 null;
74 END IF;
75
76 IF p_commit THEN
77 COMMIT;
78 END IF;
79
80 IF p_abort THEN
81 APP_EXCEPTION.RAISE_EXCEPTION;
82 END IF;
83 END PURGE_ERRORS;
84
85 FUNCTION USER_ROLLBACK_CTRL(p_rollback_segment VARCHAR2) RETURN BOOLEAN IS
86 l_result BOOLEAN := FALSE;
87 l_stmt VARCHAR2(200);
88 BEGIN
89 --
90 -- Rollback segment controlled by customers. No incremental commit will be performed
91 -- for such cases. It is user's responsibility to make sure the rollback
92 -- segment is big enough to handle the transaction
93 -- However, if fails to transaction rollback segment, then default rollback segment
94 -- will still be used with incremental commits.
95 --
96
97 IF (p_rollback_segment IS NOT NULL) THEN
98 PURGE_ERRORS('Setting rollback segment to '||p_rollback_segment);
99 -- IF FAILS, ON EXCEPTION, FLAG WLLL BE SET FALSE
100 COMMIT; -- we have to clean up the current transaction.
101 l_stmt := 'SET TRANSACTION USE ROLLBACK SEGMENT '||p_rollback_segment;
102 EXECUTE IMMEDIATE l_STMT;
103
104 -- SET TRANSACTION USE ROLLBACK SEGMENT :p_rollback_segment;
105 PURGE_ERRORS(p_rollback_segment || ' rollback segment will be used!');
106 l_result := TRUE;
107 ELSE
108 PURGE_ERRORS('Default rollback segment will be used');
109 END IF;
110 RETURN(l_result);
111 EXCEPTION
112 WHEN OTHERS THEN
113 PURGE_ERRORS('Default rollback segment will be used');
114 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512));
115 RETURN(FALSE);
116 END USER_ROLLBACK_CTRL;
117
118 PROCEDURE XDP_CHECK_ORDER(
119 p_order_id IN VARCHAR2 DEFAULT NULL
120 ) IS
121
122 l_no_records NUMBER := 0;
123 l_counter NUMBER := 0;
124 l_temp NUMBER := 0;
125 l_order_exist BOOLEAN := FALSE;
126 l_wi_type WF_ITEMS.ITEM_TYPE%TYPE;
127 l_wi_key WF_ITEMS.ITEM_KEY%TYPE;
128
129 BEGIN
130 IF p_order_id IS NULL THEN
131 -- CHECK IF THERE ARE ANY RECORDS IN ANY TABLE THAT HAVE
132 -- ORDER_IDS THAT DO NOT EXSIT IN XDP_ORDER_HEADER TABLE
133
134 RETURN;
135 END IF;
136
137 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_HEADERS
138 WHERE ORDER_ID = p_order_id;
139
140 RECORDS_PURGED_MSGS(l_no_records,'XDP_ORDER_HEADERS WHERE ORDER_ID = '||p_order_id,
141 'XDP_FOUND_REC',0);
142
143 IF l_no_records > 0 THEN
144 l_order_exist := TRUE;
145 END IF;
146
147 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_RELATIONSHIPS
148 WHERE ORDER_ID = p_order_id;
149
150 RECORDS_PURGED_MSGS(l_no_records ,'XDP_ORDER_RELATIONSHIPS WHERE ORDER_ID = '||p_order_id,
151 'XDP_FOUND_REC',0);
152
153 SELECT COUNT(*) INTO l_no_records FROM XNP_MSGS
154 WHERE ORDER_ID = p_order_id;
155
156 RECORDS_PURGED_MSGS(l_no_records,'XNP_MSGS WHERE ORDER_ID = '||p_order_id,
157 'XDP_FOUND_REC',0);
158
159 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_PARAMETERS
160 WHERE ORDER_ID = p_order_id;
161
162 RECORDS_PURGED_MSGS(l_no_records,'XDP_ORDER_PARAMETERS WHERE ORDER_ID = '||p_order_id,
163 'XDP_FOUND_REC',0);
164
165 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_BUNDLES
166 WHERE ORDER_ID = p_order_id;
167
168 RECORDS_PURGED_MSGS(l_no_records,'XDP_ORDER_BUNDLES WHERE ORDER_ID = '||p_order_id,
169 'XDP_FOUND_REC',0);
170
171 SELECT COUNT(*) INTO l_no_records FROM XNP_CALLBACK_EVENTS
172 WHERE ORDER_ID = p_order_id;
173 RECORDS_PURGED_MSGS(l_no_records,'XNP_CALLBACK_EVENTS WHERE ORDER_ID = '||p_order_id,
174 'XDP_FOUND_REC',0);
175
176 SELECT COUNT(*) INTO l_no_records FROM XNP_TIMER_REGISTRY
177 WHERE ORDER_ID = p_order_id;
178 RECORDS_PURGED_MSGS(l_no_records,'XNP_TIMER_REGISTRY WHERE ORDER_ID = '||p_order_id,
179 'XDP_FOUND_REC',0);
180
181 SELECT COUNT(*) INTO l_no_records FROM XNP_SYNC_REGISTRATION
182 WHERE ORDER_ID = p_order_id;
183 RECORDS_PURGED_MSGS(l_no_records,'XNP_SYNC_REGISTRATION WHERE ORDER_ID = '||p_order_id,
184 'XDP_FOUND_REC',0);
185
186 IF l_order_exist THEN
187 SELECT wf_item_type,wf_item_key INTO l_wi_type,l_wi_key
188 FROM XDP_ORDER_HEADERS
189 WHERE ORDER_ID = p_order_id;
190
191 SELECT count(*) INTO l_no_records
192 FROM WF_ITEMS
193 START WITH item_type = l_wi_type AND item_key = l_wi_key
194 CONNECT BY PRIOR item_key = parent_item_key
195 AND PRIOR item_type = parent_item_type;
196 RECORDS_PURGED_MSGS(l_no_records,'WF_ITEMS WHERE ORDER_ID = '||p_order_id,
197 'XDP_FOUND_REC',0);
198 END IF;
199
200 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_LINE_ITEMS
201 WHERE ORDER_ID = p_order_id;
202
203 RECORDS_PURGED_MSGS(l_no_records,'XDP_ORDER_LINE_ITEMS WHERE ORDER_ID = '||p_order_id,
204 'XDP_FOUND_REC',0);
205
206 IF l_no_records <> 0 THEN
207 FOR c_item IN (SELECT LINE_ITEM_ID FROM XDP_ORDER_LINE_ITEMS
208 WHERE ORDER_ID = p_order_id)
209 LOOP
210 SELECT COUNT(*) INTO l_no_records FROM XDP_ORDER_LINEITEM_DETS
211 WHERE LINE_ITEM_ID = c_item.LINE_ITEM_ID;
212
213 RECORDS_PURGED_MSGS(l_no_records,'XDP_ORDER_LINEITEM_DETS WHERE LINE_ITEM_ID = '
214 ||c_item.LINE_ITEM_ID,'XDP_FOUND_REC',1);
215
216 SELECT COUNT(*) INTO l_no_records FROM XDP_LINE_RELATIONSHIPS
217 WHERE LINE_ITEM_ID = c_item.LINE_ITEM_ID;
218
219 RECORDS_PURGED_MSGS(l_counter,'XDP_LINE_RELATIONSHIPS WHERE LINE_ITEM_ID = '
220 ||c_item.LINE_ITEM_ID,'XDP_FOUND_REC',1);
221
222 SELECT COUNT(*) INTO l_no_records FROM XDP_FULFILL_WORKLIST
223 WHERE LINE_ITEM_ID = c_item.LINE_ITEM_ID;
224
225 RECORDS_PURGED_MSGS(l_counter,'XDP_FULFILL_WORKLIST WHERE LINE_ITEM_ID = '
226 ||c_item.LINE_ITEM_ID,'XDP_FOUND_REC',1);
227
228 IF l_no_records <> 0 THEN
229 FOR c_fw IN (SELECT WORKITEM_INSTANCE_ID FROM XDP_FULFILL_WORKLIST
230 WHERE LINE_ITEM_ID = C_ITEM.LINE_ITEM_ID)
231 LOOP
232 SELECT COUNT(*) INTO l_temp FROM XDP_WI_RELATIONSHIPS
233 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID;
234
235 RECORDS_PURGED_MSGS(l_counter,'XDP_WI_RELATIONSHIPS '||
236 'WHERE WORKITEM_INSTANCE_ID = '
237 ||c_fw.WORKITEM_INSTANCE_ID,'XDP_FOUND_REC',2);
238
239 SELECT COUNT(*) INTO l_temp FROM XDP_WORKLIST_DETAILS
240 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID;
241
242 RECORDS_PURGED_MSGS(l_counter,'XDP_WORKLIST_DETAILS '||
243 'WHERE WORKITEM_INSTANCE_ID = '
244 ||c_fw.WORKITEM_INSTANCE_ID,'XDP_FOUND_REC',2);
245
246 SELECT COUNT(*) INTO l_temp FROM XDP_FA_RUNTIME_LIST
247 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID;
248
249 RECORDS_PURGED_MSGS(l_counter,'XDP_FA_RUNTIME_LIST '||
250 'WHERE WORKITEM_INSTANCE_ID = '
251 ||c_fw.WORKITEM_INSTANCE_ID,'XDP_FOUND_REC',2);
252
253 IF l_temp <> 0 THEN
254 FOR c_fa IN (SELECT FA_INSTANCE_ID FROM XDP_FA_RUNTIME_LIST
255 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID)
256 LOOP
257 SELECT COUNT(*) INTO l_temp FROM XDP_FA_DETAILS WHERE
258 FA_INSTANCE_ID = c_fa.FA_INSTANCE_ID;
259
260 RECORDS_PURGED_MSGS(l_counter,'XDP_FA_DETAILS WHERE FA_INSTANCE_ID = '
261 ||c_fa.FA_INSTANCE_ID,'XDP_FOUND_REC',3);
262 SELECT COUNT(*) INTO l_temp FROM XDP_FE_CMD_AUD_TRAILS
263 WHERE FA_INSTANCE_ID = c_fa.FA_INSTANCE_ID;
264
265 RECORDS_PURGED_MSGS(l_counter,'XDP_FE_CMD_AUD_TRAILS WHERE FA_INSTANCE_ID = '
266 ||c_fa.FA_INSTANCE_ID,'XDP_FOUND_REC',3);
267 END LOOP;
268 END IF;
269
270 SELECT COUNT(*) INTO l_temp FROM XDP_FMC_AUDIT_TRAILS
271 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID;
272
273 RECORDS_PURGED_MSGS(l_counter,'XDP_FMC_AUDIT_TRAILS '||
274 'WHERE WORKITEM_INSTANCE_ID = '
275 ||c_fw.WORKITEM_INSTANCE_ID,'XDP_FOUND_REC',2);
276
277 IF l_temp <> 0 THEN
278 SELECT COUNT(*) INTO l_temp FROM XDP_FMC_AUD_TRAIL_DETS WHERE FMC_ID IN
279 (SELECT FMC_ID FROM XDP_FMC_AUDIT_TRAILS
280 WHERE WORKITEM_INSTANCE_ID = c_fw.WORKITEM_INSTANCE_ID);
281
282 RECORDS_PURGED_MSGS(l_counter,'XDP_FMC_AUD_TRAIL_DETS '||
283 'WHERE WORKITEM_INSTANCE_ID = '
284 ||c_fw.WORKITEM_INSTANCE_ID,'XDP_FOUND_REC',3);
285 END IF;
286 END LOOP;
287 END IF;
288 END LOOP;
289 END IF;
290 END XDP_CHECK_ORDER;
291
292 PROCEDURE XDP_CHECK_SOA
293 (
294 p_sv_soa_id IN VARCHAR2 DEFAULT NULL,
295 p_time_from IN DATE DEFAULT NULL,
296 p_time_to IN DATE DEFAULT NULL
297 ) IS
298
299 l_no_records NUMBER :=0;
300
301 BEGIN
302
303 IF p_sv_soa_id IS NULL THEN
304 IF (p_time_from IS NULL) OR (p_time_to IS NULL) THEN
305 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
306 FND_MESSAGE.SET_TOKEN('OBJECT','SOA');
307 FND_MESSAGE.SET_TOKEN('CONDITION','XDP_CHECK_SOA');
308 PURGE_ERRORS(FND_MESSAGE.GET);
309 END IF;
310
311 FOR l_sv_soa IN (SELECT SV_SOA_ID FROM XNP_SV_SOA A, XNP_SV_STATUS_TYPES_B B
312 WHERE a.STATUS_TYPE_CODE = b.STATUS_TYPE_CODE
313 AND b.PHASE_INDICATOR ='OLD'
314 AND a.MODIFIED_DATE < p_time_to
315 AND a.MODIFIED_DATE > p_time_from)
316 LOOP
317 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_SOA_JN
318 WHERE SV_SOA_ID = l_sv_soa.SV_SOA_ID;
319
320 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_SOA_JN WHERE SV_SOA_ID ='
321 ||l_sv_soa.SV_SOA_ID,'XDP_FOUND_REC',1);
322
323 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_FAILURES
324 WHERE SV_SOA_ID = l_sv_soa.SV_SOA_ID;
325
326 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_FAILURES WHERE SV_SOA_ID ='
327 ||l_sv_soa.SV_SOA_ID,'XDP_FOUND_REC',1);
328
329 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_EVENT_HISTORY
330 WHERE SV_SOA_ID = l_sv_soa.SV_SOA_ID;
331
332 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_EVENT_HISTORY WHERE SV_SOA_ID ='
333 ||l_sv_soa.SV_SOA_ID,'XDP_FOUND_REC',1);
334 END LOOP;
335 RETURN;
336 END IF;
337
338 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_SOA WHERE SV_SOA_ID = p_sv_soa_id;
339 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_SOA WHERE SV_SOA_ID ='
340 ||p_sv_soa_id,'XDP_FOUND_REC',0);
341
342 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_EVENT_HISTORY
343 WHERE SV_SOA_ID = p_sv_soa_id;
344 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_EVENT_HISTORY WHERE SV_SOA_ID ='
345 ||p_sv_soa_id,'XDP_FOUND_REC',0);
346 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_FAILURES
347 WHERE SV_SOA_ID = p_sv_soa_id;
348 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_FAILURES WHERE SV_SOA_ID ='
349 ||p_sv_soa_id,'XDP_FOUND_REC',0);
350 SELECT COUNT(*) INTO l_no_records FROM XNP_SV_SOA_JN
351 WHERE SV_SOA_ID = p_sv_soa_id;
352 RECORDS_PURGED_MSGS(l_no_records,'XNP_SV_SOA_JN WHERE SV_SOA_ID ='
353 ||p_sv_soa_id,'XDP_FOUND_REC',0);
354 COMMIT;
355 EXCEPTION
356 WHEN OTHERS THEN
357 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
358 FND_MESSAGE.SET_TOKEN('OBJECT','SOA');
359 FND_MESSAGE.SET_TOKEN('CONDITION','XDP_CHECK_SOA');
360 PURGE_ERRORS(FND_MESSAGE.GET);
361 END XDP_CHECK_SOA;
362
363 -- Internal procedure for verifying if an order is deletable
364 -- Name IS_ORDER_DELETABLE
365 --
366
367 PROCEDURE IS_ORDER_DELETABLE(
368 p_order_id IN XDP_ORDER_HEADERS.ORDER_ID%TYPE,
369 p_date_from IN DATE,
370 p_date_to IN DATE,
371 p_order_deletable OUT NOCOPY VARCHAR2
372 ) IS
373 --
374 --The following cursor is to find all related orders in the heirachy
375 -- rooted from the order with id of p_order_id.
376 -- If any one of this related orders do not satisfy the given
377 -- purging conditions, then the current order is not deletable.
378 --
379 CURSOR c_order_relation(p_order_id VARCHAR2) IS
380 SELECT RELATED_ORDER_ID
381 FROM XDP_ORDER_RELATIONSHIPS
382 START WITH ORDER_ID = p_order_id
383 CONNECT BY PRIOR RELATED_ORDER_ID = ORDER_ID;
384
385 l_order_state XDP_ORDER_HEADERS.STATUS_CODE%TYPE;
386 --l_order_state XDP_ORDER_HEADERS.ORDER_ID%TYPE;
387 l_completion_date DATE;
388
389 BEGIN
390 p_order_deletable :='FALSE';
391 FOR l_order_relation IN c_order_relation(p_order_id) LOOP
392 --Date: 09 AUG 2006 Author: DPUTHIYE Bug #:5446335
393 --This SQL should consider CANCEL_PROVISIONING_DATE for cancelled orders as well.
394 --Dependencies: None.
395 /* SELECT status_code,
396 completion_date
397 INTO l_order_state,
398 l_completion_date
399 FROM XDP_ORDER_HEADERS
400 WHERE order_id = l_order_relation.related_order_id; */
401
402 SELECT status_code,
403 NVL(completion_date, CANCEL_PROVISIONING_DATE)
404 INTO l_order_state,
405 l_completion_date
406 FROM XDP_ORDER_HEADERS
407 WHERE order_id = l_order_relation.related_order_id;
408
409 IF (l_completion_date < p_date_from) OR
410 (l_completion_date > p_date_to) OR
411 (l_order_state <> 'SUCCESS') OR
412 (l_order_state <> 'SUCCESS_WITH_OVERRIDE') OR
413 (l_order_state <> 'CANCELED') OR
414 (l_order_state <> 'ABORTED')
415 THEN
416 RETURN; --return false
417 END IF;
418 END LOOP;
422 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512));
419 p_order_deletable :='TRUE';
420 EXCEPTION
421 WHEN OTHERS THEN
423 --SILENCE THE EXCEPTION, WILL NOT BE HANDLED
424 END IS_ORDER_DELETABLE;
425
426 -- Internal procedure for deleting fulfile worklist for a given line item
427 -- Name DELETE_FULFILL_WORKLIST
428
429 PROCEDURE DELETE_FULFILL_WORKLIST(
430 p_line_item_id IN XDP_ORDER_LINE_ITEMS.LINE_ITEM_ID%TYPE,
431 p_run_mode IN VARCHAR2
432 ) IS
433 CURSOR c_fulfill_worklist IS
434 SELECT WORKITEM_INSTANCE_ID FROM XDP_FULFILL_WORKLIST WHERE
435 line_item_id = p_line_item_id
436 FOR UPDATE NOWAIT;
437
438 CURSOR c_fulfill_action(p_workitem_instance_id XDP_FULFILL_WORKLIST.WORKITEM_INSTANCE_ID%TYPE) IS
439 SELECT FA_INSTANCE_ID FROM XDP_FA_RUNTIME_LIST
440 WHERE WORKITEM_INSTANCE_ID = p_workitem_instance_id
441 FOR UPDATE NOWAIT;
442
443 l_temp NUMBER := 0;
444 l_wi_counter NUMBER :=0;
445 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
446 BEGIN
447 IF(p_run_mode = 'PURGE') THEN
448 l_rec_name := 'XDP_PURGE_REC';
449 END IF;
450
451 FOR l_worklist IN c_fulfill_worklist LOOP
452 -- LOG PURGING INFORMATION
453 FOR l_fa IN c_fulfill_action(l_worklist.WORKITEM_INSTANCE_ID) LOOP
454 IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
455 SELECT COUNT(*) INTO l_temp FROM XDP_FA_DETAILS
456 WHERE FA_INSTANCE_ID = l_fa.FA_INSTANCE_ID;
457 RECORDS_PURGED_MSGS(l_temp,'XDP_FA_DETAILS WHERE FA_INSTANCE_ID = '
458 ||l_fa.FA_INSTANCE_ID,l_rec_name,1);
459
460 SELECT COUNT(*) INTO l_temp FROM XDP_FE_CMD_AUD_TRAILS
461 WHERE FA_INSTANCE_ID = l_fa.FA_INSTANCE_ID;
462 RECORDS_PURGED_MSGS(l_temp,'XDP_FE_CMD_AUD_TRAILS WHERE FA_INSTANCE_ID = '
463 ||l_fa.FA_INSTANCE_ID,l_rec_name,1);
464 END IF;
465
466 IF p_run_mode = 'PURGE' THEN
467 DELETE FROM XDP_FA_DETAILS WHERE FA_INSTANCE_ID = l_fa.FA_INSTANCE_ID;
468 DELETE FROM XDP_FE_CMD_AUD_TRAILS WHERE FA_INSTANCE_ID = l_fa.FA_INSTANCE_ID;
469 END IF;
470 END LOOP;
471
472 IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
473 SELECT COUNT(*) INTO l_temp FROM XDP_FMC_AUD_TRAIL_DETS
474 WHERE FMC_ID IN
475 (SELECT FMC_ID FROM XDP_FMC_AUDIT_TRAILS
476 WHERE WORKITEM_INSTANCE_ID
477 = l_worklist.WORKITEM_INSTANCE_ID);
478 RECORDS_PURGED_MSGS(l_temp ,'XDP_FE_CMD_AUD_TRAILS WHERE WORKITEM_INSTANCE_ID = '
479 ||l_worklist.WORKITEM_INSTANCE_ID,l_rec_name,1);
480
481 SELECT COUNT(*) INTO l_temp FROM XDP_FA_RUNTIME_LIST
482 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
483 RECORDS_PURGED_MSGS(l_temp, 'XDP_FA_RUNTIME_LIST WHERE WORKITEM_INSTANCE_ID = '
484 ||l_worklist.WORKITEM_INSTANCE_ID,l_rec_name,1);
485
486 SELECT COUNT(*) INTO l_temp FROM XDP_FMC_AUDIT_TRAILS
487 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
488 RECORDS_PURGED_MSGS(l_temp,'XDP_FMC_AUDIT_TRAILS WHERE WORKITEM_INSTANCE_ID = '
489 ||l_worklist.WORKITEM_INSTANCE_ID,l_rec_name,1);
490
491 SELECT COUNT(*) INTO l_temp FROM XDP_WI_RELATIONSHIPS
492 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
493 RECORDS_PURGED_MSGS(l_temp,'XDP_WI_RELATIONSHIPS WHERE WORKITEM_INSTANCE_ID = '
494 ||l_worklist.WORKITEM_INSTANCE_ID,l_rec_name,1);
495
496 SELECT COUNT(*) INTO l_temp FROM XDP_WORKLIST_DETAILS
497 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
498 RECORDS_PURGED_MSGS(l_temp,'XDP_WORKLIST_DETAILS WHERE WORKITEM_INSTANCE_ID = '
499 ||l_worklist.WORKITEM_INSTANCE_ID,l_rec_name,1);
500 END IF;
501 -- Purging if it is in run mode
502 IF p_run_mode = 'PURGE' THEN
503 DELETE FROM XDP_FMC_AUD_TRAIL_DETS
504 WHERE FMC_ID IN
505 (SELECT FMC_ID FROM XDP_FMC_AUDIT_TRAILS
506 WHERE WORKITEM_INSTANCE_ID
507 = l_worklist.WORKITEM_INSTANCE_ID);
508
509 DELETE FROM XDP_FA_RUNTIME_LIST
510 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
511
512 DELETE FROM XDP_FMC_AUDIT_TRAILS
513 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
514
515 DELETE FROM XDP_WI_RELATIONSHIPS
516 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
517
518 DELETE FROM XDP_WORKLIST_DETAILS
519 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
520
521 DELETE FROM XDP_FULFILL_WORKLIST
522 WHERE WORKITEM_INSTANCE_ID = l_worklist.WORKITEM_INSTANCE_ID;
523 END IF;
524
525 l_wi_counter := l_wi_counter+1;
526
527 END LOOP;
528 RECORDS_PURGED_MSGS(l_wi_counter,'XDP_FULFILL_WORKLIST WHERE LINE_ITEM_ID = '
529 ||p_line_item_id,l_rec_name,0);
530 EXCEPTION
531 WHEN OTHERS THEN
532 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512),P_ABORT => TRUE);
533
534 END DELETE_FULFILL_WORKLIST;
535
536 -- Internal procedure for deleting line items for an order
537 -- Name DELETE_LINE_ITEMS
538 --
539
540 PROCEDURE DELETE_LINE_ITEMS
541 (
542 p_order_id IN XDP_ORDER_HEADERS.ORDER_ID%TYPE,
543 p_run_mode IN VARCHAR2
544 ) IS
545
546 CURSOR c_line_item IS
547 SELECT LINE_ITEM_ID
548 FROM XDP_ORDER_LINE_ITEMS
549 WHERE order_id = p_order_id
553 l_li_number NUMBER := 0;
550 FOR UPDATE OF LINE_ITEM_ID NOWAIT;
551
552 l_temp NUMBER := 0;
554 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
555
556 BEGIN
557 IF(p_run_mode = 'PURGE') THEN
558 l_rec_name := 'XDP_PURGE_REC';
559 END IF;
560
561 FOR l_line_item IN c_line_item LOOP
562 Delete_Fulfill_Worklist(l_line_item.line_item_id,p_run_mode);
563 IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
564
565 SELECT COUNT(*)
566 INTO l_temp
567 FROM XDP_ORDER_LINEITEM_DETS
568 WHERE line_item_id = l_line_item.line_item_id;
569
570 RECORDS_PURGED_MSGS(l_temp, 'XDP_ORDER_LINEITEM_DETS WHERE LINE_ITEM_ID = '
571 ||l_line_item.line_item_id,l_rec_name,1);
572
573 SELECT COUNT(*)
574 INTO l_temp
575 FROM XDP_LINE_RELATIONSHIPS
576 WHERE line_item_id = l_line_item.line_item_id;
577
578 RECORDS_PURGED_MSGS(l_temp,'XDP_LINE_RELATIONSHIPS WHERE LINE_ITEM_ID = '
579 ||l_line_item.line_item_id,l_rec_name,1);
580 END IF;
581
582 IF p_run_mode = 'PURGE' THEN
583
584 DELETE FROM XDP_ORDER_LINEITEM_DETS
585 WHERE line_item_id = l_line_item.line_item_id;
586
587 DELETE FROM XDP_LINE_RELATIONSHIPS
588 WHERE line_item_id = l_line_item.line_item_id;
589
590 DELETE FROM XDP_ORDER_LINE_ITEMS WHERE CURRENT OF c_line_item;
591 END IF;
592 l_li_number := l_li_number+1;
593 END LOOP;
594 RECORDS_PURGED_MSGS(l_li_number,'XDP_ORDER_LINE_ITEMS WHERE ORDER_ID = '
595 ||p_order_id,l_rec_name,0);
596 EXCEPTION
597 WHEN OTHERS THEN
598 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512),P_ABORT => TRUE);
599 END DELETE_LINE_ITEMS;
600
601 --
602 -- Internal procedure for deleting workflow items for an order
603 -- Name DELETE_WF_ITEMS
604 --
605 -- This procedure will purge all workflow items that are connected to
606 -- the work item defined by the
607 -- WF_ITEM_TYPE AND WF_ITEM_KEY
608 -- in XDP_ORDER_HEADER table where order_id = p_order_id
609 --
610 -- A cursor is defined against WF_ITEMS table using connect by statement
611 --
612 -- Code reviewers:
613 -- would this risk of purging work items that are not belong to XDP????
614 --
615 PROCEDURE DELETE_WF_ITEMS
616 (
617 p_order_id IN VARCHAR2,
618 p_run_mode IN VARCHAR2
619 ) IS
620 CURSOR c_wi(p_wi_type IN VARCHAR2,p_wi_key IN VARCHAR2) IS
621 SELECT level,item_type,item_key
622 FROM WF_ITEMS
623 START WITH item_type = p_wi_type
624 AND item_key = p_wi_key
625 CONNECT BY PRIOR item_key = parent_item_key
626 AND PRIOR item_type = parent_item_type;
627
628 l_wi_type XDP_ORDER_HEADERS.WF_ITEM_TYPE%TYPE;
629 l_wi_key XDP_ORDER_HEADERS.WF_ITEM_KEY%TYPE;
630 l_counter NUMBER := 0;
631 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
632 l_wi_name VARCHAR2(16) := 'XDP_FOUND_WI';
633
634 l_PType VARCHAR2(8);
635
636 l_mini_secs NUMBER := 0;
637
638 BEGIN
639 -- DO NOTHING IS FLAG IS FALSE
640 IF (G_PURGE_WORK_FLOW = 'FALSE') THEN
641 RETURN;
642 END IF;
643
644 IF(p_run_mode = 'PURGE') THEN
645 l_rec_name := 'XDP_PURGE_REC';
646 l_wi_name := 'XDP_PURGE_WI';
647 END IF;
648
649 IF p_order_id IS NULL THEN
650 RETURN;
651 END IF;
652
653 l_mini_secs := DBMS_UTILITY.get_time;
654
655 SELECT wf_item_type,
656 wf_item_key
657 INTO l_wi_type,l_wi_key
658 FROM XDP_ORDER_HEADERS
659 WHERE ORDER_ID = p_order_id;
660
661 IF SQL%NOTFOUND THEN
662 RETURN;
663 END IF;
664
665 -- Purge all work items assocaited with an order
666 FOR l_wi in c_wi(l_wi_type,l_wi_key) LOOP
667
668 IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
669 RECORDS_PURGED_MSGS(1, 'WORKFLOW ITEM = '
670 ||l_wi.item_type || l_wi.item_key,1);
671 END IF;
672
673 IF (p_run_mode = 'PURGE') AND (l_wi.item_key IS NOT NULL) THEN
674 SELECT persistence_type INTO l_PType
675 FROM wf_item_types
676 WHERE NAME = l_wi.item_type;
677
678 IF SQL%NOTFOUND THEN
679 RETURN; -- DO NOTHING
680 END IF;
681
682 wf_purge.persistence_type := l_PType;
683 WF_PURGE.TOTAL(l_wi.item_type, l_wi.item_key, SYSDATE,FALSE);
684 NULL;
685 END IF;
686 l_counter := l_counter + 1;
687 END LOOP;
688 RECORDS_PURGED_MSGS(l_counter, 'WF_ITEMS WHERE ORDER_ID = '
689 ||p_order_id,l_rec_name,0);
690 G_Total_WK_TIME := G_Total_WK_TIME + DBMS_UTILITY.get_time - l_mini_secs;
691 EXCEPTION
692 WHEN OTHERS THEN
693 PURGE_ERRORS(P_MSG=>SUBSTR(SQLERRM, 1, 512),P_ABORT => TRUE);
694 END DELETE_WF_ITEMS;
695
696 -- Procedure XDP_PURGE_ORDER
697 -- Purge order for a given id
698 --
699 -- IN:
700 -- p_order_id - order id to be purged
701 -- p_time_from - date from which data is purged
702 -- p_time_to - date to which data is purged
703 -- p_run_mode - specify run mode when this API is called.--
704 -- - 'PURGE', to purge data
708 -- - in the database should be purged or not
705 -- - 'VERIFY', to verify setting and print out data will be purged
706 -- - 'CHECK', to check transactional data in the database
707 -- p_order_purge_mode - indicate if messages whose orders still exist
709 -- x_purge_status - indicate if purge is success or not,
710 -- - SUCCESS the order is or to be purged
711 -- - FAIL the order is not , or not to be purged
712 -- - EXCEPTION Exception occured while purge this order
713 -- -
714
715 PROCEDURE XDP_PURGE_ORDER
716 (
717 p_order_id IN NUMBER,
718 p_time_from IN DATE,
719 p_time_to IN DATE,
720 p_run_mode IN VARCHAR2 DEFAULT 'VERIFY',
721 p_purge_msg IN BOOLEAN DEFAULT FALSE,
722 x_purge_status OUT NOCOPY VARCHAR2
723 ) IS
724 -- it might be a good idea to make this autonomous
725 -- so that it will share no rollback segment with the main
726 -- transaction context, hence, no persistent view
727 -- PRAGMA AUTONOMOUS_TRANSACTION
728 l_temp NUMBER := 0;
729 l_order_deletable VARCHAR2(6);
730 l_exception_counter NUMBER := 0;
731 l_user_rollback BOOLEAN := FALSE;
732 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
733 l_dummy number;
734
735 BEGIN
736 SavePoint Order_Rollback;
737 --
738 -- to be sure that the order can be deleted
739 -- On exceptions, FALSE will be returned, a message will be logged
740 -- and committed to database
741 --
742 IS_ORDER_DELETABLE(p_order_id,p_time_from,p_time_to,l_order_deletable);
743
744 IF p_run_mode ='CHECK' THEN
745 IF l_order_deletable = 'TRUE' THEN
746 XDP_CHECK_ORDER(p_order_id);
747 END IF;
748 ELSE
749
750 --
751 -- To delete the order
752 -- On exceptions, a message will be logged and committed to database
753 -- carries on to next order
754 --
755 IF l_order_deletable = 'TRUE' THEN
756 BEGIN
757
758 -- Lock the record for update
759
760 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ORD');
761 FND_MESSAGE.SET_TOKEN('ORDER_ID',p_order_id);
762 PURGE_ERRORS(FND_MESSAGE.GET);
763
764 SELECT 1 INTO l_dummy FROM XDP_ORDER_HEADERS
765 WHERE order_id = p_order_id for update nowait;
766
767 DELETE_LINE_ITEMS(p_order_id,p_run_mode);
768 DELETE_WF_ITEMS(p_order_id,p_run_mode);
769
770 IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
771 SELECT COUNT(*) INTO l_temp FROM XDP_ORDER_BUNDLES
772 WHERE order_id = p_order_id;
773
774 RECORDS_PURGED_MSGS(l_temp,'XDP_ORDER_BUNDLES WHERE ORDER_ID = '
775 ||p_order_id,l_rec_name,0);
776 SELECT COUNT(*) INTO l_temp FROM XDP_ORDER_RELATIONSHIPS
777 WHERE order_id = p_order_id;
778 RECORDS_PURGED_MSGS(l_temp,'XDP_ORDER_RELATIONSHIPS WHERE ORDER_ID = '
779 ||p_order_id,l_rec_name,0);
780 SELECT COUNT(*) INTO l_temp FROM XDP_ORDER_PARAMETERS
781 WHERE order_id = p_order_id;
782 RECORDS_PURGED_MSGS(l_temp,'XDP_ORDER_PARAMETERS WHERE ORDER_ID = '
783 ||p_order_id,l_rec_name,0);
784
785 -- If p_purge_msg is true, purge both internal and external
786 -- messages associated with the order
787 -- else, only purge internal messages which are identified
788 -- the the protected flag in xnp_msg_type_b
789
790 IF p_purge_msg THEN
791 SELECT COUNT(*) INTO l_temp FROM XNP_MSGS
792 WHERE order_id = p_order_id;
793 ELSE
794 SELECT COUNT(*) INTO l_temp FROM XNP_MSGS
795 WHERE order_id = p_order_id
796 AND msg_code IN
797 (SELECT MSG_CODE FROM XNP_MSG_TYPES_B
798 WHERE PROTECTED_FLAG='Y');
799 END IF;
800
801 RECORDS_PURGED_MSGS(l_temp,'XNP_MSGS WHERE ORDER_ID = '||p_order_id
802 ,l_rec_name,0);
803 SELECT COUNT(*) INTO l_temp FROM XNP_CALLBACK_EVENTS
804 WHERE order_id = p_order_id;
805 RECORDS_PURGED_MSGS(l_temp,'XNP_CALLBACK_EVENTS WHERE ORDER_ID = '
806 ||p_order_id ,l_rec_name,0);
807 SELECT COUNT(*) INTO l_temp FROM XNP_TIMER_REGISTRY
808 WHERE order_id = p_order_id;
809 RECORDS_PURGED_MSGS(l_temp,'XNP_TIMER_REGISTRY WHERE ORDER_ID = '
810 ||p_order_id ,l_rec_name,0);
811 SELECT COUNT(*) INTO l_temp FROM XNP_SYNC_REGISTRATION
812 WHERE order_id = p_order_id;
813 RECORDS_PURGED_MSGS(l_temp,'XNP_SYNC_REGISTRATION WHERE ORDER_ID = '
814 ||p_order_id ,l_rec_name,0);
815 END IF;
816
817 IF p_run_mode = 'PURGE' THEN
818 DELETE FROM XDP_ORDER_BUNDLES
819 WHERE order_id = p_order_id;
820 DELETE FROM XDP_ORDER_RELATIONSHIPS
821 WHERE order_id = p_order_id;
822 DELETE FROM XDP_ORDER_PARAMETERS
823 WHERE order_id = p_order_id;
824 --
825 -- if this flag is true, we will delete all messages associated with this order
829 IF p_purge_msg THEN
826 -- else we will only delete internal messages that are associated with this order
827 -- This operation will not delete any messages whose order id field is null.
828 --
830 DELETE FROM XNP_MSGS
831 WHERE order_id = p_order_id;
832 ELSE
833 DELETE FROM XNP_MSGS
834 WHERE order_id = p_order_id
835 AND msg_code IN
836 (SELECT MSG_CODE FROM XNP_MSG_TYPES_B
837 WHERE PROTECTED_FLAG='Y');
838 END IF;
839
840 DELETE FROM XNP_CALLBACK_EVENTS
841 WHERE order_id = p_order_id;
842
843 DELETE FROM XNP_TIMER_REGISTRY
844 WHERE order_id = p_order_id;
845 DELETE FROM XNP_SYNC_REGISTRATION
846 WHERE order_id = p_order_id ;
847 DELETE FROM XDP_ORDER_HEADERS
848 WHERE order_id = p_order_id ;
849 -- COMMIT;
850 END IF;
851 EXCEPTION
852 WHEN OTHERS THEN
853 ROLLBACK TO Order_Rollback;
854 x_purge_status := 'EXCEPTION';
855 END;
856 END IF;
857 END IF ;
858
859 IF l_order_deletable = 'TRUE' THEN
860 x_purge_status := 'SUCCESS';
861 ELSE
862 x_purge_status := 'FAIL';
863 END IF;
864
865 EXCEPTION
866 WHEN OTHERS THEN
867 ROLLBACK TO Order_Rollback;
868 x_purge_status := 'EXCEPTION';
869 x_purge_status := 'FAIL';
870 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
871 FND_MESSAGE.SET_TOKEN('OBJECT','ORDER');
872 FND_MESSAGE.SET_TOKEN('CONDITION','');
873 PURGE_ERRORS(FND_MESSAGE.GET);
874 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512));
875 END XDP_PURGE_ORDER;
876
877 PROCEDURE XDP_PURGE_ORDERS
878 (
879 p_time_from IN DATE,
880 p_time_to IN DATE,
881 p_run_mode IN VARCHAR2 DEFAULT 'VERIFY',
882 p_purge_msg IN BOOLEAN DEFAULT FALSE,
883 p_rollback_segment IN VARCHAR2 DEFAULT NULL,
884 x_orders_purged OUT NOCOPY NUMBER
885 ) IS
886
887 --Date: 09 AUG 2006 Author: DPUTHIYE Bug #:5446335
888 --This SQL should consider CANCEL_PROVISIONING_DATE for cancelled orders as well.
889 --Dependencies: None.
890 /* CURSOR c_order(p_time_from IN DATE,p_time_to IN DATE) IS
891 SELECT ORDER_ID FROM XDP_ORDER_HEADERS
892 WHERE STATUS_CODE IN ('SUCCESS','SUCCESS_WITH_OVERRIDE','ABORTED','CANCELED')
893 AND COMPLETION_DATE < p_time_to
894 AND COMPLETION_DATE > p_time_from; */
895
896 CURSOR c_order(p_time_from IN DATE,p_time_to IN DATE) IS
897 SELECT ORDER_ID FROM XDP_ORDER_HEADERS
898 WHERE STATUS_CODE IN ('SUCCESS','SUCCESS_WITH_OVERRIDE','ABORTED','CANCELED')
899 AND NVL(COMPLETION_DATE, CANCEL_PROVISIONING_DATE) < p_time_to
900 AND NVL(COMPLETION_DATE, CANCEL_PROVISIONING_DATE) > p_time_from;
901
902 l_temp NUMBER := 0;
903
904 l_order_id XDP_ORDER_HEADERS.ORDER_ID%TYPE;
905
906 l_order_deletable VARCHAR2(6);
907 l_exception_counter NUMBER := 0;
908 l_user_rollback BOOLEAN := FALSE;
909 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
910
911 l_purge_status VARCHAR2(20);
912 l_counter NUMBER := 0;
913 --l_dummy NUMBER;
914 l_mini_secs NUMBER :=0;
915 BEGIN
916 PURGE_ERRORS('==== '||p_run_mode|| ' ORDERS ' ||' ===================');
917 IF(p_run_mode = 'PURGE') THEN
918 l_rec_name := 'XDP_PURGE_REC';
919 END IF;
920
921 IF p_run_mode ='CHECK' THEN
922 --Date: 09 AUG 2006 Author: DPUTHIYE Bug #:5446335
923 --This SQL should consider CANCEL_PROVISIONING_DATE for cancelled orders as well.
924 --Dependencies: None.
925 /* SELECT COUNT(*) INTO l_temp FROM XDP_ORDER_HEADERS
926 WHERE STATUS_CODE IN ('SUCCESS','SUCCESS_WITH_OVERRIDE','ABORTED','CANCELED')
927 AND COMPLETION_DATE < p_time_to
928 AND COMPLETION_DATE > p_time_from; */
929
930 SELECT COUNT(*) INTO l_temp FROM XDP_ORDER_HEADERS
931 WHERE STATUS_CODE IN ('SUCCESS','SUCCESS_WITH_OVERRIDE','ABORTED','CANCELED')
932 AND NVL(COMPLETION_DATE, CANCEL_PROVISIONING_DATE) < p_time_to
933 AND NVL(COMPLETION_DATE, CANCEL_PROVISIONING_DATE) > p_time_from;
934
935 IF l_temp = 0 THEN
936 XDP_CHECK_ORDER(NULL);
937 END IF;
938 END IF;
939
940 -- l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
941
942 l_mini_secs := DBMS_UTILITY.get_time;
943 G_Total_WK_TIME := 0;
944 x_orders_purged :=0;
945 --
946 -- This loop is introduced so that when it is to purge orders,
947 -- we will close the select cursor after certain number of
948 -- deletions. The purpose of this method is to minize the impact of
949 -- the size of a rollback segment. Although c_order cursor is read only,
950 -- in order to maintain a persistent view, Oracle reads from rollback segment
951 -- if a block has been changed as the cursor is open.
952 --
953 <<OUTER_LOOP>>
954 LOOP
955 -- REOPEN IT AFTER COMMIT
956 l_counter := 0;
957
958 OPEN c_order(p_time_from,p_time_to);
959 <<INNER_LOOP>>
960 LOOP
961 -- open/reopen the cursor
962 FETCH c_order INTO l_order_id;
963
964 IF c_order%notfound THEN
965 EXIT OUTER_LOOP;
966 END IF;
967
968 XDP_PURGE_ORDER(
972 p_run_mode,
969 l_order_id,
970 p_time_from,
971 p_time_to,
973 p_purge_msg,
974 l_purge_status
975 );
976
977 IF l_purge_status = 'SUCCESS' THEN
978 x_orders_purged := x_orders_purged + 1;
979 -- Reset exception counter
980 l_exception_counter := 0;
981 ELSIF l_purge_status = 'EXCEPTION' THEN
982 l_exception_counter := l_exception_counter + 1;
983 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
984 FND_MESSAGE.SET_TOKEN('OBJECT','ORDER');
985 FND_MESSAGE.SET_TOKEN('CONDITION','order_id ='|| l_order_id);
986 PURGE_ERRORS(FND_MESSAGE.GET);
987 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512));
988
989 -- if exceptions continusly occurred for more than gl_max_exception
990 -- then bubble up the exception and get out
991 IF (l_exception_counter > g_max_exceptions) THEN
992 PURGE_ERRORS(FND_MESSAGE.GET,p_abort=>TRUE);
993 END IF;
994 END IF;
995
996 -- This only applies when it is to purge, where deletions have occured
997 IF (l_counter > g_max_rows_before_commit) AND (p_run_mode = 'PURGE') THEN
998 PURGE_ERRORS(l_counter || ' orders purged, will reopen the order cursor');
999 -- Reset counter and jump out the inner loop
1000 l_counter := 0;
1001 COMMIT;
1002 EXIT INNER_LOOP;
1003 END IF;
1004 l_counter := l_counter+1;
1005 END LOOP INNER_LOOP;
1006
1007 -- if the cursor is open at this pointer, close it
1008 IF (c_order%ISOPEN) THEN
1009 CLOSE c_order;
1010 END IF;
1011 END LOOP OUTER_LOOP;
1012 RECORDS_PURGED_MSGS(x_orders_purged,'XDP_ORDER_HEADERS',l_rec_name,-1);
1013 l_mini_secs := DBMS_UTILITY.get_time - l_mini_secs;
1014 PURGE_ERRORS('Total '||l_mini_secs/100 || ' seconds used to purge orders');
1015 PURGE_ERRORS((G_Total_WK_TIME/100) || ' seconds used to purge workflow items for these orders');
1016 COMMIT;
1017 EXCEPTION
1018 WHEN OTHERS THEN
1019 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1020 FND_MESSAGE.SET_TOKEN('OBJECT','ORDER');
1021 FND_MESSAGE.SET_TOKEN('CONDITION','');
1022
1023 PURGE_ERRORS(FND_MESSAGE.GET,P_COMMIT => TRUE);
1024 PURGE_ERRORS(SUBSTR(SQLERRM, 1, 512));
1025 RAISE;
1026 END XDP_PURGE_ORDERS;
1027 --
1028 -- Procedure XDP_PRUGE_TIMER
1029 -- Purge runtime timers for a given message
1030 -- timers associated with orders are purged with orders
1031 --
1032 PROCEDURE XDP_PRUGE_TIMER(p_msg_id IN NUMBER) IS
1033 BEGIN
1034 DELETE FROM xnp_timer_registry WHERE timer_id = p_msg_id;
1035 END XDP_PRUGE_TIMER;
1036
1037 -- Procedure XDP_PURGE_MESSAGES
1038 -- Purge runtime messages from SFM
1039 --
1040 -- IN:
1041 -- p_time_from - date from which data is purged
1042 -- p_time_to - date to which data is purged
1043 -- p_run_mode - specify run mode when this API is called.--
1044 -- - 'PURGE', to purge data
1045 -- - 'VERIFY', to verify setting and print out data will be purged
1046 -- - 'CHECK', to check transactional data in the database
1047 -- p_order_purge_mode - indicate if messages whose orders still exist
1048 -- - in the database should be purged or not
1049
1050 -- The assumption here is that
1051 PROCEDURE XDP_PURGE_MESSAGES
1052 (
1053 p_time_from IN DATE,
1054 p_time_to IN DATE,
1055 p_run_mode IN VARCHAR2 DEFAULT 'PURGE',
1056 p_order_purge_mode IN BOOLEAN DEFAULT FALSE,
1057 p_rollback_segment IN VARCHAR2 DEFAULT NULL
1058 ) IS
1059
1060 -- delete all messages that are not associated with an order
1061 -- 03/30/2001. Modified. Replaced CREATION_DATE with MSG_CREATION_DATE. rnyberg
1062 CURSOR c_xnp_msgs_1 IS
1063 SELECT MSG_ID FROM XNP_MSGS M
1064 WHERE
1065 (M.MSG_STATUS IN ('PROCESSED','TIME_OUT'))
1066 AND MSG_CREATION_DATE < p_time_to
1067 AND MSG_CREATION_DATE > p_time_from
1068 FOR UPDATE OF MSG_ID NOWAIT;
1069
1070 -- 03/30/2001. Modified. Replaced CREATION_DATE with MSG_CREATION_DATE. rnyberg
1071 CURSOR c_xnp_msgs_2 IS
1072 SELECT MSG_ID FROM XNP_MSGS M
1073 WHERE
1074 (M.MSG_STATUS IN ('PROCESSED','TIME_OUT'))
1075 AND MSG_CREATION_DATE < p_time_to
1076 AND MSG_CREATION_DATE > p_time_from
1077 AND NOT Exists (SELECT ORDER_ID from xdp_order_headers where (order_id=m.order_id))
1078 FOR UPDATE OF MSG_ID NOWAIT;
1079
1080 l_xnp_msg XNP_MSGS.MSG_ID%TYPE;
1081
1082 l_counter NUMBER := 0;
1083 l_no_msgs NUMBER := 0;
1084 l_temp NUMBER := 0;
1085 l_user_rollback BOOLEAN := TRUE;
1086
1087 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
1088
1089 BEGIN
1090 PURGE_ERRORS('==== '||p_run_mode|| ' Messages ' ||' ===================');
1091 IF(p_run_mode = 'CHECK') THEN
1092 IF(P_ORDER_PURGE_MODE) THEN
1093 -- 03/30/2001. Modified. Replaced CREATION_DATE with MSG_CREATION_DATE. rnyberg
1094 SELECT COUNT(*) INTO l_no_msgs FROM XNP_MSGS
1095 WHERE
1096 MSG_STATUS IN ('PROCESSED','TIME_OUT')
1097 AND MSG_CREATION_DATE < p_time_to
1098 AND MSG_CREATION_DATE > p_time_from;
1099 ELSE
1100 SELECT COUNT(*) INTO l_no_msgs FROM XNP_MSGS M
1101 WHERE
1105 AND MSG_CREATION_DATE > p_time_from
1102 -- 03/30/2001. Modified. Replaced CREATION_DATE with MSG_CREATION_DATE. rnyberg
1103 MSG_STATUS IN ('PROCESSED','TIME_OUT')
1104 AND MSG_CREATION_DATE < p_time_to
1106 AND NOT Exists (SELECT ORDER_ID from xdp_order_headers where (order_id=m.order_id));
1107 END IF;
1108 RECORDS_PURGED_MSGS(l_no_msgs,'XNP_MSGS',l_rec_name,-1);
1109 RETURN;
1110 END IF;
1111
1112 IF(p_run_mode = 'PURGE') THEN
1113 l_rec_name := 'XDP_PURGE_REC';
1114 END IF;
1115
1116 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1117 -- purge messages that are not associated with an order
1118 l_counter := 0;
1119 <<OUTER_XNP_MSG>>
1120 LOOP
1121 SAVEPOINT MSG_RLBK;
1122 -- REOPEN IT AFTER COMMIT
1123 IF(P_ORDER_PURGE_MODE) THEN
1124 OPEN c_xnp_msgs_1;
1125 ELSE
1126 OPEN c_xnp_msgs_2;
1127 END IF;
1128 <<INNER_XNP_MSG>>
1129 LOOP
1130 IF(P_ORDER_PURGE_MODE) THEN
1131 FETCH c_xnp_msgs_1 INTO l_xnp_msg;
1132 IF c_xnp_msgs_1%notfound THEN
1133 EXIT OUTER_XNP_MSG; -- we are done
1134 END IF;
1135
1136 IF p_run_mode = 'PURGE' THEN
1137 XDP_PRUGE_TIMER(l_xnp_msg);
1138
1139 DELETE FROM XNP_MSGS WHERE CURRENT OF c_xnp_msgs_1;
1140 END IF;
1141 ELSE
1142 FETCH c_xnp_msgs_2 INTO l_xnp_msg;
1143 IF c_xnp_msgs_2%notfound THEN
1144 EXIT OUTER_XNP_MSG; -- we are done
1145 END IF;
1146
1147 IF p_run_mode = 'PURGE' THEN
1148 XDP_PRUGE_TIMER(l_xnp_msg);
1149 --
1150 DELETE FROM XNP_MSGS WHERE CURRENT OF c_xnp_msgs_2;
1151 END IF;
1152 END IF;
1153
1154 l_no_msgs := l_no_msgs + 1;
1155 l_counter := l_counter+1;
1156
1157 IF (l_counter > g_max_rows_before_commit) AND (NOT l_user_rollback) AND (p_run_mode = 'PURGE') THEN
1158 l_counter := 0;
1159 COMMIT;
1160 EXIT INNER_XNP_MSG; -- commit and reopen the cursor
1161 END IF;
1162
1163 END LOOP INNER_XNP_MSG;
1164
1165 IF(P_ORDER_PURGE_MODE) THEN
1166 IF (c_xnp_msgs_1%ISOPEN) THEN
1167 CLOSE c_xnp_msgs_1;
1168 END IF;
1169 ELSE
1170 IF (c_xnp_msgs_2%ISOPEN) THEN
1171 CLOSE c_xnp_msgs_2;
1172 END IF;
1173 END IF;
1174 END LOOP OUTER_XNP_MSG;
1175
1176 COMMIT;
1177 RECORDS_PURGED_MSGS(l_no_msgs,'XNP_MSGS',l_rec_name,-1);
1178 EXCEPTION
1179 WHEN OTHERS THEN
1180 ROLLBACK TO MSG_RLBK;
1181 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1182 FND_MESSAGE.SET_TOKEN('OBJECT','MESSAGES');
1183 FND_MESSAGE.SET_TOKEN('CONDITION',SQLERRM);
1184 PURGE_ERRORS(FND_MESSAGE.GET,P_COMMIT => TRUE);
1185 RAISE;
1186 END XDP_PURGE_MESSAGES;
1187
1188 -- Procedure XDP_PURGE_SOA
1189 -- Purge soa data from SFM
1190 --
1191 -- IN:
1192 -- p_time_from - date from which data is purged
1193 -- p_time_to - date to which data is purged
1194 -- p_run_mode - specify run mode when this API is called.--
1195 -- - 'PURGE', to purge data
1196 -- - 'VERIFY', to verify setting and print out data will be purged
1197 -- - 'CHECK', to check transactional data in the database
1198
1199 PROCEDURE XDP_PURGE_SOA
1200 (
1201 p_time_from IN DATE,
1202 p_time_to IN DATE,
1203 p_run_mode IN VARCHAR2 DEFAULT 'VERIFY',
1204 p_rollback_segment IN VARCHAR2 DEFAULT NULL
1205 ) IS
1206 CURSOR c_xnp_soa(p_time_from IN DATE,p_time_to IN DATE) IS
1207 SELECT SV_SOA_ID FROM XNP_SV_SOA A, XNP_SV_STATUS_TYPES_B B
1208 WHERE a.STATUS_TYPE_CODE = b.STATUS_TYPE_CODE
1209 AND b.PHASE_INDICATOR ='OLD'
1210 AND a.MODIFIED_DATE < p_time_to
1211 AND a.MODIFIED_DATE > p_time_from FOR UPDATE OF A.SV_SOA_ID NOWAIT;
1212
1213 l_xnp_soa_id XNP_SV_SOA.SV_SOA_ID%TYPE;
1214 l_counter NUMBER := 0;
1215 l_no_msgs NUMBER := 0;
1216 l_temp NUMBER := 0;
1217 l_user_rollback BOOLEAN := TRUE;
1218 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
1219 BEGIN
1220 SAVEPOINT SOA_RBKS;
1221
1222 PURGE_ERRORS('==== '||p_run_mode|| ' SOA ' ||' ===================');
1223
1224 IF(p_run_mode = 'PURGE') THEN
1225 l_rec_name := 'XDP_PURGE_REC';
1226 END IF;
1227 IF(p_run_mode = 'PURGE') THEN
1228 l_rec_name := 'XDP_PURGE_REC';
1229 END IF;
1230
1231 IF p_run_mode ='CHECK' THEN
1232 SELECT COUNT(*) INTO l_temp FROM XNP_SV_SOA A, XNP_SV_STATUS_TYPES_B B
1233 WHERE a.STATUS_TYPE_CODE = b.STATUS_TYPE_CODE
1234 AND b.PHASE_INDICATOR ='OLD'
1235 AND a.MODIFIED_DATE < p_time_to
1236 AND a.MODIFIED_DATE > p_time_from;
1237
1238 IF l_temp = 0 THEN
1239 XDP_CHECK_SOA(NULL,p_time_from,p_time_to);
1240 RECORDS_PURGED_MSGS(l_temp,'XNP_SV_SOA',l_rec_name,0);
1241 RETURN;
1242 END IF;
1243 END IF;
1244
1245 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1246
1247 FOR l_xnp_soa in c_xnp_soa(p_time_from,p_time_to) LOOP
1248 PURGE_ERRORS('==== '||p_run_mode||' SOA '||l_xnp_soa.sv_soa_id ||' ===================');
1249 IF p_run_mode = 'CHECK' THEN
1250 XDP_CHECK_SOA(l_xnp_soa.sv_soa_id);
1254 RECORDS_PURGED_MSGS(l_temp,'XNP_SV_EVENT_HISTORY WHERE SV_SOA_ID ='
1251 ELSE IF ((bAudit = 'TRUE') AND (p_run_mode = 'PURGE')) or (p_run_mode = 'VERIFY') THEN
1252 SELECT COUNT(*) INTO l_temp FROM XNP_SV_EVENT_HISTORY
1253 WHERE SV_SOA_ID = l_xnp_soa.sv_soa_id;
1255 ||l_xnp_soa.sv_soa_id,l_rec_name,0);
1256 SELECT COUNT(*) INTO l_temp FROM XNP_SV_FAILURES
1257 WHERE SV_SOA_ID = l_xnp_soa.sv_soa_id;
1258 RECORDS_PURGED_MSGS(l_temp,'XNP_SV_FAILURES WHERE SV_SOA_ID ='
1259 ||l_xnp_soa.sv_soa_id,l_rec_name,0);
1260 SELECT COUNT(*) INTO l_temp FROM XNP_SV_SOA_JN
1261 WHERE SV_SOA_ID = l_xnp_soa.sv_soa_id;
1262 RECORDS_PURGED_MSGS(l_temp,'XNP_SV_SOA_JN WHERE SV_SOA_ID ='
1263 ||l_xnp_soa.sv_soa_id,l_rec_name,0);
1264 END IF;
1265 END IF;
1266 END LOOP;
1267
1268 l_counter := 0;
1269 IF p_run_mode = 'PURGE' THEN
1270 <<OUTER_XNP_SOA>>
1271 LOOP
1272 -- REOPEN IT AFTER COMMIT
1273 SAVEPOINT SOA_RBKS;
1274 BEGIN
1275 OPEN c_xnp_soa(p_time_from,p_time_to);
1276 <<INNER_XNP_SOA>>
1277 LOOP
1278 FETCH c_xnp_soa INTO l_xnp_soa_id;
1279 -- IF NO DATA FOUND, THEN EXIT
1280 IF c_xnp_soa%notfound THEN
1281 EXIT OUTER_XNP_SOA; -- we are done
1282 END IF;
1283
1284 DELETE FROM XNP_SV_EVENT_HISTORY WHERE
1285 SV_SOA_ID = l_xnp_soa_id;
1286 DELETE FROM XNP_SV_FAILURES WHERE
1287 SV_SOA_ID = l_xnp_soa_id;
1288 DELETE FROM XNP_SV_SOA_JN WHERE
1289 SV_SOA_ID = l_xnp_soa_id;
1290 DELETE FROM XNP_SV_SOA WHERE CURRENT OF c_xnp_soa;
1291 l_no_msgs := l_no_msgs +1;
1292 l_counter := l_counter+1;
1293 IF (l_counter > g_max_rows_before_commit) AND (NOT l_user_rollback) THEN
1294 l_counter := 0;
1295 COMMIT;
1296 EXIT INNER_XNP_SOA; -- commit and reopen the cursor
1297 END IF;
1298 END LOOP INNER_XNP_SOA;
1299 IF (c_xnp_soa%ISOPEN) THEN
1300 CLOSE c_xnp_soa;
1301 END IF;
1302 EXCEPTION
1303 WHEN OTHERS THEN
1304 ROLLBACK TO SOA_RBKS;
1305 END;
1306 END LOOP OUTER_XNP_SOA;
1307 END IF;
1308 COMMIT;
1309
1310 RECORDS_PURGED_MSGS(l_no_msgs,'XNP_SV_SOA',l_rec_name,-1);
1311
1312 COMMIT;
1313 EXCEPTION
1314 WHEN OTHERS THEN
1315 ROLLBACK;
1316 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1317 FND_MESSAGE.SET_TOKEN('OBJECT','SOA');
1318 FND_MESSAGE.SET_TOKEN('CONDITION','');
1319 PURGE_ERRORS(FND_MESSAGE.GET,P_COMMIT => TRUE);
1320 RAISE;
1321 END XDP_PURGE_SOA;
1322
1323 -- Procedure XDP_PURGE_MISC
1324 -- Purge debug, exception and misc workflow data from SFM
1325 --
1326 -- IN:
1327 -- p_time_from - date from which data is purged
1328 -- p_time_to - date to which data is purged
1329 -- p_run_mode - specify run mode when this API is called.
1330 -- -for 'TRUE', the program will purge data
1331 -- - for any other text, the program will only test
1332 -- - the purge and log affected data into log files.
1333 -- - if not specified, the program will purge data
1334
1335 PROCEDURE XDP_PURGE_MISC
1336 (
1337 p_time_from IN DATE,
1338 p_time_to IN DATE,
1339 p_run_mode IN VARCHAR2 DEFAULT 'VERIFY',
1340 p_rollback_segment IN VARCHAR2 DEFAULT NULL
1341 ) IS
1342
1343 CURSOR c_xdp_debug(p_time_from IN DATE,p_time_to IN DATE) IS
1344 SELECT DEBUG_TYPE FROM XDP_DEBUG
1345 WHERE LAST_UPDATE_DATE < p_time_to
1346 AND LAST_UPDATE_DATE > p_time_from FOR UPDATE OF DEBUG_TYPE NOWAIT;
1347
1348 CURSOR c_xdp_errors(p_time_from IN DATE,p_time_to IN DATE) IS
1349 SELECT ERROR_ID FROM XDP_ERROR_LOG
1350 WHERE LAST_UPDATE_DATE < p_time_to
1351 AND LAST_UPDATE_DATE > p_time_from FOR UPDATE OF ERROR_ID NOWAIT;
1352
1353
1354 CURSOR c_xnp_debug(p_time_from IN DATE,p_time_to IN DATE) IS
1355 SELECT DEBUG_ID FROM XNP_DEBUG
1356 WHERE LAST_UPDATE_DATE < p_time_to
1357 AND LAST_UPDATE_DATE > p_time_from FOR UPDATE OF DEBUG_ID NOWAIT;
1358
1359 l_xdp_debug_type XDP_DEBUG.DEBUG_TYPE%TYPE;
1360 l_xdp_error_id XDP_ERROR_LOG.ERROR_ID%TYPE;
1361 l_xnp_debug_id XNP_DEBUG.DEBUG_ID%TYPE;
1362
1363 l_counter NUMBER := 0;
1364 l_no_reords NUMBER := 0;
1365 l_user_rollback BOOLEAN := TRUE;
1366
1367 l_rec_name VARCHAR2(16) := 'XDP_FOUND_REC';
1368
1369 BEGIN
1370 PURGE_ERRORS('==== '||p_run_mode|| ' Misc ' ||' ===================');
1371
1372 IF(p_run_mode = 'PURGE') THEN
1373 l_rec_name := 'XDP_PURGE_REC';
1374 END IF;
1375
1376 SELECT COUNT(*) INTO l_no_reords FROM XDP_DEBUG
1377 WHERE LAST_UPDATE_DATE < p_time_to
1378 AND LAST_UPDATE_DATE > p_time_from;
1379
1380 RECORDS_PURGED_MSGS(l_no_reords,'XDP_DEBUG',l_rec_name,0);
1381 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1382 IF p_run_mode = 'PURGE' THEN
1383 <<OUTER_LOOP>>
1384 LOOP
1385 -- REOPEN IT AFTER COMMIT
1386 OPEN c_xdp_debug(p_time_from,p_time_to);
1387 <<INNER_LOOP>>
1388 LOOP
1389 FETCH c_xdp_debug INTO l_xdp_debug_type;
1390
1391 -- IF NO DATA FOUND, THEN EXIT
1392 IF c_xdp_debug%notfound THEN
1393 EXIT OUTER_LOOP;
1394 END IF;
1395
1399 IF (l_counter > g_max_rows_before_commit) AND (NOT l_user_rollback) THEN
1396 DELETE FROM XDP_DEBUG WHERE CURRENT OF c_xdp_debug;
1397
1398 l_counter:=l_counter+1;
1400 l_counter := 0;
1401 COMMIT;
1402 EXIT INNER_LOOP;
1403 END IF;
1404
1405 END LOOP INNER_LOOP;
1406
1407 IF (c_xdp_debug%ISOPEN) THEN
1408 CLOSE c_xdp_debug;
1409 END IF;
1410 END LOOP OUTER_LOOP;
1411 END IF;
1412
1413 COMMIT;
1414
1415 SELECT COUNT(*) INTO l_no_reords FROM XDP_ERROR_LOG
1416 WHERE LAST_UPDATE_DATE < p_time_to
1417 AND LAST_UPDATE_DATE > p_time_from;
1418
1419 RECORDS_PURGED_MSGS(l_no_reords,'XDP_ERROR_LOG',l_rec_name,-1);
1420 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1421 l_counter := 0;
1422
1423 IF p_run_mode = 'PURGE' THEN
1424 <<OUTER_ERROR>>
1425 LOOP
1426
1427 -- REOPEN IT AFTER COMMIT
1428 OPEN c_xdp_errors(p_time_from,p_time_to);
1429 <<INNER_ERROR>>
1430 LOOP
1431 FETCH c_xdp_errors INTO l_xdp_error_id;
1432 -- IF NO DATA FOUND, THEN EXIT
1433 IF c_xdp_errors%notfound THEN
1434 EXIT OUTER_ERROR;
1435 END IF;
1436
1437 DELETE FROM XDP_ERROR_LOG WHERE CURRENT OF c_xdp_errors;
1438 l_counter:=l_counter+1;
1439 IF (l_counter > g_max_rows_before_commit) AND (NOT l_user_rollback) THEN
1440 l_counter := 0;
1441 COMMIT;
1442 EXIT INNER_ERROR;
1443 END IF;
1444 END LOOP INNER_ERROR;
1445 IF (c_xdp_errors%ISOPEN) THEN
1446 CLOSE c_xdp_errors;
1447 END IF;
1448 END LOOP OUTER_ERROR;
1449 END IF;
1450 COMMIT;
1451
1452 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1453
1454 SELECT COUNT(*) INTO l_no_reords FROM XNP_DEBUG
1455 WHERE LAST_UPDATE_DATE < p_time_to
1456 AND LAST_UPDATE_DATE > p_time_from;
1457
1458 RECORDS_PURGED_MSGS(l_no_reords,'XNP_DEBUG',l_rec_name,-1);
1459
1460 l_counter := 0;
1461 IF p_run_mode = 'PURGE' THEN
1462 <<OUTER_XNP_DEBUG>>
1463 LOOP
1464 -- REOPEN IT AFTER COMMIT
1465 OPEN c_xnp_debug(p_time_from,p_time_to);
1466 <<INNER_XNP_DEBUG>>
1467 LOOP
1468 FETCH c_xnp_debug INTO l_xnp_debug_id;
1469 -- IF NO DATA FOUND, THEN EXIT
1470 IF c_xnp_debug%notfound THEN
1471 EXIT OUTER_XNP_DEBUG; -- we are done
1472 END IF;
1473
1474 DELETE FROM XNP_DEBUG WHERE CURRENT OF c_xnp_debug;
1475 l_counter:=l_counter+1;
1476 IF (l_counter > g_max_rows_before_commit) AND (NOT l_user_rollback) THEN
1477 l_counter := 0;
1478 COMMIT;
1479 EXIT INNER_XNP_DEBUG; -- commit and reopen the cursor
1480 END IF;
1481 END LOOP INNER_XNP_DEBUG;
1482 IF (c_xnp_debug%ISOPEN) THEN
1483 CLOSE c_xnp_debug;
1484 END IF;
1485 END LOOP OUTER_XNP_DEBUG;
1486 END IF;
1487 COMMIT;
1488
1489 l_user_rollback := USER_ROLLBACK_CTRL(p_rollback_segment);
1490
1491 SELECT COUNT(*) INTO l_no_reords FROM WF_ITEMS
1492 WHERE ITEM_TYPE='XDPRECOV' AND END_DATE < p_time_to;
1493
1494 RECORDS_PURGED_MSGS(l_no_reords,'WF_ITEMS XDPRECOV',l_rec_name,-1);
1495
1496
1497 IF p_run_mode = 'PURGE' THEN
1498 IF G_PURGE_WORK_FLOW = 'TRUE' THEN
1499 SELECT persistence_type INTO WF_PURGE.PERSISTENCE_TYPE
1500 FROM wf_item_types WHERE NAME = 'XDPRECOV';
1501 WF_PURGE.TOTAL('XDPRECOV', NULL, p_time_to);
1502 END IF;
1503 END IF;
1504
1505 COMMIT;
1506 EXCEPTION
1507 WHEN OTHERS THEN
1508 ROLLBACK;
1509 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1510 FND_MESSAGE.SET_TOKEN('OBJECT','MISC');
1511 PURGE_ERRORS(FND_MESSAGE.GET);
1512 RAISE;
1513 END XDP_PURGE_MISC;
1514
1515 -- Procedure PURGE
1516 -- Purge obsolete data from SFM
1517 --
1518 -- IN:
1519 -- p_number_of_days
1520 -- - number of days of data will be retained in SFM.
1521 -- - if not specified, g_min_number_of_days will be
1522 -- - used if specified as null, or negative or less
1523 -- - than g_min_number_of_days.
1524 -- p_run_mode - specify run mode when this API is called.--
1525 -- - 'PURGE', to purge data
1526 -- - 'VERIFY', to verify setting and print out data will be purged
1527 -- - 'CHECK', to check transactional data in the database
1528 -- p_purge_data_set
1529 -- - indicate what data to be purged,
1530 -- - eg. '[ORDER, SOA, MSGS, MISC]' will purge order, soa
1531 -- - , messages and debug/error data
1532 -- - '[ORDER]' will only purge order data
1533 -- - Default is null, means will not purge at all
1534 --
1535 -- p_purge_msg_flag
1536 -- - indicate if messages whose orders still exist
1537 -- - in the database should be purged or not
1538 --
1539 -- p_purge_order_flag
1540 -- - indicate if the external messages related to orders
1541 -- - will be purged
1542 --
1543 -- p_max_exceptions - number of continuous exceptions allowed before terminating a purge
1544 --
1545 -- p_log_mode - indicate if how you would like to log messages for
1546 -- - purging operation. Available option TERSE and VERBOSE
1547 -- -- any other words will result no message logged
1551 -- OUT:
1548 --
1549 -- p_rollback_segment - indicate what rollback segment should be used. If null, default
1550 -- - rollback segment will be used
1552 -- ERRBUF - as required by concurrent manager
1553 -- RETCODE - as required by concurrent manager
1554 --
1555 --
1556 -- Note: for the concurrent manager, exceptions will be silenced
1557 -- with proper messages returned in ERRBUF. RETCODE is 2 for
1558 -- exception errors
1559 --
1560
1561 PROCEDURE PURGE
1562 (
1563 ERRBUF OUT NOCOPY VARCHAR2,
1564 RETCODE OUT NOCOPY VARCHAR2,
1565 p_number_of_days IN NUMBER DEFAULT g_min_number_of_days,
1566 p_run_mode IN VARCHAR2 DEFAULT 'VERIFY',
1567 p_purge_data_set IN VARCHAR2 DEFAULT '[ORDER,SOA,MSGS,MISC]',
1568 p_purge_msg_flag IN VARCHAR2 DEFAULT 'TRUE',
1569 p_purge_order_flag IN VARCHAR2 DEFAULT 'TRUE',
1570 p_max_exceptions IN NUMBER DEFAULT 10,
1571 p_log_mode IN VARCHAR2 DEFAULT 'TERSE',
1572 p_rollback_segment IN VARCHAR2 DEFAULT NULL
1573 ) IS
1574
1575 l_time_to DATE;
1576 l_time_from DATE;
1577 l_purge_order_with_msg BOOLEAN;
1578 l_purge_msgs_regardless BOOLEAN;
1579 l_orders_purged NUMBER;
1580 l_rollback_segment VARCHAR2(200);
1581 BEGIN
1582 l_purge_order_with_msg := p_purge_order_flag = 'TRUE';
1583 l_purge_msgs_regardless := p_purge_msg_flag = 'TRUE';
1584 g_max_rows_before_commit := FND_PROFILE.VALUE('XDP_THRESHOLD_PURGE_TRANSACTION');
1585 IF (g_max_rows_before_commit IS NULL) THEN
1586 g_max_rows_before_commit := 5000;
1587 END IF;
1588
1589 IF (g_max_rows_before_commit < 1) THEN
1590 g_max_rows_before_commit := 10;
1591 END IF;
1592
1593 --
1594 -- In case value is assigned to null
1595 -- It is not likely that user would have a rollback segment called null
1596 --
1597 l_rollback_segment := p_rollback_segment;
1598 IF l_rollback_segment IS NOT NULL THEN
1599 IF l_rollback_segment = 'NULL' THEN
1600 l_rollback_segment := NULL;
1601 END IF;
1602 END IF;
1603 --
1604 -- This is a global value for this module. It is used to determine what information
1605 -- will be logged.
1606 --
1607 IF p_log_mode = 'TERSE' THEN
1608 g_debug_level := 1;
1609 ELSIF p_log_mode = 'VERBOSE' THEN
1610 g_debug_level := 4;
1611 ELSE
1612 g_debug_level := 0; -- Do not log anything
1613 END IF;
1614
1615 g_max_exceptions := p_max_exceptions;
1616
1617 --
1618 -- Only CHECK, PURGE or VERIFY are legal values for p_run_mode. If not, return an error
1619 --
1620 IF (p_run_mode <> 'CHECK') AND (p_run_mode <> 'PURGE') AND
1621 (p_run_mode <> 'VERIFY')
1622 THEN
1623 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1624 FND_MESSAGE.SET_TOKEN('OBJECT','PURGE');
1625 FND_MESSAGE.SET_TOKEN('CONDITION','p_run_mode ='||p_run_mode);
1626 RETCODE := 2;
1627 ERRBUF := FND_MESSAGE.GET;
1628 PURGE_ERRORS(P_MSG => ERRBUF);
1629 RETURN;
1630 END IF;
1631 --
1632 -- For concurrent manager, do not use DBMS_OUTPUT
1633 -- Otherwise, use dbms_ouptut with one meg buffer
1634 -- This option is not available for customers.
1635 --
1636 IF (g_purge_method <> 'CM') THEN
1637 -- DBMS_OUTPUT.ENABLE(1000000);
1638 NULL;
1639 END IF;
1640
1641 -- set the from time to a very old date
1642 l_time_from := to_date('01-01-1900','mm-dd-yyyy');
1643
1644 IF (p_number_of_days IS NULL) OR
1645 (p_number_of_days < g_min_number_of_days )
1646 THEN
1647 l_time_to := SYSDATE - g_min_number_of_days;
1648 ELSE
1649 l_time_to := SYSDATE - p_number_of_days;
1650 END IF;
1651
1652 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_PROCESS');
1653
1654 --default time format will be used to convert time string
1655
1656 FND_MESSAGE.SET_TOKEN('DATE_FROM',TO_CHAR(l_time_from,'MM-DD-YYYY HH:MI:SS'));
1657 FND_MESSAGE.SET_TOKEN('DATE_TO',TO_CHAR(l_time_to,'MM-DD-YYYY HH:MI:SS'));
1658 PURGE_ERRORS(P_MSG=>FND_MESSAGE.GET);
1659 --
1660 -- By default, we will not manage workflow runtime data.
1661 -- There is a performance hit if this flag is turned on. It is
1662 -- better for performance to purge workflow using workflow purging
1663 -- utility than through this purge function. However, the option
1664 -- is here if that is required.
1665 --
1666 IF INSTR(p_purge_data_set,'ORDER_WITH_WF') <> 0 THEN
1667 G_PURGE_WORK_FLOW := 'TRUE';
1668 END IF;
1669
1670
1671 IF INSTR(p_purge_data_set,'ORDER') <> 0 THEN
1672 XDP_PURGE_ORDERS(l_time_from,l_time_to,p_run_mode,
1673 l_purge_order_with_msg,
1674 l_rollback_segment,l_orders_purged);
1675
1676 RECORDS_PURGED_MSGS(l_orders_purged,'XDP_ORDER_HEADERS','ORDER',-1);
1677 END IF;
1678
1679 IF INSTR(p_purge_data_set,'SOA') <> 0 THEN
1680 XDP_PURGE_SOA(l_time_from,l_time_to,p_run_mode,l_rollback_segment);
1681 END IF;
1682
1683 IF INSTR(p_purge_data_set,'MSG') <> 0 THEN
1684 XDP_PURGE_MESSAGES(
1685 l_time_from,l_time_to,p_run_mode,
1686 l_purge_msgs_regardless,
1687 l_rollback_segment);
1688 END IF;
1689
1690 IF INSTR(p_purge_data_set,'MISC') <> 0 THEN
1691 XDP_PURGE_MISC(l_time_from,l_time_to,p_run_mode,l_rollback_segment);
1692 END IF;
1693
1694 RETCODE := 0;
1695 ERRBUF := 'Success';
1696 COMMIT;
1697 EXCEPTION
1698 WHEN OTHERS THEN
1699 ROLLBACK;
1700 RETCODE := 2;
1701 FND_MESSAGE.SET_NAME('XDP','XDP_PURGE_ERROR');
1702 FND_MESSAGE.SET_TOKEN('OBJECT','PURGE');
1703 FND_MESSAGE.SET_TOKEN('CONDITION',SQLERRM);
1704 ERRBUF := FND_MESSAGE.GET;
1705 -- PURGE_ERRORS(P_MSG => ERRBUF,P_COMMIT => TRUE);
1706 END PURGE;
1707
1708 END XDP_PURGE;
1709