1 Package Body BSC_DBGEN_BSC_READER AS
2 /* $Header: BSCBSRDB.pls 120.19.12000000.2 2007/02/14 10:36:51 rkumar ship $*/
3
4 g_sys_measures BSC_DBGEN_STD_METADATA.tab_clsMeasure;
5 g_sys_measures_loaded boolean :=false;
6 g_error VARCHAR2(4000);
7
8 procedure init is
9 begin
10 if g_initialized=false then
11 bsc_apps.Init_bsc_apps;
12 bsc_apps.Init_Big_In_Cond_Table;
13 g_initialized := true;
14 end if;
15 end;
16
17 --****************************************************************************
18 -- IsIndicatorPnL
19 -- DESCRIPTION:
20 -- Return TRUE if the indicator is type PnL
21 -- PARAMETERS:
22 -- Ind: Indicator code
23 --
24 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
25 --***************************************************************************
26 Function IsIndicatorPnL(Ind IN Integer) return Boolean IS
27 CURSOR cBalance IS
28 SELECT indicator_type, config_type FROM BSC_KPIS_VL where INDICATOR= Ind;
29 l_indicator_type NUMBER;
30 l_config_type NUMBER;
31 BEGIN
32 If l_indicator_type = 1 And l_config_type = 3 Then
33 return true;
34 Else
35 return false;
36 END IF;
37 EXCEPTION WHEN OTHERS THEN
38 fnd_file.put_line(fnd_file.log, 'Exception in IsIndicatorPnL for '||Ind||' : '||sqlerrm);
39 RAISE;
40 End;
41
42 --****************************************************************************
43 -- EsIndicatorBalance
44 --
45 -- DESCRIPTION:
46 -- Returns TRUE is the indicator is type Balance
47 --
48 -- PARAMETERS:
49 -- Ind: Indicator code
50 --
51 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
52 --***************************************************************************
53 Function IsIndicatorBalance(Ind IN NUMBER) return Boolean IS
54 CURSOR cBalance IS
55 SELECT indicator_type, config_type FROM BSC_KPIS_VL where INDICATOR= Ind;
56 l_indicator_type NUMBER;
57 l_config_type NUMBER;
58 BEGIN
59 OPEN cBalance;
60 FETCH cBalance INTO l_indicator_type, l_config_type;
61 CLOSE cBalance;
62
63 If l_indicator_type = 1 And l_Config_Type = 2 Then
64 return true;
65 Else
66 return false;
67 END IF;
68 EXCEPTION WHEN OTHERS THEN
69 fnd_file.put_line(fnd_file.log, 'Exception in IsIndicatorBalance for '||ind||' : '||sqlerrm);
70 RAISE;
71 End;
72
73 --****************************************************************************
74 -- IsIndicatorBalanceOrPnL : EsIndicatorBalanceoPyg
75 --
76 -- DESCRIPTION:
77 -- Return TRUE if the indicator is type Balance or PnL
78 --
79 -- PARAMETERS:
80 -- Ind: indicator code
81 --
82 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
83 --***************************************************************************
84 Function IsIndicatorBalanceOrPnL(Ind IN Integer) return Boolean IS
85 CURSOR cBalance IS
86 SELECT indicator_type, config_type FROM BSC_KPIS_VL where INDICATOR= Ind;
87 l_indicator_type NUMBER;
88 l_config_type NUMBER;
89 BEGIN
90 OPEN cBalance;
91 FETCH cBalance INTO l_indicator_type, l_config_type;
92 CLOSE cBalance;
93 If l_indicator_type = 1 And (l_Config_Type = 2 OR l_Config_Type = 3) Then
94 return true;
95 Else
96 return false;
97 END IF;
98 EXCEPTION WHEN OTHERS THEN
99 fnd_file.put_line(fnd_file.log, 'Exception in IsIndicatorBalanceOrPnL for '||ind||' : '||sqlerrm);
100 RAISE;
101 End;
102
103 --***************************************************************************
104 -- DESCRIPTION:
105 -- Get the number of data columns of the indicator for the given
106 -- dimension set.
107 -- PARAMETERS:
108 -- Indic: indicator code
109 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
110 --**************************************************************************
111 Function get_num_measures(p_indicator IN NUMBER, p_dim_set IN NUMBER) RETURN NUMBER IS
112 l_num_measures number;
113 CURSOR cNumCols IS
114 SELECT COUNT(M.MEASURE_COL) NUM_DATA_COLUMNS
115 FROM BSC_SYS_MEASURES M, BSC_DB_MEASURE_BY_DIM_SET_V I
116 WHERE I.MEASURE_ID = M.MEASURE_ID
117 AND I.DIM_SET_ID = p_dim_set
118 AND I.INDICATOR = p_indicator
119 AND M.TYPE = 0 AND NVL(M.SOURCE, 'BSC') in ( 'BSC', 'PMF');
120 BEGIN
121 OPEN cNumCols;
122 FETCH cNumCols INTO l_num_measures;
123 CLOSE cNumCols;
124 return l_num_measures;
125 EXCEPTION WHEN OTHERS THEN
126 raise;
127 End;
128
129
130 PROCEDURE load_sys_measures IS
131 l_stmt varchar2(1000);
132 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
133 l_measure_null BSC_DBGEN_STD_METADATA.clsMeasure;
134 --BSC-PMF Integration: Need to filter out PMF measures
135 CURSOR c1 IS
136 SELECT ms.MEASURE_COL, ms.HELP, ms.MEASURE_GROUP_ID, ms.PROJECTION_ID, NVL(ms.MEASURE_TYPE, 1) MTYPE, sysm.source
137 FROM BSC_DB_MEASURE_COLS_VL ms,
138 BSC_SYS_MEASURES sysm
139 WHERE ms.measure_col = sysm.measure_col
140 ORDER BY MEASURE_COL;
141 cRow c1%ROWTYPE;
142
143 BEGIN
144
145 OPEN c1;
146 LOOP
147 FETCH c1 INTO cRow;
148 EXIT WHEN c1%NOTFOUND;
149 l_measure := l_measure_null;
150 l_measure.measure_name := cRow.MEASURE_COL;
151 IF (cRow.HELP IS NOT NULL) THEN
152 l_measure.Description := substr(cRow.HELP, 1,240);
153 END IF;
154 IF (cRow.MEASURE_GROUP_ID IS NOT NULL) THEN
155 l_measure.measure_group := cRow.MEASURE_GROUP_ID;
156 ELSE
157 l_measure.measure_group := -1;
158 END IF;
159 l_measure.measure_source := cRow.source;
160 --projection method of the field
161 --0: No Forecast
162 --1: Moving Averge
163 --2: Plan-Based (not used any more)
164 --3: Plan-Based
165 --4: Custom
166 IF (cRow.PROJECTION_ID IS NOT NULL) THEN
167 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID, to_char(cRow.PROJECTION_ID));
168 Else
169 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID, 0);--no projection
170 END IF;
171 l_measure.measure_type := cRow.MTYPE;
172 g_sys_measures(g_sys_measures.count+1) := l_measure;
173 END Loop;
174 CLOSE c1;
175 g_sys_measures_loaded := true;
176 return;
177 exception when others then
178 l_stmt := sqlerrm;
179 bsc_mo_helper_pkg.writeTmp('Exception in load_system_measures: '||l_stmt, FND_LOG.LEVEL_UNEXPECTED, true);
180 bsc_mo_helper_pkg.TerminateWithError('BSC_VAR_LIST_INIT_FAILED', 'load_system_measures');
181 raise;
182 End;
183
184 --****************************************************************************
185 --sys_measure_exists
186 --
187 -- DESCRIPTION:
188 -- Return TRUE if the given field exist in the collection gLov
189 --
190 -- PARAMETERS:
191 -- measure: field name
192 --
193 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
194 --***************************************************************************
195
196 Function sys_measure_exists(p_measure_name IN VARCHAR2, p_measure_source IN VARCHAR2) RETURN BOOLEAN IS
197 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
198 i NUMBER ;
199 BEGIN
200 IF (g_sys_measures_loaded=false) THEN
201 load_sys_measures;
202 END IF;
203 IF (g_sys_measures.count = 0) THEN
204 return false;
205 END IF;
206 i := g_sys_measures.first;
207 LOOP
208 l_measure := g_sys_measures(i);
209 IF (upper(l_measure.measure_Name) = upper(p_measure_name) AND upper(l_measure.measure_source) = upper(p_measure_source) ) THEN
210 return True;
211 END IF;
212 EXIT WHEN i = g_sys_measures.last;
213 i := g_sys_measures.next(i);
214 END LOOP;
215 return false;
216 EXCEPTION WHEN OTHERS THEN
217 fnd_file.put_line(fnd_file.log, 'Exception in sys_measure_exists for field '||p_measure_name||' : '||sqlerrm);
218 raise;
219 End ;
220
221 --****************************************************************************
222 --measure_exists :
223 -- DESCRIPTION:
224 -- Returns TRUE if the field exist in the collection. The collection
225 -- if of objects of class clsCampoDatos
226 --
227 -- PARAMETERS:
228 -- colMeasures: collection
229 -- measure: field name
230 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
231 --***************************************************************************
232 Function measure_exists(p_measure_collection IN BSC_DBGEN_STD_METADATA.tab_clsMeasure, p_measure_name IN VARCHAR2, p_measure_source IN VARCHAR2)
233 RETURN BOOLEAN IS
234 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
235 i NUMBER;
236
237 BEGIn
238
239 IF p_measure_collection.count = 0 THEN
240 return FALSE;
241 END IF;
242
243 i := p_measure_collection.first;
244 LOOP
245 l_measure := p_measure_collection(i);
246 If (UPPER(l_measure.measure_name) = UPPER(p_measure_name) AND upper(l_measure.measure_source)=upper(p_measure_source)) Then
247 return true;
248 END IF;
249 EXIT WHEN i = p_measure_collection.last;
250 i := p_measure_collection.next(i);
251 END LOOP;
252 return false;
253
254 EXCEPTION WHEN OTHERS THEN
255 Fnd_File.Put_Line(Fnd_File.Log, 'Exception dataFieldExists, '||sqlerrm);
256 raise;
257 End;
258
259
260
261 --****************************************************************************
262 --InsertDataColumnInDBMeasureCols
263 --
264 -- DESCRIPTION:
265 -- Creates the record for the internal column in BSC_DB_MEASURE_COLS_TL
266 --
267 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
268 --***************************************************************************
269 PROCEDURE InsertInDBMeasureCols(P_Measure_Col IN BSC_METADATA_OPTIMIZER_PKG.clsMeasureLov) IS
270
271 l_stmt VARCHAR2(1000);
272 i NUMBER;
273
274 BEGIN
275 IF BSC_METADATA_OPTIMIZER_PKG.g_log THEN
276 bsc_mo_helper_pkg.writeTmp( 'Inside InsertInDBMeasureCols, P_Measure_Col = ');
277 END IF;
278
279 bsc_mo_helper_pkg.write_this(P_Measure_Col);
280 --Delete the records if exists
281 l_stmt := 'DELETE FROM BSC_DB_MEASURE_COLS_TL WHERE MEASURE_COL = :1';
282 EXECUTE IMMEDIATE l_stmt using P_Measure_Col.fieldName;
283
284 --Because it is a TL table, we need to insert the record for every supported language
285 i := BSC_METADATA_OPTIMIZER_PKG.gInstalled_Languages.first;
286
287 LOOP
288 EXIT WHEN BSC_METADATA_OPTIMIZER_PKG.gInstalled_Languages.count = 0;
289 INSERT INTO BSC_DB_MEASURE_COLS_TL (
290 MEASURE_COL, LANGUAGE, SOURCE_LANG,
291 HELP, MEASURE_GROUP_ID, PROJECTION_ID, MEASURE_TYPE)
292 VALUES (P_Measure_Col.fieldName, BSC_METADATA_OPTIMIZER_PKG.gInstalled_Languages(i), BSC_METADATA_OPTIMIZER_PKG.gLangCode,
293 P_Measure_Col.Description, P_Measure_Col.groupCode, P_Measure_Col.prjMethod,P_Measure_Col.measureType );
294 EXIT WHEN i = BSC_METADATA_OPTIMIZER_PKG.gInstalled_Languages.last;
295 i := BSC_METADATA_OPTIMIZER_PKG.gInstalled_Languages.next(i);
296 END LOOP;
297 IF BSC_METADATA_OPTIMIZER_PKG.g_log THEN
298 bsc_mo_helper_pkg.writeTmp( 'Compl. InsertInDBMeasureCols');
299 END IF;
300
301
302 EXCEPTION WHEN OTHERS THEN
303 g_error := sqlerrm;
304 Fnd_File.Put_Line(Fnd_File.Log, 'Exception in InsertInDBMeasureCols '||g_error);
305 RAISE;
306
307 End;
308
309
310 --****************************************************************************
311 --AddInternalColumnInDB
312 --
313 -- DESCRIPTION:
314 -- Creates the record for the internal column in BSC_DB_MEASURE_COLS_TL
315 -- and also added to the collection gLov.
316 -- Projection method and type (balance or statistic) are deduced from
317 -- the base columns.
318 --
319 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
320 --***************************************************************************
321 /*
322 PROCEDURE AddInternalColumnInDB(internalColumn IN VARCHAR2, InternalColumnType NUMBER,
323 baseColumns IN dbms_sql.varchar2_table , numBaseColumns IN NUMBER) IS
324 L_Measure_Col BSC_METADATA_OPTIMIZER_PKG.clsmeasureLov;
325 i NUMBER;
326 prjMethod NUMBER;
327
328
329 l_temp number;
330 BEGIN
331
332 L_Measure_Col.fieldName := internalColumn;
333 l_temp := bsc_mo_helper_pkg.findIndex(BSC_METADATA_OPTIMIZER_PKG.gLov, baseColumns(baseColumns.first));
334 L_Measure_Col.groupCode := BSC_METADATA_OPTIMIZER_PKG.gLov(l_temp).groupCode;
335 L_Measure_Col.Description := BSC_MO_HELPER_PKG.Get_LookUp_Value('BSC_UI_BACKEND', 'INTERNAL_COLUMN');
336
337 IF (InternalColumnType =1) THEN
338 --Formula
339 --The projection method of the calculated column is deduced from the
340 --projection method of the operands:
341 --If the projection method for one of the operands is 'No forecast'
342 --then the projection method for the calculated column is 'No forecast'
343 --Else, If the projection method of one of the operands is 'Custom' then:
344 --If the projection method of one of the operands is 'Plan-based' then
345 --the projection method of the calculated column is 'Plan-based'
346 --Else, the projection method is 'Moving Average'
347 --Else, if the projection method of one of the operands is 'Plan-based' then
348 --the projection method of the calculated column is 'Plan-based'.
349 --Else, the projection method of the calculated column is 'Moving Average'
350 --Projection methods:
351 --0: No Forecast
352 --1: Moving Averge
353 --3: Plan-Based
354 --4: Custom
355
356 L_Measure_Col.prjMethod := 1; --Moving average has the lowest priority
357 i := baseColumns.first;
358 LOOP
359 EXIT WHEN baseColumns.count = 0;
360 l_temp := bsc_mo_helper_pkg.findIndex(BSC_METADATA_OPTIMIZER_PKG.gLov, baseColumns(i));
361 prjMethod := BSC_METADATA_OPTIMIZER_PKG.gLov(l_temp).prjMethod;
362
363 If prjMethod = 0 Then
364 --No forecast
365 L_Measure_Col.prjMethod := 0;
366 EXIT;
367 END IF;
368
369 If prjMethod = 3 Then
370 --Plan-Based
371 L_Measure_Col.prjMethod := 3;
372 Else
373 --Moving Average of Custom
374 If L_Measure_Col.prjMethod <> 3 Then
375 L_Measure_Col.prjMethod := 1;
376 END IF;
377 END IF;
378 EXIT WHEN i = baseColumns.last;
379 i := baseColumns.next(i);
380 END LOOP;
381
382 --The type of the calculated column (Balance or Statistics) is
383 --deduced from the type of the operands. If at least one of the operands
384 --is Balance Type, then the calculated column is Balance.
385 --Measure types:
386 --1: Statistic
387 --2: Balance
388 i := baseColumns.first;
389 LOOP
390 EXIT WHEN baseColumns.count = 0;
391 l_temp := bsc_mo_helper_pkg.findIndex(BSC_METADATA_OPTIMIZER_PKG.gLov, baseColumns(i));
392 L_Measure_Col.measureType := BSC_METADATA_OPTIMIZER_PKG.gLov(l_temp).measureType;
393 If L_Measure_Col.measureType = 2 Then
394 EXIT;
395 END IF;
396 EXIT WHEN i = baseColumns.last;
397 i := baseColumns.next(i);
398 END LOOP;
399 ELSIF (InternalColumnType=2 OR InternalColumnType=3) THEN
400 --Total and counter for Average at Lowest Level
401
402 --Projection method and type are the same of the base column
403 --In this case there is only one base column
404 l_temp := bsc_mo_helper_pkg.findIndex(BSC_METADATA_OPTIMIZER_PKG.gLov, baseColumns(baseColumns.first));
405 L_Measure_Col.prjMethod := BSC_METADATA_OPTIMIZER_PKG.gLov(l_temp).prjMethod;
406 L_Measure_Col.measureType := BSC_METADATA_OPTIMIZER_PKG.gLov(l_temp).measureType;
407 END IF;
408
409 If Not sys_measure_exists(internalColumn, 'BSC') Then
410 IF (g_sys_measures.count>0) THEN
411 g_sys_measures(g_sys_measures.last+1) := L_Measure_Col;
412 ELSE
413 g_sys_measures(1) := L_Measure_Col;
414 END IF;
415 Else
416 --Update the filed with the new information
417 l_temp := bsc_mo_helper_pkg.findIndex(g_sys_measures, internalColumn);
418 g_sys_measures(l_temp).groupCode := L_Measure_Col.groupCode;
419 g_sys_measures(l_temp).Description := L_Measure_Col.Description;
420 g_sys_measures(l_temp).measureType := L_Measure_Col.measureType;
421 g_sys_measures(l_temp).prjMethod := L_Measure_Col.prjMethod;
422 END IF;
423 InsertInDBMeasureCols( L_Measure_Col);
424
425 IF BSC_METADATA_OPTIMIZER_PKG.g_log THEN
426 bsc_mo_helper_pkg.writeTmp( 'Compl AddInternalColumnInDB');
427 END IF;
428
429
430 EXCEPTION WHEN OTHERS THEN
431 g_error := sqlerrm;
432 Fnd_File.Put_Line(Fnd_File.Log, 'Exception in AddInternalColumnInDB : '||g_error);
433 raise;
434 End;
435 */
436
437
438 --****************************************************************************
439 --SetMeasurePropertyDB
440 -- DESCRIPTION:
441 -- Update the given proeprty of the meaaure in the column
442 -- S_COLOR_FORMULA of BSC_SYS_MEAURES
443 -- given data column
444 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
445 --***************************************************************************
446
447 PROCEDURE SetMeasurePropertyDB(dataColumn IN VARCHAR2, propertyName IN VARCHAR2, propertyValue IN VARCHAR2)
448 IS
449 l_stmt VARCHAR2(1000);
450
451 BEGIN
452
453
454 UPDATE BSC_SYS_MEASURES
455 SET S_COLOR_FORMULA = BSC_APPS.SET_PROPERTY_VALUE(S_COLOR_FORMULA, propertyName, propertyValue)
456 WHERE UPPER(MEASURE_COL) = upper(dataColumn)
457 AND TYPE = 0 AND NVL(SOURCE, 'BSC') = 'BSC';
458
459 EXCEPTION WHEN OTHERS THEN
460 g_error := sqlerrm;
461 Fnd_File.Put_Line(Fnd_File.Log, 'Exception in SetMeasurePropertyDB : '||g_error);
462 raise;
463 End;
464
465 --***************************************************************************
466 --GetAgregFunction : GetAggregateFunction
467 -- DESCRIPTION:
468 -- Returns in p_aggregation_method and pAvgL the aggregation function of the
469 -- given data column
470 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
471 --***************************************************************************
472 PROCEDURE Get_Aggregate_Function(dataColumn IN VARCHAR2, p_aggregation_method IN OUT NOCOPY VARCHAR2, pAvgL IN OUT NOCOPY VARCHAR2,
473 AvgLTotalColumn IN OUT NOCOPY VARCHAR2, AvgLCounterColumn IN OUT NOCOPY VARCHAR2) IS
474 l_stmt VARCHAR2(1000);
475 aggFunction VARCHAR2(1000);
476 CURSOR C1(p1 VARCHAR2, p2 VARCHAR2, p3 VARCHAR2, p4 VARCHAR2) IS
477 SELECT NVL(OPERATION, 'SUM') AS OPER,
478 NVL(BSC_APPS.GET_PROPERTY_VALUE(S_COLOR_FORMULA, p1),'N') AS PAVGL,
479 BSC_APPS.GET_PROPERTY_VALUE(S_COLOR_FORMULA, p2) AS PAVGLTOTAL,
480 BSC_APPS.GET_PROPERTY_VALUE(S_COLOR_FORMULA, p3) AS PAVGLCOUNTER
481 FROM BSC_SYS_MEASURES
482 WHERE UPPER(MEASURE_COL) = UPPER(p4)
483 AND TYPE = 0
484 AND NVL(SOURCE, 'BSC') = 'BSC';
485
486 cRow c1%ROWTYPE;
487
488 BEGIN
489
490 OPEN c1(BSC_METADATA_OPTIMIZER_PKG.C_PAVGL,
491 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLTOTAL,
492 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLCOUNTER,
493 dataColumn);
494 FETCH c1 INto cRow;
495 If c1%NOTFOUND Then
496 p_aggregation_method := null;
497 pAvgL := null;
498 AvgLTotalColumn := null;
499 AvgLCounterColumn := null;
500 Else
501 p_aggregation_method := cRow.OPER;
502 pAvgL := cRow.PAVGL;
503 AvgLTotalColumn := null;
504 If (crow.PAVGLTOTAL is not null) Then
505 AvgLTotalColumn := cRow.PAVGLTOTAL;
506 END IF;
507 AvgLCounterColumn := null;
508 If (cRow.PAVGLCOUNTER IS NOT NULL) Then
509 AvgLCounterColumn := cRow.PAVGLCOUNTER;
510 END IF;
511 END IF;
512 close c1;
513 EXCEPTION WHEN OTHERS THEN
514 g_error := sqlerrm;
515 Fnd_File.Put_Line(Fnd_File.Log, 'Exception in GetAggregateFunction '||g_error);
516 RAISE;
517
518 End;
519
520 --***************************************************************************
521 --getNextInternalColumnName
522 -- DESCRIPTION:
523 -- Returns the next Internal Column Name
524 -- BSCIC<next value from sequence BSC_INTERNAL_COLUMN_S>
525 --
526 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
527 --***************************************************************************
528 Function get_Next_Internal_Column_Name RETURN VARCHAR2 IS
529 l_seq NUMBER;
530
531
532 BEGIN
533 SELECT BSC_INTERNAL_COLUMN_S.NEXTVAL INTO l_seq FROM DUAL;
534 return 'BSCIC'||l_seq;
535 End;
536
537 -- PRIVATE API
538 FUNCTION Get_All_Measures_For_Fact(p_fact IN VARCHAR2, p_dim_set IN NUMBER)
539 return BSC_DBGEN_STD_METADATA.tab_clsMeasure IS
540 l_measure_name varchar2(1000);
541 measures dbms_sql.varchar2_table;
542 l_num_measures NUMBER;
543 l_aggregation_method varchar2(1000);
544 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
545 l_measure_null BSC_DBGEN_STD_METADATA.clsMeasure;
546 colMeasures BSC_DBGEN_STD_METADATA.tab_clsMeasure;
547 i NUMBER;
548 msg VARCHAR2(1000);
549
550 pFormulaSource VARCHAR2(1000);
551 pAvgL VARCHAR2(1000);
552 pAvgLTotal VARCHAR2(1000);
553 pAvgLCounter VARCHAR2(1000);
554 FuncAgregSingleColumn VARCHAR2(1000);
555 pAvgLSingleColumn VARCHAR2(1000);
556 AvgLTotalColumn VARCHAR2(1000);
557 AvgLCounterColumn VARCHAR2(1000);
558 l_measure_type NUMBER;
559 l_measure_id NUMBER;
560
561 l_stmt2 VARCHAR2(1000):= 'SELECT distinct nvl(M.MEASURE_COL, C.COLUMN_NAME), NVL(M.OPERATION, ''SUM'') AS OPER,
562 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :1) AS PFORMULASOURCE,
563 NVL(BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :2 ),''N'') AS PAVGL,
564 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :3) AS PAVGLTOTAL,
565 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :4) AS PAVGLCOUNTER,
566 M.MEASURE_ID, nvl(cols.measure_type, 1) measure_type, m.source
567 FROM BSC_SYS_MEASURES M, BSC_DB_TABLES_COLS C, BSC_DB_MEASURE_COLS_VL COLS
568 WHERE M.MEASURE_COL(+) = C.COLUMN_NAME
569 AND COLS.measure_col(+) = c.column_name
570 AND C.COLUMN_TYPE = ''A''
571 AND C.TABLE_NAME LIKE ''BSC_S%'||p_fact||'_'||p_dim_set||'%'||'''
572 AND M.TYPE(+) = 0';
573 TYPE CurTyp IS REF CURSOR;
574 cv CurTyp;
575 l_measure_source varchar2(30);
576 BEGIN
577
578 OPEN cv for l_stmt2 USING BSC_METADATA_OPTIMIZER_PKG.C_PFORMULASOURCE,
579 BSC_METADATA_OPTIMIZER_PKG.C_PAVGL,
580 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLTOTAL,
581 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLCOUNTER;
582 LOOP
583 FETCH cv INTO l_measure_name, l_aggregation_method, pFormulaSource, pAvgL, pAvgLTotal, pAvgLCounter, l_measure_id, l_measure_type, l_measure_source;
584 EXIT WHEN cv%NOTFOUND;
585 Measures := BSC_DBGEN_UTILS.get_measure_list(l_measure_name);
586 l_num_measures := Measures.count;
587 i := Measures.first;
588 LOOP
589 EXIT WHEN Measures.count = 0;
590 If Not measure_exists(colMeasures, Measures(i), l_measure_source) Then
591 --Get the aggregation function and Avgl flag of the column (single column)
592 Get_Aggregate_Function (Measures(i), FuncAgregSingleColumn, pAvgLSingleColumn, AvgLTotalColumn, AvgLCounterColumn);
593 If FuncAgregSingleColumn IS NULL Then
594 FuncAgregSingleColumn := l_aggregation_method;
595 END IF;
596 If pAvgLSingleColumn IS NULL Then
597 pAvgLSingleColumn := pAvgL;
598 END IF;
599 l_measure := l_measure_null;
600 l_measure.measure_Name := Measures(i);
601 l_measure.measure_id := l_measure_id;
602 l_measure.measure_type := l_measure_type;
603 l_measure.AGGREGATION_method := FuncAgregSingleColumn;
604 l_measure.datatype := 'NUMBER';
605 l_measure.measure_source := l_measure_source;
606 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_SINGLE_COLUMN, pAvgLSingleColumn);
607 If pAvgLSingleColumn = 'Y' Then
608 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_TOTAL_COLUMN, AvgLTotalColumn);
609 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_COUNTER_COLUMN, AvgLCounterColumn);
610 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.SOURCE_FORMULA, AvgLTotalColumn||'/'||AvgLCounterColumn);
611 END IF;
612 END IF;
613 EXIT WHEN i = Measures.last;
614 i := Measures.next(i);
615 END LOOP;
616 colMeasures(colMeasures.count +1 ) := l_measure;
617 END Loop;
618 close cv;
619 return colMeasures;
620 EXCEPTION WHEN OTHERS THEN
621 raise;
622 END;
623
624
625
626 --***************************************************************************
627 -- DESCRIPTION:
628 -- handle missing levels, if Country<-State<-City is the actual relationship
629 -- and if only Country and City are configured for the KPI, return the
630 -- parent child relationship between Country and City as true if it can
631 -- be derived thru some rollup
632 -- PARAMETERS:
633 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
634 --***************************************************************************
635 function is_parent_1N_any_level(p_child_level IN VARCHAR2, p_parent_level IN VARCHAR2,
636 p_missing_levels OUT nocopy dbms_sql.varchar2_table ) RETURN boolean AS
637 CURSOR cParent IS
638 WITH tree AS
639 (
640 SELECT childlvl.level_Table_name child_lvl
641 , parentlvl.level_Table_name parent_lvl
642 , LEVEL lvl
643 FROM bsc_sys_dim_level_rels rels, bsc_sys_dim_levels_b childlvl, bsc_sys_dim_levels_b parentlvl
644 WHERE rels.parent_dim_level_id = parentlvl.dim_level_id
645 AND rels.dim_level_id = childlvl.dim_level_id
646 START WITH parent_dim_level_id = parentlvl.dim_level_id
647 AND parentlvl.level_table_name = p_parent_level
648 CONNECT BY rels.parent_dim_level_id||rels.relation_type = PRIOR rels.dim_level_id||1
649 )
650 SELECT parent_lvl, child_lvl
651 FROM tree
652 CONNECT BY PRIOR parent_lvl = child_lvl
653 AND PRIOR lvl = lvl + 1
654 START WITH child_lvl = p_child_level
655 AND lvl =
656 (
657 SELECT MIN(lvl)
658 FROM tree
659 WHERE child_lvl = p_child_level
660 );
661
662 b_parent boolean := false;
663 BEGIN
664 FOR i IN cParent LOOP
665 b_parent := true;
666 IF (i.parent_lvl <> p_parent_level) THEN
667 p_missing_levels(p_missing_levels.count+1) := i.parent_lvl;
668 END IF;
669 END LOOP;
670 return b_parent;
671 EXCEPTION WHEN OTHERS THEN
672 raise;
673 End;
674
675 --***************************************************************************
676 -- DESCRIPTION:
677 -- PARAMETERS:
678 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
679 --***************************************************************************
680 Function is_parent_1N(p_child_level IN VARCHAR2, p_parent_level IN VARCHAR2 ) RETURN boolean IS
681
682 CURSOR cParent is
683 SELECT count(1)
684 FROM BSC_SYS_DIM_LEVELS_B child_lvl, BSC_SYS_DIM_LEVELS_B parent_lvl, BSC_SYS_DIM_LEVEL_RELS Rels
685 WHERE
686 child_lvl.LEVEL_TABLE_NAME = p_child_level
687 AND parent_lvl.level_table_name= p_parent_level
688 AND child_lvl.DIM_LEVEL_ID = Rels.DIM_LEVEL_ID
689 AND parent_lvl.DIM_LEVEL_ID = Rels.PARENT_DIM_LEVEL_ID
690 AND Rels.RELATION_TYPE = 1;
691 l_count NUMBER;
692 BEGIN
693
694 OPEN cParent;
695 FETCH cParent INTO l_count;
696 CLOSE cParent;
697
698 IF (l_count > 0) THEN
699 return true;
700 ELSE
701 return false;
702 END IF;
703 EXCEPTION WHEN OTHERS THEN
704 raise;
705 End;
706
707 --***************************************************************************
708 -- DESCRIPTION:
709 -- PARAMETERS:
710 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
711 --***************************************************************************
712 Function is_parent_MN(p_child_level IN VARCHAR2, p_parent_level IN VARCHAR2 ) RETURN boolean IS
713 CURSOR cParent IS
714 SELECT count(1)
715 FROM BSC_SYS_DIM_LEVELS_B child_lvl, BSC_SYS_DIM_LEVELS_B parent_lvl, BSC_SYS_DIM_LEVEL_RELS Rels
716 WHERE
717 child_lvl.LEVEL_TABLE_NAME = p_child_level
718 AND parent_lvl.level_table_name= p_parent_level
719 AND child_lvl.DIM_LEVEL_ID = Rels.DIM_LEVEL_ID
720 AND parent_lvl.DIM_LEVEL_ID = Rels.PARENT_DIM_LEVEL_ID
721 AND Rels.RELATION_TYPE = 2;
722 l_count NUMBER;
723 BEGIN
724 OPEN cParent;
725 FETCH cParent INTO l_count;
726 CLOSE cParent;
727 IF (l_count > 0) THEN
728 return true;
729 ELSE
730 return false;
731 END IF;
732 EXCEPTION WHEN OTHERS THEN
733 g_error := sqlerrm;
734 fnd_file.put_line(fnd_file.log, 'Exception in is_parent_MN : '||g_error||', p_child_level='||p_child_level||', p_parent_level='||p_parent_level);
735 raise;
736 End;
737
738
739 --****************************************************************************
740 -- DESCRIPTION:
741 -- Returns the index of the Levels family of the collection
742 -- l_dimensions which the given dimension belongs to.
743 --
744 -- PARAMETERS:
745 -- l_dimensions: Levels families collection
746 -- Maestra: dimension table name
747 --
748 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
749 --***************************************************************************
750
751 Function get_Dimension_Index(p_dimensions IN BSC_DBGEN_STD_METADATA.tab_clsDimension,
752 p_level IN VARCHAR2,
753 p_include_missing_levels IN BOOLEAN,
754 p_missing_levels OUT nocopy DBMS_SQL.VARCHAR2_TABLE)
755 return NUMBER IS
756 l_dimension BSC_DBGEN_STD_METADATA.clsDimension;
757 l_level BSC_DBGEN_STD_METADATA.clsLevel;
758 l_ct NUMBER := 0;
759 j NUMBER := 0;
760 l_groups DBMS_SQL.NUMBER_TABLE;
761 l_missing_levels DBMS_SQL.VARCHAR2_TABLE;
762 BEGIN
763 IF (p_dimensions.count =0 ) THEN
764 return -1;
765 END IF;
766 IF (p_include_missing_levels = false) THEN
767 FOR i IN p_dimensions.first..p_dimensions.last LOOP
768 l_dimension := p_dimensions(i);
769 FOR j IN l_dimension.Hierarchies(1).Levels.first..l_dimension.Hierarchies(1).Levels.last LOOP
770 l_level := l_dimension.Hierarchies(1).levels(j);
771 If is_parent_1N(p_level, l_level.level_table_name) Then
772 return i;
773 END IF;
774 If is_parent_MN(p_level, l_level.level_table_name) Then
775 return i;
776 END IF;
777 END LOOP;
778 END LOOP;
779 ELSE
780 FOR i IN p_dimensions.first..p_dimensions.last LOOP
781 l_dimension := p_dimensions(i);
782 FOR j IN l_dimension.Hierarchies(1).Levels.first..l_dimension.Hierarchies(1).Levels.last LOOP
783 l_level := l_dimension.Hierarchies(1).levels(j);
784 If is_parent_1N_any_level(p_level, l_level.level_table_name, l_missing_levels ) Then
785 return i;
786 END IF;
787 If is_parent_MN(p_level, l_level.level_table_name) Then
788 return i;
789 END IF;
790 END LOOP;
791 END LOOP;
792 END IF;
793 return -1;
794 EXCEPTION WHEN OTHERS THEN
795 g_error := sqlerrm;
796 fnd_file.put_line(fnd_file.log, 'Exception in getDimensionIndex '||g_error);
797 RAISE;
798 End ;
799
800
801 PROCEDURE insert_parents(p_periodicity IN NUMBER, p_parents IN VARCHAR2, p_periodicity_list IN BSC_DBGEN_STD_METADATA.tab_clsPeriodicity) IS
802 l_parents_list DBMS_SQL.NUMBER_TABLE;
803 l_table_name VARCHAR2(100) := 'bsc_tmp_per_circ_'||userenv('SESSIONID');
804 l_stmt VARCHAR2(1000) := 'INSERT INTO '||l_table_name||'(periodicity, source) values (:1, :2)';
805 l_index NUMBER;
806 l_per_id_list DBMS_SQL.NUMBER_TABLE;
807 BEGIN
808 l_parents_list := bsc_mo_helper_pkg.decomposeStringtoNumber(p_parents, ',');
809 IF (p_periodicity_list.count>0) THEN
810 FOR i IN p_periodicity_list.first..p_periodicity_list.last LOOP
811 l_per_id_list(l_per_id_list.count+1) :=p_periodicity_list(i).periodicity_id;
812 END LOOP;
813 END IF;
814 IF l_parents_list.count>0 THEN
815 FOR i IN l_parents_list.first..l_parents_list.last LOOP
816 IF bsc_mo_helper_pkg.searchNumberExists(l_per_id_list, l_per_id_list.count, l_parents_list(i)) THEN
817 execute immediate l_stmt USING p_periodicity, l_parents_list(i);
818 END IF;
819 end loop;
820 END IF;
821 EXCEPTION WHEN OTHERS THEN
822 g_error := sqlerrm;
823 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.insert_parents '||g_error);
824 RAISE;
825 END;
826
827 FUNCTION configure_parent_periods(p_periodicity_list IN OUT nocopy BSC_DBGEN_STD_METADATA.tab_clsPeriodicity)
828 RETURN BSC_DBGEN_STD_METADATA.tab_clsPeriodicity IS
829 PRAGMA AUTONOMOUS_TRANSACTION;
830 l_table_name VARCHAR2(100) := 'bsc_tmp_per_circ_'||userenv('SESSIONID');
831 l_stmt VARCHAR2(1000) := 'CREATE TABLE '||l_table_name||'(periodicity NUMBER, source NUMBER)';
832 CURSOR cPeriods (p_periodicity NUMBER) IS
833 SELECT SOURCE
834 FROM BSC_SYS_PERIODICITIES_VL
835 WHERE PERIODICITY_ID=p_periodicity;
836 l_parents VARCHAR2(4000);
837 l_temp NUMBER;
838 l_periodicity_list BSC_DBGEN_STD_METADATA.tab_clsPeriodicity;
839 TYPE CurTyp IS REF CURSOR;
840 cv CurTyp;
841 BEGIN
842 l_periodicity_list := p_periodicity_list;
843 bsc_mo_helper_pkg.dropTable(l_table_name);
844 bsc_mo_helper_pkg.Do_DDL(l_stmt, ad_ddl.create_table, l_table_name);
845 IF p_periodicity_list.count>0 THEN
846 FOR i IN p_periodicity_list.first..p_periodicity_list.last LOOP
847 OPEN cPeriods(p_periodicity_list(i).periodicity_id);
848 FETCH cPeriods INTO l_parents;
849 insert_parents(p_periodicity_list(i).periodicity_id, l_parents, p_periodicity_list);
850 CLOSE cPeriods;
851 END LOOP;
852 commit;
853 END IF;
854 l_stmt := ' select distinct source from '||l_table_name||' connect by periodicity = prior source start with periodicity = :1';
855 IF (p_periodicity_list.count>0) THEN
856 FOR i IN p_periodicity_list.first..p_periodicity_list.last LOOP
857 BEGIN
858 OPEN cv FOR l_stmt USING p_periodicity_list(i).periodicity_id;
859 LOOP
860 FETCH cv INTO l_temp;
861 EXIT WHEN cv%NOTFOUND;
862 p_periodicity_list(i).parent_periods(p_periodicity_list(i).parent_periods.count+1) := l_temp;
863 END LOOP;
864 CLOSE cv;
865 EXCEPTION WHEN OTHERS THEN
866 raise;
867 END ;
868 END LOOP;
869 END IF;
870 bsc_mo_helper_pkg.dropTable(l_table_name);
871 commit;
872 return p_periodicity_list;
873 EXCEPTION WHEN OTHERS THEN
874 g_error := sqlerrm;
875 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.configure_parent_periods '||g_error);
876 RAISE;
877 END;
878
879
880 FUNCTION Get_Fact_Info(p_process_id IN NUMBER, p_prototype_flag IN NUMBER, p_fact_list IN DBMS_SQL.NUMBER_TABLE ) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
881 l_stmt varchar2(1000);
882 l_Code number;
883 l_Name BSC_KPIS_VL.NAME%TYPE;
884 l_IndicatorType number;
885 l_ConfigType number;
886 l_per_inter number;
887 l_OptimizationMode number;
888 l_Action_Flag number;
889 l_Share_Flag number;
890 l_Source_Indicator number;
891 TYPE CurTyp IS REF CURSOR;
892 cv CurTyp;
893 l_fact BSC_DBGEN_STD_METADATA.clsFact;
894 l_fact_list BSC_DBGEN_STD_METADATA.tab_clsFact;
895 strWhereInIndics VARCHAR2(1000);
896 BEGIN
897
898
899 l_stmt := 'SELECT DISTINCT INDICATOR, NAME, PROTOTYPE_FLAG,
900 INDICATOR_TYPE, CONFIG_TYPE, PERIODICITY_ID,
901 SHARE_FLAG, SOURCE_INDICATOR
902 FROM BSC_KPIS_VL ';
903 IF (p_process_id IS NOT NULL) THEN
904 l_stmt := l_stmt || ' where prototype_flag =:prototype_flag and indicator in
905 (SELECT to_number(fact_name) FROM BSC_DB_GEN_KPI_LIST WHERE process_id = :process_ID)';
906 l_Stmt := l_stmt || ' ORDER BY INDICATOR ';
907 OPEN cv FOR l_stmt using p_prototype_flag, p_process_id;
908 ELSE
909 strWhereInIndics := BSC_DBGEN_UTILS.Get_New_Big_In_Cond_Number(10, 'INDICATOR');
910 IF (l_fact_list.count>0) THEN
911 FOR i IN l_fact_list.first..l_fact_list.last LOOP
912 BSC_DBGEN_UTILS.Add_Value_Big_In_Cond_Number( 9, p_fact_list(i));
913 END LOOP;
914 END IF;
915 l_stmt := l_stmt || ' where '||strWhereInIndics;
916 l_Stmt := l_stmt || ' ORDER BY INDICATOR ';
917 OPEN cv FOR l_stmt;
918 END IF;
919 LOOP
920 FETCH cv into l_code, l_name, l_action_flag,
921 l_IndicatorType, l_configType, l_per_inter, l_share_flag, l_source_indicator;
922 EXIT WHEN cv%NOTFOUND;
923 l_optimizationMode := BSC_DBGEN_UTILS.get_KPI_Property_Value(l_Code, 'DB_TRANSFORM', 1);
924 IF l_Action_Flag <> 2 THEN
925 l_Action_Flag := 3;
926 END IF;
927 l_fact.Fact_ID := l_code;
928 l_fact.Fact_Name := l_name;
929 l_fact.fact_type := l_indicatorType;
930 l_fact.Application_short_name := 'BSC';
931 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.PROTOTYPE_FLAG, l_action_flag);
932 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.CONFIG_TYPE, l_ConfigType);
933 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.PERIODICITY_ID, l_per_inter);
934 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.OPTIMIZATION_MODE, l_OptimizationMode);
935 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.SHARE_FLAG,l_share_flag);
936 bsc_dbgen_utils.add_property(l_fact.properties, BSC_DBGEN_STD_METADATA.SOURCE_INDICATOR, nvl(l_source_indicator, 0));
937 l_fact_list(l_fact_list.count+1) := l_fact;
938 END Loop;
939 CLOSE cv;
940 EXCEPTION WHEN OTHERS THEN
941 g_error := sqlerrm;
942 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.get_fact_info '||g_error);
943 RAISE;
944
945 END;
946 FUNCTION Get_Fact_Info(p_process_id IN NUMBER, p_prototype_flag IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
947 l_id_list DBMS_SQL.NUMBER_TABLE;
948 BEGIN
949 return Get_Fact_Info(p_process_id, p_prototype_flag, l_id_list);
950 END;
951
952 FUNCTION Get_Facts_To_Recreate(p_process_id IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
953 BEGIN
954 return get_fact_info(p_process_id, 3);
955 END;
956
957 FUNCTION Get_Facts_To_Delete(p_process_id IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
958 BEGIN
959 return get_fact_info(p_process_id, 2);
960 END;
961
962 FUNCTION Get_Facts_To_Recalculate(p_process_id IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
963 l_stmt Varchar2(1000);
964 strWhereInIndics Varchar2(1000);
965 strWhereNotInIndics Varchar2(1000);
966 strWhereInMeasures Varchar2(1000);
967 i NUMBER := 0;
968 arrMeasuresCols DBMS_SQL.VARCHAR2_TABLE;
969 arrRelatedMeasuresIds DBMS_SQL.NUMBER_TABLE;
970
971 --measureCol Varchar2(1000);
972 Operands DBMS_SQL.VARCHAR2_TABLE;
973 NumOperands NUMBER;
974 l_measureID NUMBER;
975 l_measureCol VARCHAR2(500);
976 TYPE CurTyp IS REF CURSOR;
977 cv CurTyp;
978
979 l_error varchar2(400);
980 l_indicator_id NUMBER;
981 l_fact_list BSC_DBGEN_STD_METADATA.tab_clsFact;
982 l_fact BSC_DBGEN_STD_METADATA.clsFact;
983 l_fact_ids DBMS_SQL.NUMBER_TABLE;
984 l_num_measures NUMBER;
985 BEGIN
986 l_fact_list := get_fact_info(p_process_id, 4);
987 IF (l_fact_list.count = 0) THEN
988 return l_fact_list;
989 END IF;
990 --Init and array with the measures used by the indicators flagged for
991 --non-structural changes
992 l_num_measures := 0;
993 strWhereInIndics := BSC_DBGEN_UTILS.Get_New_Big_In_Cond_Number(9, 'I.INDICATOR');
994 i:= 0;
995 LOOP
996 EXIT WHEN i=l_fact_list.count;
997 BSC_DBGEN_UTILS.Add_Value_Big_In_Cond_Number( 9, l_fact_list(i).fact_id);
998 i:=i+1;
999 END LOOP;
1000 --PMF-BSC Integration: Filter out PMF measures
1001 l_stmt := 'SELECT DISTINCT M.MEASURE_COL FROM BSC_SYS_MEASURES M, BSC_DB_MEASURE_BY_DIM_SET_V I'
1002 || ' WHERE I.MEASURE_ID = M.MEASURE_ID AND ('|| strWhereInIndics ||' )'||
1003 ' AND M.TYPE = 0 AND NVL(M.SOURCE, ''BSC'') in (''PMF'', ''BSC'') ';
1004 OPEN cv FOR l_stmt;
1005 LOOP
1006 FETCH cv INTO l_measureCol;
1007 EXIT when cv%NOTFOUND;
1008 arrMeasuresCols(l_num_measures) := l_measureCol;
1009 END Loop;
1010 CLOSE cv;
1011 /*The measures in the array arrMeasuresCols are the ones that could be changed
1012 For that reason the indicators were flaged to 4
1013 We need to see in all system measures if there is a formula using that measure.
1014 IF that happen we need to add that measure. Any kpi using that meaure should be flaged too.*/
1015 strWhereNotInIndics := ' NOT ( ' || strWhereInIndics || ')';
1016 l_stmt := 'SELECT DISTINCT M.MEASURE_ID, M.MEASURE_COL '
1017 ||'FROM BSC_SYS_MEASURES M, BSC_DB_MEASURE_BY_DIM_SET_V I '||
1018 ' WHERE I.MEASURE_ID = M.MEASURE_ID AND ('|| strWhereNotInIndics ||' ) '||
1019 ' AND M.TYPE = 0 AND NVL(M.SOURCE, ''BSC'') in (''BSC'', ''PMF'')';
1020 OPEN cv FOR l_stmt;
1021 LOOP
1022 FETCH cv into l_measureID, l_measureCol;
1023 EXIT WHEN cv%NOTFOUND;
1024 NumOperands := BSC_MO_HELPER_PKG.GetFieldExpression(Operands, l_measureCol);
1025 i:= Operands.first;
1026 LOOP
1027 EXIT WHEN Operands.count =0 ;
1028 IF BSC_MO_HELPER_PKG.SearchStringExists(arrMeasuresCols, arrMeasuresCols.count, Operands(i)) THEN
1029 --One operand of the formula is one of the measures of a indicator flagged with 4
1030 --We need to add this formula (measure) to the related ones
1031 arrRelatedMeasuresIds(arrRelatedMeasuresIds.count+1) := l_measureID;
1032 END IF;
1033 EXIT WHEN i = Operands.last;
1034 i:= Operands.next(i);
1035 END LOOP;
1036 END Loop;
1037 CLOSE cv;
1038 --Now we need to add to the indicator list all the indicators using any of the measures
1039 --in arrRelatedMeasuresIds()
1040 IF arrRelatedMeasuresIds.count > 0 THEN
1041 strWhereInMeasures := BSC_DBGEN_UTILS.Get_New_Big_In_Cond_Number( 9, 'MEASURE_ID');
1042 i:= arrRelatedMeasuresIds.first;
1043 LOOP
1044 EXIT WHEN i=arrRelatedMeasuresIds.last;
1045 BSC_DBGEN_UTILS.Add_Value_Big_In_Cond_Number( 9, arrRelatedMeasuresIds(i));
1046 i:= arrRelatedMeasuresIds.next(i);
1047 END LOOP;
1048 l_stmt := 'SELECT DISTINCT INDICATOR FROM BSC_DB_MEASURE_BY_DIM_SET_V '||
1049 ' WHERE ('|| strWhereInMeasures || ')';
1050 open cv for L_stmt;
1051 LOOP
1052 FETCH cv into l_indicator_id;/*Indicator*/
1053 EXIT WHEN cv%NOTFOUND;
1054 IF Not bsc_mo_helper_pkg.SearchNumberExists(l_fact_ids, l_fact_ids.count, l_indicator_id) THEN
1055 l_fact_ids(l_fact_ids.count+1) := l_indicator_id;
1056 END IF;
1057 END Loop;
1058 CLOSE cv;
1059 END IF;
1060 return Get_Fact_Info(null, null, l_fact_ids);
1061 EXCEPTION WHEN OTHERS THEN
1062 bsc_mo_helper_pkg.writeTmp('Exception in Get_Facts_To_Recalculate : '||sqlerrm, FND_LOG.LEVEL_EXCEPTION, true);
1063 raise;
1064 END;
1065
1066 FUNCTION Fact_ID_Exists(p_facts IN BSC_DBGEN_STD_METADATA.tab_clsFact, p_fact_id IN NUMBER) RETURN BOOLEAN IS
1067 BEGIN
1068 IF (p_facts.count=0) THEN
1069 return false;
1070 END IF;
1071 FOR i IN p_facts.first..p_facts.last LOOP
1072 IF (p_facts(i).fact_id = p_fact_id) THEN
1073 return true;
1074 END IF;
1075 END LOOP;
1076 return false;
1077 END;
1078
1079 -- PUBLIC APIs
1080
1081 --first find the highest S table for this kpi, dim_set, then reuse get_levels_for_table api
1082 --note we ignore the periodicity here
1083 FUNCTION get_highest_s_table(p_fact IN VARCHAR2, p_dim_set IN NUMBER) return VARCHAR2 IS
1084 CURSOR cSTable(p_table varchar2) IS
1085 select table_name, count(1) ct from bsc_db_calculations
1086 where table_name like p_table
1087 and calculation_type=4
1088 group by table_name
1089 having count(1)=
1090 (
1091 select max(ct) from(
1092 select table_name, count(1) ct from bsc_db_calculations
1093 where table_name like p_table
1094 and calculation_type=4
1095 group by table_name )
1096 );
1097
1098 l_s_tablename VARCHAR2(300);
1099 l_dummy number;
1100 BEGIn
1101 OPEN cSTable('BSC_S_'||p_fact||'_'||p_dim_set||'%');
1102 FETCH cSTable INTO l_s_tablename, l_dummy;
1103 CLOSE cSTable;
1104 return l_s_tablename;
1105 EXCEPTION WHEN OTHERS THEN
1106 g_error := sqlerrm;
1107 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.get_highest_s_table '||g_error);
1108 RAISE;
1109 END;
1110
1111 FUNCTION get_lowest_s_table(p_fact IN VARCHAR2, p_dim_set IN NUMBER) return VARCHAR2 IS
1112 CURSOR cSTable(p_fact_pattern varchar2, p_s_pattern varchar2) IS
1113 select table_name from bsc_db_Tables_rels
1114 where table_name like p_fact_pattern
1115 and source_table_name not like p_s_pattern;
1116 l_s_tablename VARCHAR2(300);
1117 BEGIn
1118 OPEN cSTable('BSC_S_'||p_fact||'_'||p_dim_set||'%', 'BSC_S%');
1119 FETCH cSTable INTO l_s_tablename;
1120 CLOSE cSTable;
1121 return l_s_tablename;
1122 END;
1123
1124 FUNCTION Get_Facts_To_Process(p_process_id IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsFact IS
1125 l_fact_list BSC_DBGEN_STD_METADATA.tab_clsFact;
1126 l_fact_list_temp BSC_DBGEN_STD_METADATA.tab_clsFact;
1127 BEGIN
1128 l_fact_list := Get_Facts_To_Recreate(p_process_id);
1129 l_fact_list_temp := Get_Facts_To_Delete(p_process_id);
1130 IF l_fact_list_temp.count >0 THEN
1131 FOR i IN l_fact_list_temp.first..l_fact_list_temp.last LOOP
1132 IF fact_id_exists(l_fact_list, l_fact_list_temp(i).fact_id)=false THEN
1133 l_fact_list(l_fact_list.count+1) := l_fact_list_temp(i);
1134 END IF;
1135 END LOOP;
1136 END IF;
1137 l_fact_list_temp := Get_Facts_To_recalculate(p_process_id);
1138 IF l_fact_list_temp.count >0 THEN
1139 FOR i IN l_fact_list_temp.first..l_fact_list_temp.last LOOP
1140 IF fact_id_exists(l_fact_list, l_fact_list_temp(i).fact_id)=false THEN
1141 l_fact_list(l_fact_list.count+1) := l_fact_list_temp(i);
1142 END IF;
1143 END LOOP;
1144 END IF;
1145 return l_fact_list;
1146 EXCEPTION WHEN OTHERS THEN
1147 g_error := sqlerrm;
1148 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.get_lowest_s_table'||g_error);
1149 RAISE;
1150 END;
1151
1152
1153
1154 FUNCTION Get_Measures_For_Fact_dbgen(p_fact IN VARCHAR2, p_dim_set IN NUMBER) return BSC_DBGEN_STD_METADATA.tab_clsMeasure IS
1155 l_stmt VARCHAR2(1000);
1156 l_measure_name varchar2(1000);
1157 measures dbms_sql.varchar2_table;
1158 l_num_measures NUMBER;
1159 l_aggregation_method varchar2(1000);
1160 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
1161 l_measure_null BSC_DBGEN_STD_METADATA.clsMeasure;
1162 colMeasures BSC_DBGEN_STD_METADATA.tab_clsMeasure;
1163 i NUMBER;
1164 msg VARCHAR2(1000);
1165
1166 pFormulaSource VARCHAR2(1000);
1167 pAvgL VARCHAR2(1000);
1168 pAvgLTotal VARCHAR2(1000);
1169 pAvgLCounter VARCHAR2(1000);
1170 FuncAgregSingleColumn VARCHAR2(1000);
1171 pAvgLSingleColumn VARCHAR2(1000);
1172 AvgLTotalColumn VARCHAR2(1000);
1173 AvgLCounterColumn VARCHAR2(1000);
1174 baseColumn dbms_sql.varchar2_table;
1175
1176 l_stmt2 VARCHAR2(1000):= 'SELECT M.MEASURE_COL, NVL(M.OPERATION, ''SUM'') AS OPER,
1177 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :1) AS PFORMULASOURCE,
1178 NVL(BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :2 ),''N'') AS PAVGL,
1179 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :3) AS PAVGLTOTAL,
1180 BSC_APPS.GET_PROPERTY_VALUE(M.S_COLOR_FORMULA, :4) AS PAVGLCOUNTER,
1181 M.source
1182 FROM BSC_SYS_MEASURES M, BSC_DB_MEASURE_BY_DIM_SET_V I
1183 WHERE I.MEASURE_ID = M.MEASURE_ID
1184 AND I.MEASURE_COL = M.MEASURE_COL
1185 AND I.DIM_SET_ID = :5
1186 AND I.INDICATOR = :6
1187 AND M.TYPE = 0
1188 AND NVL(M.SOURCE, ''BSC'') in(''PMF'', ''BSC'') ';
1189 TYPE CurTyp IS REF CURSOR;
1190 cv CurTyp;
1191 l_measure_source varchar2(30);
1192 BEGIN
1193 bsc_mo_helper_pkg.writeTmp( 'Inside GetMeasuresForFact, System time is '||bsc_mo_helper_pkg.get_time, fnd_log.level_statement, true);
1194 OPEN cv for l_stmt2 USING BSC_METADATA_OPTIMIZER_PKG.C_PFORMULASOURCE,
1195 BSC_METADATA_OPTIMIZER_PKG.C_PAVGL,
1196 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLTOTAL,
1197 BSC_METADATA_OPTIMIZER_PKG.C_PAVGLCOUNTER, p_dim_set, to_number(p_fact);
1198
1199 LOOP
1200 FETCH cv INTO l_measure_name, l_aggregation_method, pFormulaSource, pAvgL, pAvgLTotal, pAvgLCounter, l_measure_source ;
1201 EXIT WHEN cv%NOTFOUND;
1202 Measures := BSC_DBGEN_UTILS.get_measure_list(l_measure_name);
1203 l_num_measures := Measures.count;
1204 i := Measures.first;
1205 LOOP
1206 EXIT WHEN Measures.count = 0;
1207 If sys_measure_exists(Measures(i), l_measure_source) Then
1208 If Not measure_exists(colMeasures, Measures(i), l_measure_source) Then
1209 --Get the aggregation function and Avgl flag of the column (single column)
1210 Get_Aggregate_Function (Measures(i), FuncAgregSingleColumn, pAvgLSingleColumn, AvgLTotalColumn, AvgLCounterColumn);
1211 If FuncAgregSingleColumn IS NULL Then
1212 FuncAgregSingleColumn := l_aggregation_method;
1213 END IF;
1214 If pAvgLSingleColumn IS NULL Then
1215 pAvgLSingleColumn := pAvgL;
1216 END IF;
1217 l_measure := l_measure_null;
1218 l_measure.measure_Name := Measures(i);
1219 l_measure.AGGREGATION_method := FuncAgregSingleColumn;
1220 l_measure.datatype := 'NUMBER';
1221 l_measure.measure_source := l_measure_source;
1222 --l_measure.Origen is not set
1223 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_SINGLE_COLUMN, pAvgLSingleColumn);
1224 If pAvgLSingleColumn = 'Y' Then
1225 --This is a single column, we can have AvgL on a single column.
1226 --We need two internal columns: one for total and one for counter
1227 --Also we need to add the internal columns in gLov and in
1228 --BSC_DB_MEASURES_COLS_TL table
1229 baseColumn(0) := Measures(i);
1230 If AvgLTotalColumn IS NULL Then
1231 AvgLTotalColumn := get_Next_Internal_Column_Name;
1232 --Update the measure property pAvgLTotal in the database
1233 SetMeasurePropertyDB (Measures(i), BSC_METADATA_OPTIMIZER_PKG.C_PAVGLTOTAL, AvgLTotalColumn);
1234 END IF;
1235 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_TOTAL_COLUMN, AvgLTotalColumn);
1236 --AddInternalColumnInDB(AvgLTotalColumn, 2, baseColumn, 1);
1237 If AvgLCounterColumn IS NULL Then
1238 AvgLCounterColumn := get_Next_Internal_Column_Name;
1239 --Update the measure property pAvgLCounter in the database
1240 SetMeasurePropertyDB (Measures(i), BSC_METADATA_OPTIMIZER_PKG.C_PAVGLCOUNTER, AvgLCounterColumn);
1241 END IF;
1242 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_COUNTER_COLUMN, AvgLCounterColumn);
1243 --AddInternalColumnInDB(AvgLCounterColumn, 3, baseColumn, 1);
1244 END IF;
1245 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 0); -- Normal
1246 colMeasures(colMeasures.count+1) := l_measure;
1247
1248 If pAvgLSingleColumn = 'Y' Then
1249 --Add the two internal column for AvgL in the collection
1250 --Column for Total
1251 l_measure := l_measure_null;
1252 l_measure.measure_name := AvgLTotalColumn;
1253 l_measure.aggregation_method := 'SUM';
1254 l_measure.datatype := 'NUMBER';
1255 --l_measure.Origen is not set
1256 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_FLAG, 'N');
1257 --l_measure.avgLTotalColumn does not apply
1258 --l_measure.avgLCounterColumn does not apply
1259
1260 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 2); --Internal column for Total of AvgL
1261 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_SOURCE, Measures(i));
1262 colMeasures(colMeasures.count+1) := l_measure;
1263 --Column for Counter
1264 l_measure := l_measure_null;
1265 l_measure.measure_Name := AvgLCounterColumn;
1266 l_measure.AGGREGATION_method := 'SUM';
1267 l_measure.datatype := 'NUMBER';
1268 --l_measure.Origen is not set
1269 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_FLAG, 'N');
1270 --l_measure.avgLTotalColumn does not apply
1271 --l_measure.avgLCounterColumn does not apply
1272 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 3); --Internal column for Counter of AvgL
1273 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_SOURCE, Measures(i));
1274 colMeasures(colMeasures.count+1) := l_measure;
1275 END IF;
1276 END IF;
1277
1278 ELSE
1279 raise bsc_metadata_optimizer_pkg.optimizer_exception ;
1280 EXIT ;
1281 END IF;
1282 EXIT WHEN i = Measures.last;
1283 i := Measures.next(i);
1284 END LOOP;
1285
1286 --Now add internal column if the formula needs to calculated in another column
1287 If pFormulaSource IS NOT NULL Then
1288 --Add the internal column in gLov and in BSC_DB_MEASURES_COLS_TL table
1289 --AddInternalColumnInDB(pFormulaSource, 1, Measures, l_num_measures);
1290 l_measure := l_measure_null;
1291 l_measure.measure_Name := pFormulaSource;
1292 l_measure.aggregation_method := l_aggregation_method;
1293 l_measure.datatype := 'NUMBER';
1294 --l_measure.Origen is not set
1295 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_FLAG, pAvgL);
1296 If pAvgL = 'Y' Then
1297 --This is a formula calculated in another column, we can have AvgL on a that.
1298 --We need to internal columns: one for total and one for counter
1299 --Also we need to add the internal columns in gLov and in
1300 --BSC_DB_MEASURES_COLS_TL table
1301 If pAvgLTotal IS NULL Then
1302 pAvgLTotal := get_Next_Internal_Column_Name ;
1303 --Update the measure property pAvgLTotal in the database
1304 SetMeasurePropertyDB( l_measure_name, BSC_METADATA_OPTIMIZER_PKG.C_PAVGLTOTAL, pAvgLTotal);
1305 END IF;
1306 --AddInternalColumnInDB(pAvgLTotal, 2, Measures, l_num_measures);
1307 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_TOTAL_COLUMN, pAvgLTotal);
1308 If pAvgLCounter IS NULL Then
1309 pAvgLCounter := get_Next_Internal_Column_Name;
1310 --Update the measure property pAvgLTotal in the database
1311 SetMeasurePropertyDB( l_measure_name, BSC_METADATA_OPTIMIZER_PKG.C_PAVGLCOUNTER, pAvgLCounter);
1312 END IF;
1313 --AddInternalColumnInDB( pAvgLCounter, 3, Measures, l_num_measures);
1314 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_COUNTER_COLUMN, pAvgLCounter);
1315 END IF;
1316 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 1); --Internal column for formula
1317 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_SOURCE, l_measure_name); -- Formula Example A/
1318 colMeasures(colMeasures.last +1 ) := l_measure;
1319 If pAvgL = 'Y' Then
1320 --Add the two internal column for AvgL in the collection
1321 --Bug 2993089: When the column is not a formula but has the option
1322 --Apply rollup to formula', the columns for Average at lowest level
1323 --are already in colCamporDatos.
1324 --We need to evaluate this situation adding te condition
1325 --If Not Existel_measure(colMeasures, <internal column for AvgL>)
1326 --Column for Total
1327 If Not measure_exists(colMeasures, pAvgLTotal, 'BSC') Then
1328 l_measure := l_measure_null;
1329 l_measure.measure_Name := pAvgLTotal;
1330 l_measure.AGGREGATION_method := 'SUM';
1331 l_measure.datatype := 'NUMBER';
1332 --l_measure.Origen is not set
1333 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_FLAG, 'N');
1334 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 2); -- 'Internal column for Total of AvgL
1335 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_SOURCE, l_measure_name); -- Formula Example A/B
1336 colMeasures(colMeasures.last+1) := l_measure ;
1337 END IF;
1338 --Column for Counter
1339 If Not measure_exists(colMeasures, pAvgLCounter, 'BSC') Then
1340 l_measure := l_measure_null;
1341 l_measure.measure_name := pAvgLCounter;
1342 l_measure.AGGREGATION_METHOD := 'SUM';
1343 l_measure.datatype := 'NUMBER';
1344 --l_measure.Origen is not set
1345 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.AVGL_FLAG, 'N');
1346 --l_measure.avgLTotalColumn does not apply
1347 --l_measure.avgLCounterColumn does not apply
1348 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_TYPE, 3); --Internal column for Counter of AvgL
1349 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.INTERNAL_COLUMN_SOURCE, l_measure_name); -- Formula Example A/B
1350 colMeasures(colMeasures.last+1) := l_measure ;
1351 END IF;
1352 END IF;
1353 END IF;
1354 END Loop;
1355 close cv;
1356
1357 bsc_mo_helper_pkg.writeTmp( 'Compl. GetMeasuresForFact, System time is '||bsc_mo_helper_pkg.get_time, fnd_log.level_statement, true);
1358 return colMeasures;
1359 EXCEPTION WHEN OTHERS THEN
1360 g_error := sqlerrm;
1361 fnd_file.put_line(fnd_file.log, 'Exception in bsc_dbgen_bsc_reader.get_measures_for_fact, p_fact='||p_fact||', dimset='||p_dim_set||g_error);
1362 RAISE;
1363 END;
1364
1365 FUNCTION Get_Measures_For_Fact(p_fact IN VARCHAR2, p_dim_set IN NUMBER, p_include_derived_columns IN BOOLEAN default false) return BSC_DBGEN_STD_METADATA.tab_clsMeasure IS
1366
1367 CURSOR cMeasureList IS
1368 SELECT M.MEASURE_COL, NVL(M.OPERATION, 'SUM') AS OPER, m.source measure_source
1369 FROM BSC_SYS_MEASURES M, BSC_DB_MEASURE_BY_DIM_SET_V I
1370 WHERE I.MEASURE_ID = M.MEASURE_ID
1371 AND I.DIM_SET_ID = p_dim_set
1372 AND I.INDICATOR = to_number(p_fact)
1373 AND M.TYPE = 0
1374 AND NVL(M.SOURCE, 'BSC') in('PMF', 'BSC');
1375
1376 CURSOR cProperties(p_col VARCHAR2) IS
1377 SELECT sysm.measure_id, nvl(COLS.MEASURE_GROUP_ID,-1) measure_group_id, nvl(COLS.PROJECTION_ID, 0) projection_id , NVL(COLS.MEASURE_TYPE, 1) MEASURE_TYPE
1378 FROM BSC_DB_MEASURE_COLS_VL COLS , BSC_SYS_MEASURES sysm
1379 WHERE sysm.measure_col = cols.measure_col(+)
1380 AND sysm.measure_col = p_col;
1381 l_measure_row cProperties%ROWTYPE;
1382 ColMeasures BSC_DBGEN_STD_METADATA.tab_clsMeasure;
1383 l_num_measures NUMBER;
1384 l_measures_list DBMS_SQL.VARCHAR2_TABLE;
1385 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
1386 l_measure_null BSC_DBGEN_STD_METADATA.clsMeasure;
1387
1388 BEGIN
1389 IF (p_include_derived_columns) THEN
1390 return get_all_measures_for_fact(p_fact, p_dim_set);
1391 END IF;
1392 --BSC-PMF Integration: Even though a PMF measure cannot be present in a BSC
1393 --dimension set, I am going to do the validation to filter out PMF measures
1394 FOR i IN cMeasureList LOOP
1395 l_measures_list := BSC_DBGEN_UTILS.get_measure_list(i.measure_col);
1396 l_num_measures := l_measures_list.count;
1397 IF (l_measures_list.count>0) THEN
1398 FOR j IN l_measures_list.first..l_measures_list.last LOOP
1399 If Not measure_exists(colMeasures, l_measures_list(j), i.measure_source) Then
1400 --Get the aggregation function and Avgl flag of the column (single column)
1401 OPEN cProperties(l_measures_list(j));
1402 FETCH cProperties INTO l_measure_row;
1403 CLOSE cProperties;
1404 l_measure := l_measure_null;
1405 l_measure.measure_Name := l_measures_list(j);
1406 l_measure.aggregation_method := i.oper;
1407 l_measure.datatype := 'NUMBER';
1408 l_measure.measure_id := l_measure_row.measure_id;
1409 l_measure.measure_source := i.measure_source;
1410 -- Possible measure type values
1411 --1: Statistic
1412 --2: Balance
1413 l_measure.Measure_Type := l_measure_row.measure_type;
1414 l_measure.measure_group := l_measure_row.measure_group_id;
1415 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID, l_measure_row.projection_id);
1416 colMeasures(colMeasures.count+1) := l_measure;
1417 END IF;
1418 END LOOP;
1419 END IF;
1420 END LOOP;
1421 return colMeasures;
1422
1423 EXCEPTION WHEN OTHERS THEN
1424 fnd_file.put_line(FND_FILE.LOG, 'Error in Get_Measures_For_Fact:fact='||p_fact||', error='||sqlerrm);
1425 raise;
1426 END;
1427
1428 --****************************************************************************
1429 --GetPeriodicities: GetColPeriodicidadesIndic
1430 -- DESCRIPTION:
1431 -- Get the collection of periodicity codes of the indicator
1432 -- PARAMETERS:
1433 -- Indic: indicator code
1434 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
1435 --***************************************************************************
1436
1437 FUNCTION Get_Periodicities_For_Fact(p_fact IN VARCHAR2) RETURN BSC_DBGEN_STD_METADATA.tab_ClsPeriodicity IS
1438 colPeriodicities BSC_DBGEN_STD_METADATA.tab_ClsPeriodicity;
1439 CURSOR cPeriodicities IS
1440 SELECT kpi.PERIODICITY_ID, NVL(TARGET_LEVEL, 1) AS TARGET_LEVEL, s.calendar_id
1441 FROM BSC_KPI_PERIODICITIES kpi, bsc_sys_periodicities s
1442 WHERE
1443 kpi.periodicity_id = s.periodicity_id
1444 AND kpi.INDICATOR = to_number(p_fact)
1445 ORDER BY PERIODICITY_ID;
1446 l_periodicity BSC_DBGEN_STD_METADATA.ClsPeriodicity ;
1447 cRow cPeriodicities%ROWTYPE;
1448 BEGIN
1449
1450 OPEN cPeriodicities;
1451 LOOP
1452 FETCH cPeriodicities INTO cRow;
1453 EXIT WHEN cPeriodicities%NOTFOUND;
1454 l_periodicity.periodicity_id := cRow.periodicity_id;
1455 l_periodicity.calendar_id := cRow.calendar_id;
1456 bsc_dbgen_utils.add_property(l_periodicity.properties, BSC_DBGEN_STD_METADATA.TARGET_LEVEL, cRow.target_level);
1457 colPeriodicities(colPeriodicities.count+1) := l_periodicity;
1458 END LOOP;
1459 close cPeriodicities;
1460 colPeriodicities := configure_parent_periods(colPeriodicities);
1461 return colPeriodicities;
1462 EXCEPTION WHEN OTHERS THEN
1463
1464 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_Periodicities_For_Fact:fact='||p_fact||',error='||sqlerrm);
1465 raise;
1466 End;
1467
1468
1469 --****************************************************************************
1470 --
1471 --
1472 -- DESCRIPTION:
1473 -- Get the collection of drill families of the indicator
1474 --
1475 -- PARAMETERS:
1476 -- Indic: indicator code
1477 -- p_dim_set: p_dim_set
1478 --
1479 -- AUTHOR/DATE - MODIFICATIONS (AUTHOR/DATE/DESCRIPTION):
1480 --***************************************************************************
1481 Function get_dimensions_for_fact(p_fact IN VARCHAR2, p_dim_set IN NUMBER, p_include_missing_levels IN boolean)
1482 RETURN BSC_DBGEN_STD_METADATA.tab_clsDimension IS
1483
1484 l_dimensions BSC_DBGEN_STD_METADATA.tab_clsDimension;
1485 DimensionLevels BSC_DBGEN_STD_METADATA.clsDimension;
1486 l_missing_levels DBMS_SQL.VARCHAR2_TABLE;
1487 cLevel BSC_DBGEN_STD_METADATA.clsLevel;
1488
1489 Level_null BSC_DBGEN_STD_METADATA.clsLevel;
1490 Parents1N varchar2(1000);
1491 ParentsMN varchar2(1000);
1492 tParents1N varchar2(1000);
1493 tParentsMN varchar2(1000);
1494
1495 l_level_index NUMBER;
1496 l_level_table VARCHAR2(1000);
1497 l_level_pk VARCHAR2(1000);
1498 l_level_name VARCHAR2(1000);
1499 l_level_id NUMBER;
1500 l_level_fk VARCHAR2(100);
1501 TargetLevel NUMBER;
1502 l_stmt varchar2(1000);
1503 l_dimension_index NUMBER;
1504 msg VARCHAR2(1000);
1505 l_count number;
1506 l_ct Number;
1507 TYPE CurTyp IS REF CURSOR;
1508 cv CurTyp;
1509 l_group_id NUMBER := 0;
1510
1511 cursor cMissing(p_missing_level VARCHAR2) IS
1512 SELECT DISTINCT LEVEL_PK_COL, NAME, 1 TAR_LEVEL
1513 FROM BSC_SYS_DIM_LEVELS_VL WHERE LEVEL_TABLE_NAME = p_missing_level;
1514 l_missing_level_info cMissing%ROWTYPE;
1515 l_missing_level BSC_DBGEN_STD_METADATA.clsLevel;
1516 l_current_level_index NUMBER := 0;
1517
1518 l_level_parent BSC_DBGEN_STD_METADATA.clsLevel;
1519 l_level_null BSC_DBGEN_STD_METADATA.clsLevel;
1520
1521 BEGIN
1522 l_stmt := 'SELECT DISTINCT kpidim.DIM_LEVEL_INDEX, kpidim.LEVEL_TABLE_NAME, kpidim.LEVEL_PK_COL, kpidim.NAME, NVL(kpidim.TARGET_LEVEL,1) AS TAR_LEVEL' ||
1523 ' , sysdim.dim_level_id, kpidim.parent_level_rel FROM BSC_KPI_DIM_LEVELS_VL kpidim, BSC_SYS_DIM_LEVELS_B sysdim
1524 WHERE
1525 kpidim.level_table_name = sysdim.level_table_name
1526 AND kpidim.INDICATOR = :1 AND kpidim.DIM_SET_ID = :2 AND kpidim.STATUS = 2';
1527
1528 IF IsIndicatorBalanceOrPnL(to_number(p_fact)) Then
1529 --The level 0 which is the Type of Account drill is excluded. This drill is
1530 --not considered to generate the tables
1531 l_stmt:= l_stmt||' AND DIM_LEVEL_INDEX <> 0';
1532 END IF;
1533 l_stmt := l_stmt||' ORDER BY DIM_LEVEL_INDEX';
1534 OPEN cv FOR l_stmt using to_number(p_fact), p_dim_set;
1535 LOOP
1536 Fetch cv into l_level_index, l_level_table, l_level_pk, l_level_name, TargetLevel, l_level_id, l_level_fk ;
1537 EXIT WHEN cv%NOTFOUND;
1538 cLevel := level_null;
1539 cLevel := get_level_info(l_level_table);
1540 cLevel.level_id := l_level_id;
1541 cLevel.level_pk := l_level_pk;
1542 cLevel.level_table_name := l_level_table;
1543 cLevel.level_Name := l_level_table;
1544 cLevel.level_fk := l_level_Fk;
1545 bsc_dbgen_utils.add_property(cLevel.properties, BSC_DBGEN_STD_METADATA.TARGET_LEVEL, TargetLevel);
1546 l_dimension_index := get_dimension_index(l_dimensions, l_level_table, p_include_missing_levels, l_missing_levels);
1547 --Get the index of the drill family which this drill belongs to.
1548 If l_dimension_index <> -1 Then
1549 --Level belongs to family l_dimension_index.
1550 -- If there are missing levels, add it to the list of levels
1551 IF (l_missing_levels.count<>0) THEN
1552 FOR i IN l_missing_levels.first..l_missing_levels.last LOOP
1553 OPEN cMissing(l_missing_levels(i));
1554 FETCH cMissing INTO l_missing_level_info;
1555 CLOSE cMissing;
1556 l_missing_level := level_null;
1557 l_missing_level.level_pk := l_missing_level_info.level_pk_col;
1558 l_missing_level.level_table_name := l_missing_levels(i);
1559 l_missing_level.level_name := l_missing_levels(i);
1560 bsc_dbgen_utils.add_property(l_missing_level.properties, BSC_DBGEN_STD_METADATA.MISSING_LEVEL, 'Y');
1561 l_current_level_index := l_current_level_index + 1;
1562 l_missing_level.level_index := l_current_level_index ;
1563 l_dimensions(l_dimensions.count).Hierarchies(1).Levels(l_current_level_index) := l_missing_level;
1564 END LOOP;
1565 ELSE
1566 l_current_level_index := l_current_level_index+1;
1567 END IF;
1568 -- needed to handle missing levels
1569 cLevel.level_index := l_current_level_index;
1570 --Review target levels
1571 IF bsc_dbgen_utils.get_property_value(cLevel.properties, BSC_DBGEN_STD_METADATA.TARGET_LEVEL) = '1' Then
1572 --If target apply to this level, then
1573 --it must apply for all parents
1574 IF l_dimensions(l_dimension_index).Hierarchies(1).Levels.count>0 THEN
1575 FOR j IN l_dimensions(l_dimension_index).Hierarchies(1).Levels.first..l_dimensions(l_dimension_index).Hierarchies(1).Levels.last LOOP
1576 bsc_dbgen_utils.add_property(l_dimensions(l_dimension_index).Hierarchies(1).Levels(j).properties, BSC_DBGEN_STD_METADATA.TARGET_LEVEL, 1);
1577 END LOOP;
1578 END IF;
1579 END IF;
1580 -- set parent levels
1581 l_count := l_dimensions(l_dimension_index).hierarchies(1).levels.first;
1582 LOOP
1583 EXIT WHEN l_dimensions(l_dimension_index).hierarchies(1).levels.count= 0;
1584 l_level_parent := l_level_null;
1585 l_level_parent := l_dimensions(l_dimension_index).hierarchies(1).levels(l_count);
1586 If is_parent_1N(l_level_table, l_level_parent.level_name) Then
1587 --There is 1n relationship with this drill
1588 cLevel.Parents1N(cLevel.Parents1N.count+1) := l_level_parent.level_name;
1589 --The 1n relations of the parent drill are also (by transitivity)
1590 --1n with the current drill
1591 IF (l_level_parent.parents1N.count>0)THEN
1592 FOR j IN l_level_parent.parents1N.first..l_level_parent.parents1N.last LOOP
1593 cLevel.Parents1N(cLevel.Parents1N.count+1) := l_level_parent.parents1N(j);
1594 END LOOP;
1595 END IF;
1596 END IF;
1597 EXIT WHEN l_count = l_dimensions(l_dimension_index).hierarchies(1).levels.last;
1598 l_count := l_dimensions(l_dimension_index).hierarchies(1).levels.next(l_count);
1599 END LOOP;
1600 l_dimensions(l_dimensions.count).Hierarchies(1).Levels(l_current_level_index) := cLevel;
1601 ELSE
1602 --The Level does not belong to any family previously created.
1603 --So, create a new dimension with this Level
1604 --Review target level
1605 --This is the first Level in this family, then target must apply
1606 l_current_level_index := 1;
1607 cLevel.level_index := l_current_level_index;
1608 bsc_dbgen_utils.add_property(cLevel.properties, BSC_DBGEN_STD_METADATA.TARGET_LEVEL, 1);
1609 l_dimensions(l_dimensions.count+1).Hierarchies(1).Levels(1) := cLevel;
1610 END IF;
1611 END Loop;
1612 close cv;
1613
1614 return l_dimensions;
1615 EXCEPTION WHEN OTHERS THEN
1616 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_Dimensions_For_Fact:fact='||p_fact||', dimset='||p_dim_set||', missing levels='||bsc_mo_helper_pkg.boolean_decode(p_include_missing_levels)||', error='||sqlerrm);
1617 raise;
1618 END;
1619
1620
1621 function get_parents_for_level(
1622 p_level_name varchar2,
1623 p_num_levels number default 1000000
1624 ) RETURN BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship IS
1625 CURSOR cParents IS
1626 select parent_lvl.level_table_name parent_level, lvl.level_table_name child_level, 'CODE' parent_pk, parent_lvl.level_pk_col child_fk, level
1627 from
1628 bsc_sys_dim_level_rels rels,
1629 bsc_sys_dim_levels_b lvl,
1630 bsc_sys_dim_levels_b parent_lvl
1631 where
1632 lvl.dim_level_id = rels.dim_level_id and
1633 rels.parent_dim_level_id = parent_lvl.dim_level_id and
1634 rels.relation_type <> 2 and
1635 level <= p_num_levels
1636 connect by rels.dim_level_id= PRIOR rels.parent_dim_level_id
1637 and rels.relation_type<>2
1638 and rels.dim_level_id <> rels.parent_dim_level_id
1639 start with rels.dim_level_id in
1640 (select dim_level_id from bsc_sys_dim_levels_b where level_table_name = p_level_name)
1641 order by level;
1642
1643 l_lvl_rel BSC_DBGEN_STD_METADATA.ClsLevelRelationship;
1644 l_tab_rels BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship;
1645 l_count NUMBER := 1;
1646 BEGIN
1647 FOR i IN cParents
1648 LOOP
1649 l_lvl_rel.Parent_Level := i.parent_level;
1650 l_lvl_rel.child_level := i.child_level;
1651 l_lvl_rel.child_level_fk := i.child_fk;
1652 l_lvl_rel.Parent_Level_pk := i.parent_pk;
1653 l_tab_rels(l_count) := l_lvl_rel;
1654 l_count := l_count + 1;
1655 END LOOP;
1656 return l_tab_rels;
1657 EXCEPTION WHEN OTHERS THEN
1658 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_Parents_For_Level:p_level='||p_level_name||', p_num_levels='||p_num_levels||', error='||sqlerrm);
1659 raise;
1660 END;
1661
1662 function get_children_for_level(
1663 p_level_name varchar2,
1664 p_num_levels number default 1000000
1665 ) RETURN BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship IS
1666 CURSOR cChildren IS
1667 select parent_lvl.level_table_name parent_level, lvl.level_table_name child_level, 'CODE' parent_pk, rels.relation_col child_fk, level
1668 from
1669 bsc_sys_dim_level_rels rels,
1670 bsc_sys_dim_levels_b lvl,
1671 bsc_sys_dim_levels_b parent_lvl
1672 where
1673 lvl.dim_level_id = rels.dim_level_id and
1674 rels.parent_dim_level_id = parent_lvl.dim_level_id and
1675 rels.relation_type <> 2 and
1676 level <= p_num_levels
1677 connect by PRIOR rels.dim_level_id||rels.relation_type = rels.parent_dim_level_id||1
1678 and rels.dim_level_id <> rels.parent_dim_level_id
1679 start with rels.parent_dim_level_id in
1680 (select dim_level_id from bsc_sys_dim_levels_b where level_table_name = p_level_name)
1681 order by level;
1682 l_lvl_rel BSC_DBGEN_STD_METADATA.ClsLevelRelationship;
1683 l_tab_rels BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship;
1684 BEGIN
1685 FOR i IN cChildren
1686 LOOP
1687 l_lvl_rel.Parent_Level := i.parent_level;
1688 l_lvl_rel.child_level := i.child_level;
1689 l_lvl_rel.child_level_fk := i.child_fk;
1690 l_lvl_rel.Parent_Level_pk := i.parent_pk;
1691 l_tab_rels(l_tab_rels.count + 1) := l_lvl_rel;
1692 END LOOP;
1693 return l_tab_rels;
1694 EXCEPTION WHEN OTHERS THEN
1695 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.get_children_for_level:p_level='||p_level_name||', p_num_levels='||p_num_levels||', error='||sqlerrm);
1696 raise;
1697 END;
1698
1699 function get_level_info(
1700 p_level varchar2
1701 ) return BSC_DBGEN_STD_METADATA.clsLevel is
1702 l_level BSC_DBGEN_STD_METADATA.clsLevel ;
1703 CURSOR c_level IS
1704 SELECT dim_level_id , level_pk_col
1705 FROM bsc_sys_dim_levels_b
1706 WHERE level_table_name = p_level;
1707 Begin
1708 l_level.Level_Name := p_level;
1709 OPEN c_level;
1710 FETCH c_level INTO l_level.Level_id, l_level.level_fk;
1711 CLOSE c_level;
1712 l_level.Level_PK := 'CODE';
1713 l_level.Level_PK_Datatype := BSC_DBGEN_UTILS.get_datatype(p_level, l_level.Level_PK);
1714 l_level.level_type := 0; -- normal
1715 return l_level;
1716 Exception when others then
1717 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_Level_Info:level='||p_level||', error='||sqlerrm);
1718 raise;
1719 End;
1720
1721 function get_facts_for_levels(p_levels dbms_sql.varchar2_table) return BSC_DBGEN_STD_METADATA.tab_clsFact is
1722 l_facts BSC_DBGEN_STD_METADATA.tab_clsFact ;
1723 l_fact BSC_DBGEN_STD_METADATA.clsFact;
1724 l_stmt VARCHAR2(1000);
1725 TYPE CurTyp IS REF CURSOR;
1726 cv CurTyp;
1727 l_dim_sets DBMS_SQL.NUMBER_TABLE;
1728 Begin
1729 IF (p_levels.count=0) THEN
1730 return l_facts;
1731 END IF;
1732 init;
1733 l_stmt := BSC_DBGEN_UTILS.Get_New_Big_In_Cond_Varchar2(1, 'level_table_name');
1734 For i IN p_levels.first..p_levels.last LOOP
1735 BSC_DBGEN_UTILS.Add_Value_Big_In_Cond_Varchar2 (1, p_levels(i));
1736 END LOOP;
1737 --insert the children
1738 l_stmt := 'SELECT distinct dim.INDICATOR, dim.DIM_SET_ID, kpi.name , ''BSC''
1739 FROM BSC_KPI_DIM_LEVELS_B dim, BSC_KPIS_VL kpi
1740 WHERE dim.indicator = kpi.indicator and ('|| l_stmt||') order by indicator, dim_set_id';
1741 OPEN cv FOR l_stmt;
1742 LOOP
1743 FETCH cv INTO l_fact.fact_id, l_fact.dimension_set(1), l_fact.fact_name, l_fact.application_short_name;
1744 EXIT WHEN cv%NOTFOUND;
1745 IF (l_facts.count>0) THEN
1746 -- if its the same fact, but different dim set, then add to dim_set
1747 IF (l_facts(l_facts.last).fact_id = l_fact.fact_id) THEN
1748 l_facts(l_facts.last).dimension_set(l_facts(l_facts.last).dimension_set.last+1) := l_fact.dimension_set(1);
1749 ELSE
1750 l_facts(l_facts.last+1) := l_fact;
1751 END IF;
1752 ELSE
1753 l_facts(l_facts.count+1) := l_fact;
1754 END IF;
1755 END LOOP;
1756 CLOSE cv;
1757 return l_facts;
1758 Exception when others then
1759 fnd_file.put_line(FND_FILE.LOG, 'Exception in get_facts_for_levels :'||sqlerrm);
1760 for i in p_levels.first..p_levels.last loop
1761 fnd_file.put_line(FND_FILE.LOG, 'Level '||i||':'||p_levels(i));
1762 end loop;
1763 raise;
1764 End;
1765
1766
1767 Function get_dim_sets_for_fact(p_fact IN VARCHAR2) return DBMS_SQL.NUMBER_TABLE IS
1768 l_dim_sets dbms_sql.number_table;
1769 l_dim_set NUMBER;
1770 CURSOR cDimSets IS
1771 SELECT DISTINCT DIM_SET_ID
1772 FROM BSC_DB_DATASET_DIM_SETS_V
1773 WHERE INDICATOR = to_number(p_fact)
1774 ORDER BY DIM_SET_ID;
1775 BEGIN
1776 OPEN cDimSets;
1777 LOOP
1778 FETCH cDimSets INTO l_dim_set;
1779 EXIT WHEN cDimSets%NOTFOUND;
1780 --BSC-PMF Integration: Only get BSC dimension sets
1781 If get_num_measures(p_fact, l_dim_set) > 0 Then
1782 l_dim_sets(l_dim_sets.count+1) := l_dim_set;
1783 END IF;
1784 END LOOP;
1785 CLOSE cDimSets;
1786 return l_dim_sets;
1787 Exception when others then
1788 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_dim_sets_for_fact:'||p_fact||':'||sqlerrm);
1789 raise;
1790 End;
1791
1792
1793 function get_s_views(
1794 p_fact IN VARCHAR2,
1795 p_dim_set IN NUMBER)
1796 return dbms_sql.varchar2_table is
1797 cursor cList is
1798 select distinct mv_name from bsc_kpi_data_tables
1799 where indicator = to_number(p_fact)
1800 and dim_set_id = p_dim_set
1801 and mv_name not like 'BSC_S_%ZMV';
1802 l_mv_list dbms_sql.varchar2_table ;
1803 Begin
1804 FOR i IN cList LOOP
1805 l_mv_list(l_mv_list.count+1) := i.mv_name;
1806 END LOOP;
1807 return l_mv_list;
1808 Exception when others then
1809 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_s_views:'||p_fact||','||p_dim_set||':'||sqlerrm);
1810 raise;
1811 End;
1812
1813
1814 function get_levels_for_table(
1815 p_table_name varchar2,
1816 p_table_type VARCHAR2) return BSC_DBGEN_STD_METADATA.tab_clsLevel is
1817 l_level BSC_DBGEN_STD_METADATA.clsLevel ;
1818 cursor cLevels(p_s_table VARCHAR2) IS
1819 select distinct dim_level_id, level_table_name, level_pk_col from bsc_db_tables_cols cols, bsc_sys_dim_levels_b lvl
1820 where
1821 cols.table_name like p_s_table
1822 and cols.column_type='P'
1823 and cols.column_name = lvl.level_pk_col;
1824 l_table_name VARCHAR2(100) ;
1825 l_level_list BSC_DBGEN_STD_METADATA.tab_clsLevel ;
1826 Begin
1827 IF (p_table_type='MV' or p_Table_type='VIEW') THEN
1828 IF (p_table_name like '%ZMV') THEN
1829 l_table_name :=substr(p_table_name, 1, instr(p_table_name, '_ZMV'))||'%';
1830 ELSE
1831 l_table_name :=substr(p_table_name, 1, instr(p_table_name, '_MV'))||'%';
1832 END IF;
1833 ELSE
1834 l_table_name := p_table_name;
1835 END IF;
1836 FOR i IN cLevels(l_table_name) LOOP
1837 l_level := get_level_info(l_table_name);
1838 l_level.level_id := i.dim_level_id;
1839 l_level.level_name := i.level_table_name;
1840 l_level.level_table_name := i.level_table_name;
1841 l_level.level_fk := i.level_pk_col;
1842 l_level.level_pk := 'CODE';
1843 l_level.level_pk_datatype := BSC_DBGEN_UTILS.get_datatype(l_level.level_table_name, l_level.level_pk);
1844 l_level_list(l_level_list.count+1) := l_level;
1845 END LOOP;
1846 return l_level_list;
1847 Exception when others then
1848 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_levels_for_Table:'||p_table_name||','||p_table_type||':'||sqlerrm);
1849 raise;
1850 End;
1851
1852
1853 --
1854 function column_exists_in_table (p_b_table in varchar2, p_column in varchar2) return boolean is
1855 l_count number;
1856 begin
1857 select count(1) into l_count from bsc_db_tables_cols where table_name=p_b_table and column_name=p_column;
1858 if (l_count>0) then
1859 return true;
1860 end if;
1861 return false;
1862 end;
1863
1864 -- used to see if an BSCIC column is from a B table
1865 function is_BSCIC_column_from_b_table(p_s_table in varchar2, p_b_table in varchar2, p_column in varchar2) return boolean is
1866 cursor cFormula is
1867 select source_formula
1868 from bsc_db_tables_cols
1869 where table_name=p_s_table
1870 and column_type='A'
1871 and column_name=p_column;
1872 l_column_name varchar2(400);
1873 begin
1874 open cFormula;
1875 fetch cFormula into l_column_name;
1876 close cFormula;
1877 l_column_name := replace(l_column_name, 'SUM(', '');
1878 l_column_name := replace(l_column_name, 'COUNT(', '');
1879 l_column_name := replace(l_column_name, ')', '');
1880 return column_exists_in_table(p_b_table, l_column_name);
1881 end;
1882
1883 function is_b_table_a_source(p_s_table in varchar2, p_b_table in varchar2) return boolean is
1884 l_count number;
1885 begin
1886 select count(1) into l_count from bsc_db_tables_rels
1887 where table_name = p_s_table and source_table_name=p_b_table;
1888 if l_count>0 then
1889 return true;
1890 end if;
1891 return false;
1892 end;
1893
1894 function get_b_table_measures_for_fact(
1895 p_fact varchar2,
1896 p_dim_set varchar2,
1897 p_base_table varchar2,
1898 p_include_derived_columns boolean)
1899 return BSC_DBGEN_STD_METADATA.tab_clsMeasure IS
1900 CURSOR cMeasures(p_s_table IN VARCHAR2) is
1901 select distinct s_table.column_name
1902 , s_table.source_formula
1903 , measures.MEASURE_GROUP_ID
1904 , measures.PROJECTION_ID
1905 , NVL(measures.MEASURE_TYPE, 1) MEASURE_TYPE
1906 , sysm.MEASURE_ID
1907 From bsc_db_tables_cols s_table,
1908 bsc_db_tables_cols b_table,
1909 BSC_DB_MEASURE_COLS_VL measures,
1910 BSC_SYS_MEASURES sysm
1911 where s_table.table_name = p_s_table
1912 and b_table.table_name = p_base_table
1913 and s_table.column_name = b_table.column_name
1914 and s_table.column_type = 'A'
1915 and measures.measure_col = s_table.column_name
1916 AND measures.measure_col = sysm.measure_col;
1917
1918 CURSOR cMeasuresIncludeDerived (p_s_table IN VARCHAR2)is
1919 select distinct s_table.column_name, s_table.source_formula,
1920 measures.MEASURE_GROUP_ID, measures.PROJECTION_ID, NVL(measures.MEASURE_TYPE, 1) MEASURE_TYPE,
1921 sysm.MEASURE_ID
1922 from
1923 bsc_db_tables_cols s_table,
1924 bsc_db_tables_cols b_table,
1925 BSC_DB_MEASURE_COLS_VL measures,
1926 BSC_SYS_MEASURES sysm
1927 where s_table.table_name =p_s_table
1928 and b_table.table_name = p_base_table
1929 and s_table.column_name = b_table.column_name
1930 and s_table.column_type = 'A'
1931 and measures.measure_col = s_table.column_name
1932 AND measures.measure_col = sysm.measure_col
1933 union all
1934 select distinct s_table.column_name, s_table.source_formula,
1935 measures.MEASURE_GROUP_ID, measures.PROJECTION_ID, NVL(measures.MEASURE_TYPE, 1) MEASURE_TYPE,
1936 sysm.MEASURE_ID
1937 from
1938 bsc_db_tables_cols s_table,
1939 bsc_db_tables_cols b_table,
1940 BSC_DB_MEASURE_COLS_VL measures,
1941 BSC_SYS_MEASURES sysm
1942 where s_table.table_name =p_s_table
1943 and b_table.table_name(+) = p_base_table
1944 and s_table.column_name = b_table.column_name(+)
1945 and s_table.column_name like 'BSCIC%'
1946 and s_table.column_type = 'A'
1947 and measures.measure_col = s_table.column_name
1948 AND measures.measure_col = sysm.measure_col(+);
1949 l_measure BSC_DBGEN_STD_METADATA.clsMeasure;
1950 l_measure_list BSC_DBGEN_STD_METADATA.tab_clsMeasure;
1951 -- there can be multiple Base tables feeding this kpi
1952 -- this may be because of different lowest level periodicities or different measures from diff. tables
1953 CURSOR cLowestStable IS
1954 SELECT table_name FROM
1955 BSC_DB_TABLES_RELS rels
1956 WHERE table_name like 'BSC_S%'||p_fact||'_'||p_dim_set||'%'
1957 AND source_table_name not like 'BSC_S%'
1958 AND p_base_table IN (select table_name from bsc_db_tables_rels rels2 connect by table_name=prior source_table_name start with table_name = rels.table_name);
1959
1960
1961 l_lowest_s_table VARCHAR2(100);
1962 Begin
1963
1964 -- Here there may be 2 or more lowest level S tables, for eg monthly and weekly periodicity
1965 FOR i IN cLowestSTable LOOP
1966 IF is_b_table_a_source(i.table_name, p_base_table) THEN
1967 l_lowest_s_table := i.table_name;
1968 exit;
1969 END IF;
1970 END LOOP;
1971
1972 IF (p_include_derived_columns=false) THEN
1973 FOR i IN cMeasures(l_lowest_s_table) LOOP
1974 l_measure.measure_id := i.measure_id;
1975 l_measure.measure_Name := i.column_name;
1976 l_measure.Measure_Type := i.measure_type;
1977 -- just get the operator
1978 l_measure.aggregation_method := substr(i.source_formula, 1, instr(i.source_formula, '(')-1);
1979 l_measure.datatype := 'NUMBER';
1980 l_measure.measure_group := i.measure_group_id;
1981 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID, i.projection_id);
1982 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.SOURCE_FORMULA, i.source_formula);
1983 l_measure_list(l_measure_list.count+1) := l_measure;
1984 END LOOP;
1985 ELSE
1986 FOR i IN cMeasuresIncludeDerived(l_lowest_s_table) LOOP
1987 l_measure.measure_id := i.measure_id;
1988 l_measure.measure_Name := i.column_name;
1989 l_measure.Measure_Type := i.measure_type;
1990 -- just get the operator
1991 l_measure.aggregation_method := substr(i.source_formula, 1, instr(i.source_formula, '(')-1);
1992 l_measure.datatype := 'NUMBER';
1993 l_measure.measure_group := i.measure_group_id;
1994 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID, i.projection_id);
1995 bsc_dbgen_utils.add_property(l_measure.properties, BSC_DBGEN_STD_METADATA.SOURCE_FORMULA, i.source_formula);
1996 -- Bug 4540103 if its a BSCIC column check which B table its from
1997 if i.column_name like 'BSCIC%' then
1998 if is_BSCIC_column_from_b_table(l_lowest_s_table, p_base_table, i.column_name) then
1999 l_measure_list(l_measure_list.count+1) := l_measure;
2000 end if;
2001 else
2002 l_measure_list(l_measure_list.count+1) := l_measure;
2003 end if;
2004 END LOOP;
2005 END IF;
2006 return l_measure_list;
2007
2008 Exception when others then
2009 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_b_table_measures_for_fact:'||p_fact||','||p_dim_set||','||p_base_table||','||bsc_mo_helper_pkg.boolean_decode(p_include_derived_columns)||':'||sqlerrm);
2010 raise;
2011 End;
2012
2013 function get_periodicity_for_table(
2014 p_table varchar2) return NUMBER is
2015 CURSOR cTablePer IS
2016 SELECT periodicity_id from bsc_db_tables where table_name=p_table;
2017 l_per NUMBER;
2018 Begin
2019 OPEN cTablePer;
2020 FETCH cTablePer into l_per;
2021 CLOSE cTablePer;
2022 return l_per;
2023
2024 Exception when others then
2025 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_periodicity_for_table:'||p_table||':'||sqlerrm);
2026 raise;
2027 End;
2028
2029 function get_db_calendar_column(
2030 p_calendar_id number,
2031 p_periodicity_id number) return varchar2 is
2032 CURSOR cDBColumn IS
2033 SELECT db_column_name FROM bsc_sys_periodicities
2034 WHERE periodicity_id = p_periodicity_id AND calendar_id = p_calendar_id;
2035 l_db_column VARCHAR2(100);
2036 Begin
2037 OPEN cDBColumn;
2038 FETCH cDBColumn INTO l_db_column;
2039 CLOSE cDBColumn;
2040 return l_db_column;
2041 Exception when others then
2042 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_db_calendar_column: calendar='||p_calendar_id||',per id='||p_periodicity_id||':'||sqlerrm);
2043 raise;
2044 End;
2045
2046
2047 function get_zero_code_levels(
2048 p_fact varchar2,
2049 p_dim_set varchar2) return BSC_DBGEN_STD_METADATA.tab_clsLevel is
2050 CURSOR cSTable(p_num_zero_code in number) IS
2051 select table_name, count(1) ct from bsc_db_calculations
2052 where table_name like 'BSC_S_%'||p_fact||'_'||p_dim_set||'%'
2053 and calculation_type=4
2054 group by table_name
2055 having count(1)= p_num_zero_code;
2056
2057 l_s_table_name VARCHAR2(300);
2058 l_num_zero_code number;
2059 /*5014050 */
2060 cursor c1(p_kpi number) is
2061 select
2062 a.DIM_LEVEL_ID,a.LEVEL_TABLE_NAME,a.level_pk_col
2063 from
2064 bsc_sys_dim_levels_b a,
2065 (select a.LEVEL_TABLE_NAME,0 RELATION_TYPE
2066 from
2067 bsc_kpi_dim_levels_b a
2068 where
2069 a.indicator=p_kpi
2070 and a.PARENT_LEVEL_INDEX is null
2071 union all
2072 select a.LEVEL_TABLE_NAME,e.RELATION_TYPE
2073 from
2074 bsc_kpi_dim_levels_b a,
2075 bsc_kpi_dim_levels_b b,
2076 bsc_sys_dim_levels_b c,
2077 bsc_sys_dim_levels_b d,
2078 bsc_sys_dim_level_rels e
2079 where
2080 a.indicator=p_kpi
2081 and b.indicator=p_kpi
2082 and a.PARENT_LEVEL_INDEX=b.DIM_LEVEL_INDEX
2083 and a.LEVEL_TABLE_NAME=c.LEVEL_TABLE_NAME
2084 and b.LEVEL_TABLE_NAME=d.LEVEL_TABLE_NAME
2085 and e.DIM_LEVEL_ID=c.DIM_LEVEL_ID
2086 and e.PARENT_DIM_LEVEL_ID=d.DIM_LEVEL_ID) b
2087 where b.LEVEL_TABLE_NAME=a.LEVEL_TABLE_NAME
2088 and b.relation_type<>1;
2089 l_level BSC_DBGEN_STD_METADATA.clsLevel ;
2090 l_level_list BSC_DBGEN_STD_METADATA.tab_clsLevel ;
2091 Begin
2092 --l_s_table_name := get_highest_s_table(p_fact, p_dim_set);
2093 --return get_levels_for_table(l_s_table_name, 'TABLE');
2094 /*5014050
2095 this issue came from m:n relations. now, we look for all levels of the kpi and minus those that are child levels*/
2096 FOR i IN c1(to_number(p_fact)) LOOP
2097 l_level.level_id := i.dim_level_id;
2098 l_level.level_name := i.level_table_name;
2099 l_level.level_table_name := i.level_table_name;
2100 l_level.level_fk := i.level_pk_col;
2101 l_level.level_pk := 'CODE';
2102 l_level.level_pk_datatype := BSC_DBGEN_UTILS.get_datatype(l_level.level_table_name, l_level.level_pk);
2103 l_level_list(l_level_list.count+1) := l_level;
2104 END LOOP;
2105 return l_level_list;
2106 Exception when others then
2107 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_zero_code_levels:'||p_fact||','||p_dim_set||':'||sqlerrm);
2108 raise;
2109 End;
2110
2111 function get_base_tables_for_dim_set(
2112 p_fact in varchar2,
2113 p_dim_set in number,
2114 p_targets in boolean) return dbms_sql.varchar2_table is
2115 CURSOR cBTables(p_prefix VARCHAR2) IS
2116 select distinct rels.table_name
2117 from bsc_db_Tables_rels rels,
2118 bsc_db_tables src
2119 where
2120 rels.source_table_name = src.table_name
2121 and src.table_type=0
2122 and rels.table_name like 'BSC_B%'
2123 connect by rels.table_name=prior rels.source_table_name
2124 start with rels.table_name in -- lowest level S tables
2125 ( SELECT table_name FROM
2126 BSC_DB_TABLES_RELS rels
2127 WHERE table_name like p_prefix||p_fact||'_'||p_dim_set||'%'
2128 AND source_table_name not like 'BSC_S%'
2129 ) ;
2130
2131 l_table_list dbms_sql.varchar2_table ;
2132 l_prefix varchar2(10) := 'BSC_S_';
2133 -- this may be because of different lowest level periodicities or different measures from diff. tables
2134
2135 Begin
2136 IF (p_targets) THEN
2137 l_prefix := 'BSC_SB_';
2138 END IF;
2139 FOR i IN cBTables(l_prefix) LOOP
2140 l_table_list(l_table_list.count+1) := i.table_name;
2141 END LOOP;
2142 return l_table_list;
2143 Exception when others then
2144 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_base_tables_for_dim_set:'||p_fact||','||p_dim_set||','||bsc_mo_helper_pkg.boolean_decode(p_targets)||':'||sqlerrm);
2145 raise;
2146 END;
2147
2148
2149 /*function get_filter_for_dim_level(
2150 p_fact varchar2,
2151 p_level varchar2) return varchar2 is
2152 l_stmt VARCHAR2(1000);
2153 CURSOR cFilter IS
2154 select sysdim.dim_level_id, source_type, source_code
2155 from bsc_kpi_dim_levels_b kpidim,
2156 bsc_sys_dim_levels_b sysdim,
2157 bsc_sys_filters_views filters
2158 where
2159 kpidim.level_table_name = sysdim.level_table_name
2160 and kpidim.level_view_name <> sysdim.level_view_name
2161 and sysdim.dim_level_id = filters.dim_level_id
2162 and filters.level_view_name = kpidim.level_view_name
2163 and kpidim.indicator = to_number(p_fact)
2164 and kpidim.level_table_name = p_level;
2165 l_row cFilter%ROWTYPE;
2166 Begin
2167 l_stmt := '(select dim_level_value from bsc_sys_filters where ';
2168 OPEN cFilter;
2169 FETCH cFilter INTO l_row;
2170 IF (cFilter%FOUND) THEN
2171 l_stmt := l_stmt||' source_type='||l_row.source_type||' and source_code='||l_row.source_code||' and dim_level_id='||l_row.dim_level_id||')';
2172 return l_stmt;
2173 ELSE
2174 return null;
2175 END IF;
2176 CLOSE cFilter;
2177
2178 Exception when others then
2179 raise;
2180 End;*/
2181
2182 function get_filter_for_dim_level(
2183 p_fact varchar2,
2184 p_level varchar2) return varchar2 is
2185 l_stmt VARCHAR2(1000);
2186 CURSOR cFilter IS
2187 SELECT level_view_name
2188 FROM bsc_kpi_dim_levels_b
2189 WHERE indicator=to_number(p_fact)
2190 AND level_table_name = p_level;
2191 l_level_view varchar2(100);
2192 Begin
2193 OPEN cFilter;
2194 FETCH cFilter INTO l_level_view ;
2195 IF (cFilter%FOUND) THEN
2196 l_level_view := '(select code from '||l_level_view ||')';
2197 CLOSE cFilter;
2198 return l_level_view;
2199 ELSE
2200 CLOSE cFilter;
2201 return null;
2202 END IF;
2203 Exception when others then
2204 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_Filter_for_dim_level:'||p_fact||','||p_level||':'||sqlerrm);
2205 raise;
2206 End;
2207
2208 function get_year_periodicity_for_fact(p_fact varchar2) return number is
2209 cursor cYearPeriodicity IS
2210 select p.periodicity_id from
2211 bsc_sys_periodicities p, bsc_kpis_vl k
2212 where
2213 p.yearly_flag =1
2214 and p.calendar_id=k.calendar_id
2215 and k.indicator = to_number(p_fact);
2216
2217 l_year_periodicity NUMBER;
2218 Begin
2219 OPEN cYearPeriodicity;
2220 FETCH cYearPeriodicity INTO l_year_periodicity;
2221 CLOSE cYearPeriodicity;
2222 return l_year_periodicity;
2223
2224 end;
2225
2226 /* Changed Aug 11, 2005 by Arun
2227 Bug 4549520
2228 Discussed this with Venu, he asked me to change the code to first check bsc_db_tables.
2229 If its null, then we goto bsc_sys_calendars
2230 */
2231
2232 function get_current_year_for_fact(
2233 p_fact varchar2) return number is
2234
2235 -- changed for bug 4549520
2236 cursor cCurrentYearFromCal IS
2237 select c.fiscal_year
2238 from bsc_sys_calendars_b c, bsc_kpis_vl k
2239 where c.calendar_id = k.calendar_id
2240 and k.indicator = to_number(p_fact);
2241
2242 l_current_year NUMBER;
2243 l_year_periodicity NUMBER;
2244 Begin
2245 l_year_periodicity := get_year_periodicity_for_fact(p_fact);
2246 OPEN cCurrentYearFromCal;
2247 FETCH cCurrentYearFromCal INTO l_current_year;
2248 CLOSE cCurrentYearFromCal;
2249 return l_current_year;
2250
2251 Exception when others then
2252 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.get_current_year_for_fact:'||p_fact||':'||sqlerrm);
2253 raise;
2254 End;
2255
2256 --added Jan 12, 2006
2257 function get_current_period_for_table(
2258 p_table_name varchar2) return number is
2259 cursor cPeriod is
2260 select current_period
2261 from bsc_db_tables
2262 where table_name=p_table_name;
2263 l_period number;
2264 begin
2265 open cPeriod;
2266 fetch cPeriod into l_period;
2267 close cPeriod;
2268 return l_period;
2269 end;
2270
2271 function get_current_year_for_table(
2272 p_table_name varchar2) return number is
2273 cursor cPeriod is
2274 select current_year
2275 from bsc_sys_calendars_b cal
2276 , bsc_sys_periodicities per
2277 , bsc_db_tables dbtbl
2278 where dbtbl.table_name = p_table_name
2279 and dbtbl.periodicity_id = per.periodicity_id
2280 and per.calendar_id = cal.calendar_id;
2281 l_year number;
2282 begin
2283 open cPeriod;
2284 fetch cPeriod into l_year;
2285 close cPeriod;
2286 return l_year;
2287 end;
2288
2289 function get_current_period_for_fact(
2290 p_fact varchar2,
2291 p_periodicity number) return number is
2292 ------------------------------
2293 cursor cCurrentPeriod IS
2294 select current_period from bsc_kpi_periodicities
2295 where indicator=to_number(p_fact)
2296 and periodicity_id=p_periodicity;
2297 l_current_period NUMBER;
2298 ------------------------------
2299 cursor cSourcePeriodicities(pp_periodicity number) is
2300 select source, db_column_name, calendar_id from bsc_sys_periodicities
2301 where periodicity_id=pp_periodicity;
2302 ------------------------------
2303 cursor cKPIPeriodicity is
2304 select periodicity_id from bsc_kpi_periodicities
2305 where indicator = to_number(p_fact);
2306 ------------------------------
2307 l_kpi_periodicity number;
2308 l_stmt VARCHAR2(1000);
2309 TYPE CurTyp IS REF CURSOR;
2310 cv CurTyp;
2311 l_current_year NUMBER;
2312 l_source_periodicities VARCHAR2(1000);
2313 l_db_col VARCHAR2(100);
2314 l_cal_id NUMBER;
2315 l_number_table DBMS_SQL.NUMBER_TABLE;
2316
2317
2318 Begin
2319 OPEN cCurrentPeriod;
2320 FETCH cCurrentPeriod INTO l_current_period;
2321 CLOSE cCurrentPeriod;
2322 IF (l_current_period is not null) THEN
2323 return l_current_period;
2324 END IF;
2325
2326 -- IF it is null, then find the source periodicity for this periodicity
2327 -- This is reqd as AW will may call this API for semester periodicity
2328 -- and semester periodicity may not exist for most objectives
2329 -- In this case, we find the sources of semester, see if any of them
2330 -- is attached to the objective.
2331 -- Lets say month is a valid periodicty for the objective and a source
2332 -- for semester. Now, we get the current_period for month, say 7.
2333 -- Then we get the current_year for month using the get_current_year API
2334 -- Once we have the year and the month, we can query bsc_db_calendar
2335 -- to get the value for Semester... whew... :D
2336
2337 -- Get the source_periodicity, db_column_name for p_periodicity
2338
2339 OPEN cSourcePeriodicities(p_periodicity);
2340 FETCH cSourcePeriodicities into l_source_periodicities, l_db_col, l_cal_id;
2341 CLOSE cSourcePeriodicities;
2342 l_source_periodicities:= ','||l_source_periodicities ||',';
2343
2344
2345 OPEN cKPIPeriodicity;
2346 LOOP
2347 FETCH cKPIPeriodicity INTO l_kpi_periodicity ;
2348 EXIT WHEN cKPIPeriodicity%NOTFOUND;
2349 IF (instr(l_source_periodicities, ','||l_kpi_periodicity||',')>0) THEN -- this is a source periodicity
2350 EXIT;
2351 ELSE
2352 l_kpi_periodicity := null;
2353 END IF;
2354 END LOOP;
2355
2356 -- Assuming month is a periodicity in the objective
2357 -- we now get the current_period for month, say 7
2358 l_current_period := get_current_period_for_fact (p_fact, l_kpi_periodicity);
2359
2360 -- Get the current year also, now that we have the current_period for month, say 2003
2361 l_current_year:= get_current_year_for_fact(p_fact);
2362
2363 -- Select semester (eg.) from bsc_db_calendar where calendar_id=2 and month=7 and year = 2003
2364 l_stmt := 'select '||l_db_col ||' from bsc_db_calendar where calendar_id=:1 and '||
2365 get_db_calendar_column(l_cal_id, l_kpi_periodicity) ||' = :2 and year = :3';
2366 OPEN cv FOR l_stmt using l_cal_id, l_current_period, l_current_year;
2367 FETCH cv INTO l_current_period;
2368 CLOSE cv;
2369 return l_current_period;
2370
2371 Exception when others then
2372 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_current_period_for_fact:'||p_fact||','||p_periodicity||':'||sqlerrm);
2373 raise;
2374
2375 End;
2376
2377
2378 -- this API is only called from the BSC Metadata Optimizer UI for AW support
2379 function is_projection_enabled_for_kpi(
2380 p_kpi in varchar2
2381 ) return varchar2 is
2382 l_dim_sets dbms_sql.number_table;
2383 l_measures BSC_DBGEN_STD_METADATA.tab_clsMeasure;
2384 l_properties BSC_DBGEN_STD_METADATA.tab_ClsProperties;
2385 Begin
2386 l_dim_sets := bsc_dbgen_metadata_reader.get_dim_sets_for_fact(p_kpi);
2387 --DBMS_OUTPUT.PUT_LINE('L_DIM_SETS.COUNT = '||TO_CHAR(l_dim_sets.count));
2388 IF (l_dim_sets.count > 0) THEN
2389 FOR i IN l_dim_sets.first..l_dim_sets.last LOOP
2390 l_measures := bsc_dbgen_metadata_reader.get_measures_for_fact(p_kpi, l_dim_sets(i));
2391 IF (l_measures.count > 0) THEN
2392 FOR j IN l_measures.first..l_measures.last LOOP
2393 l_properties := l_measures(j).Properties;
2394 IF (bsc_dbgen_utils.get_property_value(l_properties, BSC_DBGEN_STD_METADATA.PROJECTION_ID) <> '0') THEN
2395 RETURN 'Y';
2396 END IF;
2397 END LOOP;
2398 END IF;
2399 END LOOP;
2400 END IF;
2401 RETURN 'N';
2402 Exception when others then
2403 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.is_projection_enabled_for_kpi:'||p_kpi||':'||sqlerrm);
2404 raise;
2405
2406 End;
2407
2408 function get_all_facts_in_aw return dbms_sql.varchar2_table is
2409 CURSOR cAWFacts IS
2410 SELECT kpi.indicator
2411 FROM BSC_KPIS_VL KPI,
2412 BSC_KPI_PROPERTIES PROP
2413 WHERE KPI.INDICATOR = PROP.INDICATOR
2414 AND PROP.PROPERTY_CODE = BSC_METADATA_OPTIMIZER_PKG.IMPL_TYPE
2415 AND PROP.PROPERTY_VALUE = '2';
2416 l_facts DBMS_SQL.VARCHAR2_TABLE;
2417 Begin
2418 FOR i IN cAWFacts
2419 LOOP
2420 l_facts(l_facts.count+1) := i.indicator;
2421 END LOOP;
2422 return l_facts;
2423 Exception when others then
2424 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_all_facts_in_aw:'||sqlerrm);
2425 raise;
2426
2427 End;
2428
2429 --get the ZMV for a kpi and dimset
2430 function get_z_s_views(
2431 p_fact IN VARCHAR2,
2432 p_dim_set IN NUMBER)
2433 return dbms_sql.varchar2_table is
2434 cursor cList is
2435 SELECT DISTINCT mv_name
2436 FROM bsc_kpi_data_tables
2437 WHERE indicator = to_number(p_fact)
2438 AND dim_set_id = p_dim_set
2439 AND mv_name like 'BSC%ZMV';
2440 l_mv_list dbms_sql.varchar2_table ;
2441 Begin
2442 FOR i IN cList LOOP
2443 l_mv_list(l_mv_list.count+1) := i.mv_name;
2444 END LOOP;
2445 return l_mv_list;
2446 Exception when others then
2447 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.get_z_s_views:'||p_fact||','||p_dim_set||':'||sqlerrm);
2448 raise;
2449
2450 End;
2451
2452 Function get_all_levels_for_fact(p_fact IN VARCHAR2)
2453 RETURN DBMS_SQL.VARCHAR2_TABLE IS
2454 l_stmt VARCHAR2(1000);
2455 l_level VARCHAR2(1000);
2456 l_level_index number;
2457 l_return DBMS_SQL.VARCHAR2_TABLE;
2458 TYPE CurTyp IS REF CURSOR;
2459 cv CurTyp;
2460 BEGIN
2461 l_stmt := 'SELECT DISTINCT LEVEL_TABLE_NAME, DIM_LEVEL_INDEX ' ||
2462 ' FROM BSC_KPI_DIM_LEVELS_VL WHERE INDICATOR = :1 AND STATUS = 2';
2463 IF IsIndicatorBalanceOrPnL(to_number(p_fact)) Then
2464 --The level 0 which is the Type of Account drill is excluded. This level is not considered to generate the tables
2465 l_stmt:= l_stmt||' AND DIM_LEVEL_INDEX <> 0';
2466 END IF;
2467 l_stmt := l_stmt||' ORDER BY DIM_LEVEL_INDEX';
2468 OPEN cv FOR l_stmt using to_number(p_fact);
2469 LOOP
2470 FETCH cv INTO l_level, l_level_index;
2471 EXIT WHEN cv%NOTFOUND;
2472 l_return(l_return.count+1) := l_level;
2473 END LOOP;
2474 CLOSE cv;
2475 return l_return;
2476 Exception when others then
2477 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_all_levels_for_fact:'||p_fact||':'||sqlerrm);
2478 raise;
2479 END;
2480
2481 function get_dimension_level_short_name(p_dim_level_table_name IN VARCHAR2) return VARCHAR2
2482 IS
2483 CURSOR cShortName IS
2484 SELECT short_name
2485 FROM bsc_sys_dim_levels_b
2486 WHERE level_table_name = p_dim_level_table_name;
2487 l_short_name VARCHAR2(100);
2488 BEGIN
2489 OPEN cShortName;
2490 FETCH cShortName INTO l_short_name;
2491 CLOSE cShortName;
2492 return l_short_name;
2493 END;
2494
2495
2496 function get_measures_for_short_names(p_short_names in dbms_sql.varchar2_table) return dbms_sql.varchar2_table is
2497 l_measure_cols dbms_sql.varchar2_table;
2498 l_session_id number := userenv('SESSIONID');
2499 --l_counter number := 0;
2500 l_index number;
2501 l_variable_id number := 1;
2502 CURSOR c1(p_session_id NUMBER, p_variable_id NUMBER) IS
2503 SELECT nvl(sysm.measure_col, tmp.value_v) measure_col
2504 FROM bsc_sys_measures sysm, bsc_tmp_big_in_cond tmp
2505 where tmp.session_id = p_session_id
2506 and tmp.variable_id = p_variable_id
2507 and tmp.value_v = sysm.short_name(+)
2508 order by tmp.value_n;
2509 begin
2510 DELETE bsc_tmp_big_in_cond WHERE session_id=l_session_id and variable_id=l_variable_id;
2511 l_index := p_short_names.first;
2512 LOOP
2513 EXIT WHEN p_short_names.count=0;
2514 --l_counter := l_counter+1;
2515 INSERT INTO BSC_TMP_BIG_IN_COND (session_id, variable_id, value_n, value_v)
2516 VALUES (l_session_id, l_variable_id, l_index/*l_counter*/, p_short_names(l_index));
2517 EXIT WHEN l_index = p_short_names.last;
2518 l_index := p_short_names.next(l_index);
2519 END LOOP;
2520 l_index := p_short_names.first;
2521 FOR i IN c1(l_session_id, l_variable_id) LOOP
2522 l_measure_cols(l_index) := i.measure_col;
2523 IF (l_index<> p_short_names.last) THEN
2524 l_index:= p_short_names.next(l_index);
2525 END IF;
2526 END LOOP;
2527 return l_measure_cols;
2528 Exception when others then
2529 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_measures_for_short_names:'||sqlerrm);
2530 raise;
2531 end;
2532
2533
2534
2535 function get_dim_levels_for_short_names(p_short_names in dbms_sql.varchar2_table) return dbms_sql.varchar2_table is
2536 l_dim_levels dbms_sql.varchar2_table;
2537 l_session_id number := userenv('SESSIONID');
2538 --l_counter number := 0;
2539 l_index number;
2540 l_variable_id number := 1;
2541 CURSOR c1(p_session_id NUMBER, p_variable_id NUMBER) IS
2542 SELECT nvl(sysd.level_table_name, tmp.value_v) level_table_name
2543 FROM bsc_sys_dim_levels_b sysd, bsc_tmp_big_in_cond tmp
2544 where tmp.session_id = p_session_id
2545 and tmp.variable_id = p_variable_id
2546 and tmp.value_v = sysd.short_name(+)
2547 order by tmp.value_n;
2548 l_counter number;
2549 begin
2550 DELETE bsc_tmp_big_in_cond WHERE session_id=l_session_id and variable_id=l_variable_id;
2551 l_index := p_short_names.first;
2552 LOOP
2553 EXIT WHEN p_short_names.count=0;
2554 INSERT INTO BSC_TMP_BIG_IN_COND (session_id, variable_id, value_n, value_v)
2555 VALUES (l_session_id, l_variable_id, l_index/*l_counter*/, p_short_names(l_index));
2556 EXIT WHEN l_index = p_short_names.last;
2557 l_index := p_short_names.next(l_index);
2558 END LOOP;
2559 l_index := p_short_names.first;
2560 FOR i IN c1(l_session_id, l_variable_id) LOOP
2561 l_dim_levels(l_index) := i.level_table_name;
2562 IF (l_index<> p_short_names.last) THEN
2563 l_index:= p_short_names.next(l_index);
2564 END IF;
2565 END LOOP;
2566 return l_dim_levels;
2567 Exception when others then
2568 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_dim_levels_for_short_names:'||':'||sqlerrm);
2569 raise;
2570 end;
2571
2572 function get_fact_implementation_type(p_fact in varchar2) return varchar2 is
2573 cursor cImplType is
2574 SELECT property_value
2575 FROM
2576 BSC_KPI_PROPERTIES
2577 WHERE INDICATOR = p_fact
2578 AND PROPERTY_CODE = BSC_METADATA_OPTIMIZER_PKG.IMPL_TYPE;
2579 l_impl_type varchar2(30);
2580
2581 l_mv_level number;
2582 begin
2583 open cImplType;
2584 fetch cImplType into l_impl_type;
2585 close cimplType;
2586 if (l_impl_type = 2) then
2587 l_impl_type := 'AW';--Analytical Workspaces
2588 else
2589 SELECT fnd_profile.value('BSC_ADVANCED_SUMMARIZATION_LEVEL') into l_mv_level from dual;
2590 if (l_mv_level) is null then
2591 l_impl_type:='ST'; -- summary tables
2592 else
2593 l_impl_type := 'MV';-- Materialized view
2594 end if;
2595 end if;
2596 return l_impl_type;
2597 Exception when others then
2598 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_fact_implementation_type:'||p_fact||':'||sqlerrm);
2599 raise;
2600 end;
2601
2602 function is_level_used_by_prod_aw_fact(p_level_name in varchar2) return boolean is
2603 l_count number;
2604 begin
2605 select count(1) into l_count
2606 from bsc_kpi_dim_levels_b lvl,
2607 bsc_kpi_properties prop,
2608 bsc_kpis_vl kpis
2609 where kpis.indicator= lvl.indicator
2610 and kpis.indicator=prop.indicator
2611 and lvl.level_table_name=p_level_name
2612 and prop.property_code='IMPLEMENTATION_TYPE'
2613 and prop.property_value=2
2614 and kpis.prototype_flag not in (2,3,4);
2615 --dbms_output.put_line('is_level-used_by_prod_aw_fact='||l_count);
2616 if (l_count>0) then
2617 return true;
2618 end if;
2619 return false;
2620 Exception when others then
2621 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.is_level_used_by_prod_aw_fact:'||p_level_name||':'||sqlerrm);
2622 raise;
2623 end;
2624
2625 function is_level_used_by_aw_fact(p_level_name in varchar2) return boolean is
2626 l_count number;
2627 l_session_id number;
2628 begin
2629 if is_level_used_by_prod_aw_fact(p_level_name) then
2630 return true;
2631 end if;
2632 --dbms_output.put_line('assume count='||BSC_DBGEN_METADATA_READER.g_assume_production_facts.count);
2633
2634 -- Not used by any production facts, now check if any processing facts have it
2635 -- This memory variable is populated by GDB during process time
2636 IF (BSC_DBGEN_METADATA_READER.g_assume_production_facts.count=0) THEN
2637 return false;
2638 END IF;
2639 -- now see if objectives being processed have these levels
2640 l_session_id := userenv('SESSIONID');
2641 delete bsc_tmp_big_in_cond where session_id=l_session_id and variable_id=1;
2642 FORALL i in 1..BSC_DBGEN_METADATA_READER.g_assume_production_facts.count
2643 insert into bsc_tmp_big_in_cond (session_id, variable_id, value_n) values (l_session_id, 1,
2644 to_number(BSC_DBGEN_METADATA_READER.g_assume_production_facts(i)));
2645
2646 select count(1) into l_count
2647 from bsc_kpi_dim_levels_b lvl,
2648 bsc_kpi_properties prop,
2649 bsc_kpis_vl kpis
2650 where kpis.indicator= lvl.indicator
2651 and kpis.indicator=prop.indicator
2652 and lvl.level_table_name=p_level_name
2653 and prop.property_code='IMPLEMENTATION_TYPE'
2654 and prop.property_value=2
2655 and kpis.prototype_flag<>2
2656 and kpis.indicator in
2657 (select value_n from bsc_tmp_big_in_cond where session_id=l_session_id
2658 and variable_id=1);
2659 if l_count > 0 then
2660 return true;
2661 end if;
2662 --dbms_output.put_line('returning false in is_level_used_by_aw_fact');
2663 return false;
2664 Exception when others then
2665 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.is_level_used_by_aw_fact:'||p_level_name||':'||sqlerrm);
2666 raise;
2667 end;
2668
2669 function get_parents_for_level_aw(
2670 p_level_name varchar2,
2671 p_num_levels number default 1000000
2672 ) RETURN BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship IS
2673 CURSOR cParents IS
2674 select parent_lvl.level_table_name parent_level, lvl.level_table_name child_level, 'CODE' parent_pk,
2675 -- bug 5168537
2676 --rels.relation_col child_fk,
2677 parent_lvl.level_pk_col child_fk,
2678 level
2679 from
2680 bsc_sys_dim_level_rels rels,
2681 bsc_sys_dim_levels_b lvl,
2682 bsc_sys_dim_levels_b parent_lvl
2683 where
2684 lvl.dim_level_id = rels.dim_level_id and
2685 rels.parent_dim_level_id = parent_lvl.dim_level_id and
2686 rels.relation_type <> 2 and
2687 level <= p_num_levels
2688 connect by rels.dim_level_id= PRIOR rels.parent_dim_level_id
2689 and rels.relation_type<>2
2690 and rels.dim_level_id <> rels.parent_dim_level_id
2691 start with rels.dim_level_id in
2692 (select dim_level_id from bsc_sys_dim_levels_b where level_table_name = p_level_name)
2693 order by level;
2694
2695 l_lvl_rel BSC_DBGEN_STD_METADATA.ClsLevelRelationship;
2696 l_tab_rels BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship;
2697 l_count NUMBER := 1;
2698
2699
2700 BEGIN
2701 FOR i IN cParents
2702 LOOP
2703 l_lvl_rel.Parent_Level := i.parent_level;
2704 l_lvl_rel.child_level := i.child_level;
2705 l_lvl_rel.child_level_fk := i.child_fk;
2706 l_lvl_rel.Parent_Level_pk := i.parent_pk;
2707 -- Add it only if BOTH parent and child are used by an AW objective
2708 if is_level_used_by_aw_fact(i.parent_level) and is_level_used_by_aw_fact(i.child_level) then
2709 l_tab_rels(l_count) := l_lvl_rel;
2710 l_count := l_count + 1;
2711 end if;
2712 END LOOP;
2713 return l_tab_rels;
2714 Exception when others then
2715 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_parent_levels_for_aw:'||p_level_name||',levels='||p_num_levels||', error:'||sqlerrm);
2716 raise;
2717 END;
2718
2719 function get_children_for_level_aw(
2720 p_level_name varchar2,
2721 p_num_levels number default 1000000
2722 ) RETURN BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship IS
2723 CURSOR cChildren IS
2724 select parent_lvl.level_table_name parent_level, lvl.level_table_name child_level, 'CODE' parent_pk, rels.relation_col child_fk, level
2725 from
2726 bsc_sys_dim_level_rels rels,
2727 bsc_sys_dim_levels_b lvl,
2728 bsc_sys_dim_levels_b parent_lvl
2729 where
2730 lvl.dim_level_id = rels.dim_level_id and
2731 rels.parent_dim_level_id = parent_lvl.dim_level_id and
2732 rels.relation_type <> 2 and
2733 level <= p_num_levels
2734 connect by PRIOR rels.dim_level_id||rels.relation_type = rels.parent_dim_level_id||1
2735 and rels.dim_level_id <> rels.parent_dim_level_id
2736 start with rels.parent_dim_level_id in
2737 (select dim_level_id from bsc_sys_dim_levels_b where level_table_name = p_level_name)
2738 order by level;
2739 l_lvl_rel BSC_DBGEN_STD_METADATA.ClsLevelRelationship;
2740 l_tab_rels BSC_DBGEN_STD_METADATA.tab_ClsLevelRelationship;
2741 BEGIN
2742 FOR i IN cChildren
2743 LOOP
2744 l_lvl_rel.Parent_Level := i.parent_level;
2745 l_lvl_rel.child_level := i.child_level;
2746 l_lvl_rel.child_level_fk := i.child_fk;
2747 l_lvl_rel.Parent_Level_pk := i.parent_pk;
2748 -- Aug 8, 2005, added to handle dim. level changes within aw
2749 -- Add it only if BOTH parent and child are used by an AW objective
2750 if is_level_used_by_aw_fact(i.parent_level) and is_level_used_by_aw_fact(i.child_level) then
2751 l_tab_rels(l_tab_rels.count + 1) := l_lvl_rel;
2752 end if;
2753 END LOOP;
2754 return l_tab_rels;
2755 Exception when others then
2756 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_children_for_level_aw:'||p_level_name||':'||sqlerrm);
2757 raise;
2758 END;
2759
2760
2761 function get_target_per_for_b_table(p_fact in varchar2, p_dim_set in number, p_b_table in varchar2) return dbms_sql.varchar2_table is
2762 cursor cTgtPeriodicities is
2763 select periodicity_id from bsc_db_tables where table_name in
2764 (
2765 select distinct table_name from bsc_db_tables_rels rels
2766 where
2767 rels.table_name like 'BSC_S%'||p_fact||'_'||p_dim_set||'%'
2768 and rels.source_table_name not like 'BSC_S%'||p_fact||'_'||p_dim_set||'%'
2769 connect by prior rels.table_name=rels.source_table_name
2770 and rels.relation_type<>2
2771 start with rels.source_table_name = p_b_table
2772 );
2773 l_periodicities dbms_sql.varchar2_table;
2774 l_stmt varchar2(1000);
2775 TYPE CurTyp IS REF CURSOR;
2776 cv CurTyp;
2777 l_pattern varchar2(30);
2778 l_per number;
2779 BEGIN
2780
2781 l_pattern := 'BSC_S%'||p_fact||'_'||p_dim_set||'%';
2782 FOR i IN cTgtPeriodicities LOOP
2783 l_periodicities(l_periodicities.count+1):=i.periodicity_id;
2784 END LOOP;
2785 return l_periodicities;
2786 Exception when others then
2787 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.get_target_per_for_b_table:'||p_fact||','||p_dim_set||','||p_b_table||':'||sqlerrm);
2788 raise;
2789 END;
2790
2791
2792 function get_last_update_date_for_fact(p_fact in varchar2) return date is
2793 cursor cdate is
2794 select last_update_date from bsc_kpis_vl
2795 where indicator=p_fact;
2796 l_date date;
2797 begin
2798 open cdate;
2799 fetch cdate into l_date;
2800 close cdate;
2801 return l_date;
2802 end;
2803
2804 function get_fact_cols_from_b_table(
2805 p_fact in varchar2,
2806 p_dim_set in number,
2807 p_b_table_name in varchar2,
2808 p_col_type in varchar2
2809 ) return BSC_DBGEN_STD_METADATA.tab_clsColumnMaps
2810 --BSC_DBGEN_STD_METADATA.tab_clsLevel
2811 is
2812 --Find Summary Table fed by this B table
2813 cursor cSummary(p_pattern in varchar2) is
2814 select distinct table_name from bsc_db_tables_rels
2815 where instr(table_name, p_pattern)=1
2816 and source_table_name not like p_pattern||'%'
2817 connect by source_table_name = prior table_name
2818 start with source_table_name = p_b_table_name;
2819
2820 l_s_table varchar2(100);
2821
2822 cursor cPath(p_parent_level varchar2, p_child_level varchar2) is
2823 WITH tree AS
2824 (
2825 SELECT table_name child_lvl
2826 , source_Table_name parent_lvl
2827 , LEVEL lvl
2828 FROM bsc_db_tables_rels rels
2829 START WITH source_table_name = p_parent_level
2830 CONNECT BY source_table_name = PRIOR table_name
2831 )
2832 SELECT parent_lvl, child_lvl, lvl
2833 FROM tree
2834 CONNECT BY PRIOR parent_lvl = child_lvl
2835 AND PRIOR lvl = lvl + 1
2836 START WITH child_lvl = p_child_level
2837 AND lvl =
2838 (
2839 SELECT MIN(lvl)
2840 FROM tree
2841 WHERE child_lvl = p_child_level
2842 )
2843 union
2844 select source_table_name,table_name , -1 from bsc_db_Tables_rels
2845 where table_name=p_parent_level
2846 order by lvl ;
2847
2848 cursor cCols (p_table_name in varchar2, p_col_type1 in varchar2, p_col_type2 in varchar2) is
2849 select column_name, source_column source_column_name from bsc_db_Tables_cols
2850 where table_name = p_table_name
2851 and column_type in(p_col_type1, p_col_type2);
2852
2853
2854 l_var1 dbms_sql.varchar2_table;
2855 l_var2 dbms_sql.varchar2_table;
2856 l_var3 dbms_sql.varchar2_table;
2857 l_var4 dbms_sql.varchar2_table;
2858
2859 l_col_maps_table varchar2(100) := 'BSC_TMP_OPT_COL_MAPS';
2860 l_stmt varchar2(1000) :='create global temporary table '||l_col_maps_table||' (column_name varchar2(100), source_column_name varchar2(100), table_name varchar2(100), source_table_name varchar2(100))';
2861 PRAGMA AUTONOMOUS_TRANSACTION;
2862 l_col_type1 VARCHAR2(10);
2863 l_col_type2 VARCHAR2(10);
2864 TYPE CurTyp IS REF CURSOR;
2865 cv CurTyp;
2866
2867 l_col_map BSC_DBGEN_STD_METADATA.clsColumnMaps;
2868 l_col_maps BSC_DBGEN_STD_METADATA.tab_clsColumnMaps;
2869
2870 Begin
2871 init;
2872 if (bsc_apps.table_exists(l_col_maps_table)=false) then
2873 bsc_apps.Do_DDL(l_stmt, ad_ddl.create_table, l_col_maps_table);
2874 end if;
2875
2876 if (p_col_type='ALL') then
2877 l_col_type1 := 'A';
2878 l_col_type2 := 'P';
2879 elsif (p_col_type='KEYS') then
2880 l_col_type1 := 'P';
2881 l_col_type2 := 'P';
2882 elsif (p_col_type='MEASURES') then
2883 l_col_type1 := 'A';
2884 l_col_type2 := 'A';
2885 end if;
2886
2887 --rkumar: modified for bug#5506476
2888 IF BSC_MO_HELPER_PKG.FindIndex(BSC_METADATA_OPTIMIZER_PKG.g_bt_tables_tgt,p_b_table_name) = -1 THEN
2889 open cSummary('BSC_S_'||p_fact);
2890 fetch cSummary into l_s_table;
2891 close cSummary;
2892 ELSE
2893 open cSummary('BSC_SB_'||p_fact);
2894 fetch cSummary into l_s_table;
2895 close cSummary;
2896 END IF;
2897
2898 -- get shortest path and their correpsonding tables/source_tables/cols/source_cols
2899 for i in cPath(p_b_table_name, l_s_table) loop
2900 --match_columns
2901 for j in cCols(i.child_lvl, l_col_type1, l_col_type2) loop
2902 l_var1(l_var1.count+1) := i.child_lvl;
2903 l_var2(l_var2.count+1) := i.parent_lvl;
2904 l_var3(l_var3.count+1) := j.column_name;
2905 l_var4(l_var4.count+1) := j.source_column_name;
2906 end loop;
2907 end loop;
2908
2909 forall i in 1..l_var1.count
2910 execute immediate 'insert into '||l_col_maps_table||'(table_name, source_table_name, column_name, source_column_name) '
2911 ||' values (:1, :2, :3, :4)' using l_var1(i), l_var2(i), l_var3(i), l_var4(i);
2912
2913 l_stmt := 'SELECT column_name FROM '||l_col_maps_table||' WHERE TABLE_NAME LIKE :1
2914 CONNECT BY TABLE_NAME = PRIOR SOURCE_TABLE_NAME
2915 AND COLUMN_NAME = PRIOR SOURCE_COLUMN_NAME
2916 START WITH TABLE_NAME = :2';
2917 OPEN cv FOR l_stmt USING 'BSC_B%', l_s_table;
2918 LOOP
2919 FETCH cv INTO l_col_map.source_column_name;
2920 EXIT WHEN cv%NOTFOUND;
2921 l_col_maps(l_col_maps.count+1) := l_col_map;
2922 end loop;
2923 CLOSE cv;
2924
2925 l_stmt := 'SELECT column_name FROM '||l_col_maps_table||
2926 ' WHERE TABLE_NAME= :1
2927 CONNECT BY PRIOR TABLE_NAME = SOURCE_TABLE_NAME
2928 AND PRIOR COLUMN_NAME = SOURCE_COLUMN_NAME
2929 START WITH SOURCE_TABLE_NAME= :2 AND SOURCE_COLUMN_NAME =:3';
2930
2931 -- now requery temp table to get the target column fed by this source_column
2932 for i in 1..l_col_maps.count loop
2933 open cv for l_stmt using l_s_table, p_b_table_name, l_col_maps(i).source_column_name;
2934 fetch cv into l_col_maps(i).column_name;
2935 close cv;
2936 end loop;
2937 commit;
2938 return l_col_maps;
2939 Exception when others then
2940 commit;
2941 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.Get_fact_cols_from_b_table:'||p_fact||','||p_dim_set||','||p_b_table_name||','||p_col_type||':'||sqlerrm);
2942 raise;
2943
2944 End;
2945
2946
2947 procedure set_table_property(p_table_name in varchar2, p_property_name in varchar2, p_property_value in varchar2) is
2948 cursor get_old_value is
2949 select properties from bsc_db_tables where table_name=p_table_name;
2950 l_old_value varchar2(4000);
2951 l_final_value varchar2(4000);
2952 l_pos number;
2953 l_property_value varchar2(4000);
2954
2955 begin
2956 open get_old_value;
2957 fetch get_old_value into l_old_value;
2958 close get_old_value;
2959 l_property_value := p_property_name||BSC_DBGEN_STD_METADATA.BSC_ASSIGNMENT||
2960 p_property_value||BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR;
2961 if (l_old_value is null) then
2962 update bsc_db_tables
2963 set properties = l_property_value
2964 where table_name = p_table_name;
2965 return;
2966 end if;
2967 -- already has some value, update it in place
2968 l_pos := instr(l_old_value, BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR||p_property_name||BSC_DBGEN_STD_METADATA.BSC_ASSIGNMENT);
2969 if l_pos = 0 then -- check if first value
2970 l_pos := instr(l_old_value, p_property_name||BSC_DBGEN_STD_METADATA.BSC_ASSIGNMENT);
2971 end if;
2972 if l_pos =0 then -- this value does not exist, so append it
2973 update bsc_db_tables
2974 set properties = properties||l_property_value
2975 where table_name = p_table_name;
2976 return;
2977 end if;
2978 -- value exists, so update old value
2979 if l_pos = 1 then --first value
2980 l_final_value := l_property_Value;
2981 l_final_value := l_final_value||substr(l_old_value,
2982 instr(l_old_value, BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR, l_pos)+
2983 length(BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR) );
2984 else -- intermediate value
2985 l_final_value := substr(l_old_value, 1, l_pos-1+length(BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR))||l_property_value;
2986 l_final_value := l_final_value||substr(l_old_value,
2987 instr(l_old_value, BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR, l_pos, 2)+
2988 length(BSC_DBGEN_STD_METADATA.BSC_PROPERTY_SEPARATOR) );
2989 end if;
2990 -- now add the rest of the string back
2991
2992 update bsc_db_tables
2993 set properties = l_final_value
2994 where table_name = p_table_name;
2995 return;
2996 Exception when others then
2997 fnd_file.put_line(FND_FILE.LOG, 'Error in BSC_DBGEN_BSC_READER.set_table_property:table='||p_table_name||', property='||p_property_name||', value='||p_property_value||':'||sqlerrm);
2998 raise;
2999 end;
3000
3001 END BSC_DBGEN_BSC_READER ;