1 package body BSC_AW_MD_WRAPPER AS
2 /*$Header: BSCAWMWB.pls 120.20 2006/04/20 11:47 vsurendr noship $*/
3
4 procedure set_context(p_context varchar2) is
5 Begin
6 g_context:=p_context;
7 Exception when others then
8 log_n('Exception in set_context '||sqlerrm);
9 raise;
10 End;
11
12 procedure default_context_if_null is
13 Begin
14 if g_context is null then
15 g_context:='AW';
16 end if;
17 Exception when others then
18 log_n('Exception in default_context_if_null '||sqlerrm);
19 raise;
20 End;
21
22 procedure mark_kpi_recreate(
23 p_kpi varchar2
24 ) is
25 Begin
26 default_context_if_null;
27 update bsc_olap_object set operation_flag='recreate' where object=p_kpi and object_type='kpi' and context=g_context;
28 Exception when others then
29 log_n('Exception in mark_kpi_recreate '||sqlerrm);
30 raise;
31 End;
32
33 procedure drop_dim(p_dim_name varchar2) is
34 Begin
35 default_context_if_null;
36 if g_debug then
37 log('Drop metadata for Dim '||p_dim_name);
38 end if;
39 delete bsc_olap_object_relation where parent_object_type='dimension' and parent_object=p_dim_name and context=g_context;
40 --with the concept of level groups, we do not remove snowflake implementation
41 --delete bsc_olap_object_relation where parent_object_type='dimension' and parent_object in (select object from
42 --bsc_olap_object where object_type='dimension level' and parent_object_type='dimension' and parent_object=p_dim_name
43 --and context=g_context)
44 --and context=g_context;
45 --delete bsc_olap_object where parent_object_type='dimension' and parent_object in (select object from
46 --bsc_olap_object where object_type='dimension level' and parent_object_type='dimension' and parent_object=p_dim_name
47 --and context=g_context)
48 --and context=g_context;
49 delete bsc_olap_object where parent_object_type='dimension' and parent_object=p_dim_name and context=g_context;
50 Exception when others then
51 log_n('Exception in drop_dim '||sqlerrm);
52 raise;
53 End;
54
55 /*
56 create the following
57 dim
58 levels
59 zero levels
60 rec levels
61 level relations : only for real levels
62 register the program names : we need this since we will need to drop the programs when we drop the dim
63 we assume that the dimension entry is clean. this means we dont try a delete here
64 */
65 procedure create_dim(p_dimension bsc_aw_adapter_dim.dimension_r) is
66 --
67 l_position varchar2(400);
68 l_property varchar2(4000);
69 l_dim_type varchar2(100);
70 --
71 Begin
72 default_context_if_null;
73 if p_dimension.concat='Y' then
74 l_dim_type:='concat dimension';
75 else
76 l_dim_type:='dimension';--for TYPE, PROJECTION
77 end if;
78 --property1 will hold info on recursive dim or normal vs time, multi level
79 insert_olap_object(p_dimension.dim_name,'dimension',p_dimension.dim_name,l_dim_type,p_dimension.dim_name,'dimension',p_dimension.property);
80 --dim related objects
81 if p_dimension.relation_name is not null then
82 insert_olap_object(p_dimension.relation_name,'relation',p_dimension.relation_name,'relation',
83 p_dimension.dim_name,'dimension',null);
84 end if;
85 if p_dimension.level_name_dim is not null then
86 insert_olap_object(p_dimension.level_name_dim,'level name dim',p_dimension.level_name_dim,'dimension',
87 p_dimension.dim_name,'dimension',null);
88 end if;
89 if p_dimension.filter_variable is not null then
90 insert_olap_object(p_dimension.filter_variable,'filter cube',p_dimension.filter_variable,'variable',
91 p_dimension.dim_name,'dimension',null);
92 end if;
93 if p_dimension.limit_variable is not null then
94 insert_olap_object(p_dimension.limit_variable,'limit cube',p_dimension.limit_variable,'variable',
95 p_dimension.dim_name,'dimension',null);
96 end if;
97 if p_dimension.rec_level_position_cube is not null then
98 insert_olap_object(p_dimension.rec_level_position_cube,'rec level position cube',p_dimension.rec_level_position_cube,'variable',
99 p_dimension.dim_name,'dimension',null);
100 end if;
101 if p_dimension.base_value_cube is not null then
102 insert_olap_object(p_dimension.base_value_cube,'base value cube',p_dimension.base_value_cube,'variable',
103 p_dimension.dim_name,'dimension',null);
104 end if;
105 --enter the level group info
106 for i in 1..p_dimension.level_groups.count loop
107 insert_olap_object(p_dimension.level_groups(i).level_group_name,'level group',null,null,p_dimension.dim_name,'dimension',null);
108 end loop;
109 --populate the levels
110 for i in 1..p_dimension.level_groups.count loop
111 for j in 1..p_dimension.level_groups(i).levels.count loop
112 l_property:='level group='||p_dimension.level_groups(i).level_group_name||',position='||p_dimension.level_groups(i).levels(j).position||
113 ',pk='||p_dimension.level_groups(i).levels(j).pk.pk||',level source='||p_dimension.level_groups(i).levels(j).level_source;
114 insert_olap_object(p_dimension.level_groups(i).levels(j).level_name,'dimension level',p_dimension.level_groups(i).levels(j).level_name,'dimension',
115 p_dimension.dim_name,'dimension',l_property);
116 end loop;
117 end loop;
118 --
119 --snow flake. to support kpi when they reference independent levels. look at bsc_aw_adapter_kpi.identify_standalone_levels
120 --since the same level can come from diff dim, we need to merge the entries in
121 --if this is the metadata of the corrected dim, do not touch the snowflake implementation. corrected dim cannot have new dim levels
122 if p_dimension.dim_type <> 'std' and p_dimension.corrected='N' then
123 for i in 1..p_dimension.level_groups.count loop
124 for j in 1..p_dimension.level_groups(i).levels.count loop
125 l_property:='dimension type=normal,zero code,relation name='||p_dimension.level_groups(i).levels(j).relation_name||',level name dim='||
126 p_dimension.level_groups(i).levels(j).level_name_dim||',pk='||p_dimension.level_groups(i).levels(j).pk.pk||',';
127 merge_olap_object(p_dimension.level_groups(i).levels(j).level_name,'dimension',p_dimension.level_groups(i).levels(j).level_name,'dimension',
128 p_dimension.level_groups(i).levels(j).level_name,'dimension',l_property);
129 --also insert row for relation and level name dim
130 merge_olap_object(p_dimension.level_groups(i).levels(j).relation_name,'relation',p_dimension.level_groups(i).levels(j).relation_name,'relation',
131 p_dimension.level_groups(i).levels(j).level_name,'dimension',l_property);
132 merge_olap_object(p_dimension.level_groups(i).levels(j).level_name_dim,'level name dim',p_dimension.level_groups(i).levels(j).level_name_dim,
133 'dimension',p_dimension.level_groups(i).levels(j).level_name,'dimension',l_property);
134 --related objects for each level
135 merge_olap_object(p_dimension.level_groups(i).levels(j).filter_variable,'filter cube',p_dimension.level_groups(i).levels(j).filter_variable,
136 'variable',p_dimension.level_groups(i).levels(j).level_name,'dimension',l_property);
137 merge_olap_object(p_dimension.level_groups(i).levels(j).limit_variable,'limit cube',p_dimension.level_groups(i).levels(j).limit_variable,
138 'variable',p_dimension.level_groups(i).levels(j).level_name,'dimension',l_property);
139 end loop;
140 end loop;
141 end if;
142 --
143 if p_dimension.limit_variable is not null then
144 insert_olap_object_relation(p_dimension.dim_name,'dimension',p_dimension.limit_variable,
145 'dim limit cube','dim limit cube',p_dimension.dim_name,'dimension',null);
146 end if;
147 --also insert in olap relation the level and its corresponding zero code level
148 for i in 1..p_dimension.level_groups.count loop
149 for j in 1..p_dimension.level_groups(i).zero_levels.count loop
150 l_property:='level group='||p_dimension.level_groups(i).level_group_name;
151 insert_olap_object_relation(p_dimension.level_groups(i).zero_levels(j).child_level_name,'dimension level',
152 p_dimension.level_groups(i).zero_levels(j).level_name,'zero code level','zero code level',p_dimension.dim_name,'dimension',l_property);
153 --insert this zero code also as a relation for the dim of each level (snow flake levels)
154 if p_dimension.dim_type <> 'std' and p_dimension.corrected='N' then
155 l_property:=null;--no level group since snow flake
156 merge_olap_object_relation(p_dimension.level_groups(i).zero_levels(j).child_level_name,'dimension level',
157 p_dimension.level_groups(i).zero_levels(j).level_name,'zero code level','zero code level',
158 p_dimension.level_groups(i).zero_levels(j).child_level_name,'dimension',l_property);
159 end if;
160 end loop;
161 end loop;
162 --rec levels
163 for i in 1..p_dimension.level_groups.count loop
164 for j in 1..p_dimension.level_groups(i).rec_levels.count loop
165 l_property:='level group='||p_dimension.level_groups(i).level_group_name;
166 insert_olap_object(p_dimension.level_groups(i).rec_levels(j).level_name,'recursive level',p_dimension.level_groups(i).rec_levels(j).level_name,
167 'dimension',p_dimension.dim_name,'dimension',l_property);
168 end loop;
169 --also insert into olap relation
170 for j in 1..p_dimension.level_groups(i).rec_levels.count loop
171 l_property:='level group='||p_dimension.level_groups(i).level_group_name;
172 insert_olap_object_relation(p_dimension.level_groups(i).rec_levels(j).child_level_name,'dimension level',
173 p_dimension.level_groups(i).rec_levels(j).level_name,
174 'recursive parent level','recursive parent level',p_dimension.dim_name,'dimension',l_property);
175 end loop;
176 end loop;
177 --level relations
178 --pk and fk info will be used in creating data source for base tables. if base table is at city level and the kpi is at country
179 --level, we need to join to the city and state view. we need to know how to join
180 for i in 1..p_dimension.level_groups.count loop
181 for j in 1..p_dimension.level_groups(i).parent_child.count loop
182 insert_olap_object_relation(p_dimension.level_groups(i).parent_child(j).child_level,'dimension level',
183 p_dimension.level_groups(i).parent_child(j).parent_level,
184 'dimension level','parent level',p_dimension.dim_name,'dimension','level group='||p_dimension.level_groups(i).level_group_name||
185 ',pk='||p_dimension.level_groups(i).parent_child(j).parent_pk||',fk='||p_dimension.level_groups(i).parent_child(j).child_fk);
186 end loop;
187 end loop;
188 --register the program names
189 if p_dimension.initial_load_program is not null then
190 insert_olap_object(p_dimension.initial_load_program,'dml program',p_dimension.initial_load_program,'dml program initial load',
191 p_dimension.dim_name,'dimension',null);
192 end if;
193 --inc refresh program
194 if p_dimension.inc_load_program is not null then
195 insert_olap_object(p_dimension.inc_load_program,'dml program',p_dimension.inc_load_program,'dml program inc load',
196 p_dimension.dim_name,'dimension',null);
197 end if;
198 --insert dep kpi info
199 for i in 1..p_dimension.kpi_for_dim.count loop
200 --insert_olap_object_relation(p_dimension.dim_name,'dimension',p_dimension.kpi_for_dim(i).kpi,'kpi','dimension kpi',p_dimension.dim_name,'dimension',
201 --null);
202 --when we delete a kpi, we must delete this entry. for perf reasons, we keep the object as kpi
203 insert_olap_object_relation(p_dimension.kpi_for_dim(i).kpi,'kpi',p_dimension.kpi_for_dim(i).kpi,'kpi','dimension kpi',p_dimension.dim_name,'dimension',
204 null);
205 end loop;
206 Exception when others then
207 log_n('Exception in create_dim '||sqlerrm);
208 raise;
209 End;
210
211 procedure drop_kpi(p_kpi varchar2) is
212 Begin
213 default_context_if_null;
214 if g_debug then
215 log('drop kpi metadata '||p_kpi||bsc_aw_utility.get_time);
216 end if;
217 if p_kpi is not null then
218 delete bsc_olap_object_relation where parent_object_type='kpi' and parent_object=p_kpi and context=g_context;
219 delete bsc_olap_object_relation where object=p_kpi and object_type='kpi' and relation_object=p_kpi and relation_object_type='kpi' and
220 relation_type='dimension kpi';
221 delete bsc_olap_object where parent_object_type='kpi' and parent_object=p_kpi and context=g_context;
222 end if;
223 Exception when others then
224 log_n('Exception in drop_kpi '||sqlerrm);
225 raise;
226 End;
227
228 procedure create_calendar(p_calendar bsc_aw_calendar.calendar_r) is
229 l_property varchar2(4000);
230 Begin
231 default_context_if_null;
232 insert_olap_object(p_calendar.dim_name,'dimension',p_calendar.dim_name,'concat dimension',
233 p_calendar.dim_name,'dimension',p_calendar.property);
234 --related objects of the dim
235 insert_olap_object(p_calendar.relation_name,'relation',p_calendar.relation_name,'relation',
236 p_calendar.dim_name,'dimension',null);
237 insert_olap_object(p_calendar.denorm_relation_name,'denorm relation',p_calendar.denorm_relation_name,'relation',
238 p_calendar.dim_name,'dimension',null);
239 insert_olap_object(p_calendar.end_period_relation_name,'end period relation',p_calendar.end_period_relation_name,'relation',
240 p_calendar.dim_name,'dimension',null);
241 --there is also the end_period.temp variable
242 insert_olap_object(p_calendar.end_period_relation_name||'.temp','end period temp variable',
243 p_calendar.end_period_relation_name||'.temp','variable',p_calendar.dim_name,'dimension',null);
244 --
245 insert_olap_object(p_calendar.levels_name,'level name dim',p_calendar.levels_name,'dimension',
246 p_calendar.dim_name,'dimension',null);
247 insert_olap_object(p_calendar.end_period_levels_name,'end period level name dim',p_calendar.end_period_levels_name,'dimension',
248 p_calendar.dim_name,'dimension',null);
249 --misc objects
250 for i in 1..p_calendar.misc_object.count loop
251 insert_olap_object(p_calendar.misc_object(i).object_name,p_calendar.misc_object(i).object_type,
252 p_calendar.misc_object(i).object_name,p_calendar.misc_object(i).object_type,p_calendar.dim_name,'dimension',null);
253 end loop;
254 --populate the levels
255 for i in 1..p_calendar.periodicity.count loop
256 insert_olap_object(p_calendar.periodicity(i).dim_name,'dimension level',p_calendar.periodicity(i).dim_name,'dimension',
257 p_calendar.dim_name,'dimension','periodicity='||p_calendar.periodicity(i).periodicity_id||',db_column_name='||
258 p_calendar.periodicity(i).db_column_name||',periodicity_type='||p_calendar.periodicity(i).periodicity_type);
259 --related objects for each periodicity
260 if p_calendar.periodicity(i).aw_time_dim_name is not null then
261 insert_olap_object(p_calendar.periodicity(i).aw_time_dim_name,'aw time dim level',p_calendar.periodicity(i).aw_time_dim_name,'dimension',
262 p_calendar.dim_name,'dimension','periodicity='||p_calendar.periodicity(i).periodicity_id);
263 insert_olap_object(p_calendar.periodicity(i).aw_bsc_aw_rel_name,'bsc aw time relation',
264 p_calendar.periodicity(i).aw_bsc_aw_rel_name,'relation',
265 p_calendar.dim_name,'dimension','periodicity='||p_calendar.periodicity(i).periodicity_id);
266 insert_olap_object(p_calendar.periodicity(i).aw_aw_bsc_rel_name,'aw bsc time relation',
267 p_calendar.periodicity(i).aw_aw_bsc_rel_name,'relation',
268 p_calendar.dim_name,'dimension','periodicity='||p_calendar.periodicity(i).periodicity_id);
269 end if;
270 end loop;
271 --register the program names
272 insert_olap_object(p_calendar.load_program,'dml program',p_calendar.load_program,'dml program initial load',
273 p_calendar.dim_name,'dimension',null);
274 --fill dep kpi info
275 for i in 1..p_calendar.kpi_for_dim.count loop
276 --insert_olap_object_relation(p_calendar.dim_name,'dimension',p_calendar.kpi_for_dim(i).kpi,'kpi','dimension kpi',p_calendar.dim_name,'dimension',
277 --null);
278 insert_olap_object_relation(p_calendar.kpi_for_dim(i).kpi,'kpi',p_calendar.kpi_for_dim(i).kpi,'kpi','dimension kpi',p_calendar.dim_name,'dimension',
279 null);
280 end loop;
281 --
282 --insert the parent child relations
283 for i in 1..p_calendar.parent_child.count loop
284 l_property:='parent periodicity='||p_calendar.parent_child(i).parent||',child periodicity='||p_calendar.parent_child(i).child||',';
285 insert_olap_object_relation(p_calendar.parent_child(i).child_dim_name,'dimension level',
286 p_calendar.parent_child(i).parent_dim_name,'dimension level','parent level',p_calendar.dim_name,'dimension',l_property);
287 end loop;
288 Exception when others then
289 log_n('Exception in create_calendar '||sqlerrm);
290 raise;
291 End;
292
293 /*
294 get bsc olap object table data given the parent object and parent type
295 access paths
296 1. par obj specified. par obj type specified. obj not specified. obj type not specified.
297 2. par obj specified. par obj type specified. obj type specified. obj not specified
298 3. obj specified. obj type specified
299 4. obj specified. obj type specified. parent obj type specified
300 5. obj specified. obj type specified. parent obj specified. parent obj type specified
301 6. obj null, obj type not null, parent obj null, par obj type not null
302 */
303 procedure get_bsc_olap_object(
304 p_object varchar2,
305 p_type varchar2,
306 p_parent_object varchar2,
307 p_parent_type varchar2,
308 p_bsc_olap_object out nocopy bsc_olap_object_tb
309 ) is
310 --
311 cursor c1 is select * from bsc_olap_object where parent_object=p_parent_object and parent_object_type=p_parent_type
312 and context=g_context order by object_type;
313 cursor c2 is select * from bsc_olap_object where parent_object=p_parent_object and parent_object_type=p_parent_type
314 and object_type=p_type and context=g_context order by object_type;
315 cursor c3 is select * from bsc_olap_object where object=p_object and object_type=p_type
316 and context=g_context order by object_type;
317 cursor c4 is select * from bsc_olap_object where object=p_object and object_type=p_type and parent_object_type=p_parent_type
318 and context=g_context order by object_type;
319 cursor c5 is select * from bsc_olap_object where object=p_object and object_type=p_type and parent_object=p_parent_object
320 and parent_object_type=p_parent_type and context=g_context order by object_type;
321 cursor c6 is select * from bsc_olap_object where object_type=p_type and parent_object_type=p_parent_type and context=g_context;
322 Begin
323 default_context_if_null;
324 if g_debug and bsc_aw_utility.g_debug_level='all' then
325 log(' get_bsc_olap_object object='||p_object||' type='||p_type||' parent_object='||p_parent_object||' po_type='||
326 p_parent_type);
327 end if;
328 if p_object is null and p_type is null and p_parent_object is not null and p_parent_type is not null then --given the parent, get the objects
329 open c1;
330 loop
331 fetch c1 bulk collect into p_bsc_olap_object;
332 exit when c1%notfound;
333 end loop;
334 close c1;
335 elsif p_object is null and p_type is not null and p_parent_object is not null and p_parent_type is not null then
336 open c2;
337 loop
338 fetch c2 bulk collect into p_bsc_olap_object;
339 exit when c2%notfound;
340 end loop;
341 close c2;
342 elsif p_object is not null and p_type is not null and p_parent_object is null and p_parent_type is null then
343 open c3;
344 loop
345 fetch c3 bulk collect into p_bsc_olap_object;
346 exit when c3%notfound;
347 end loop;
348 close c3;
349 elsif p_object is not null and p_type is not null and p_parent_object is null and p_parent_type is not null then
350 open c4;
351 loop
352 fetch c4 bulk collect into p_bsc_olap_object;
353 exit when c4%notfound;
354 end loop;
355 close c4;
356 elsif p_object is not null and p_type is not null and p_parent_object is not null and p_parent_type is not null then
357 open c5;
358 loop
359 fetch c5 bulk collect into p_bsc_olap_object;
360 exit when c5%notfound;
361 end loop;
362 close c5;
363 elsif p_object is null and p_type is not null and p_parent_object is null and p_parent_type is not null then
364 open c6;
365 loop
366 fetch c6 bulk collect into p_bsc_olap_object;
367 exit when c6%notfound;
368 end loop;
369 close c6;
370 end if;
371 Exception when others then
372 log_n('Exception in get_bsc_olap_object '||sqlerrm);
373 raise;
374 End;
375
376 /*
377 access paths:
378 obj specified. rel type not specified. par obj specified
379 obj specified. rel type specified. par obj specified
380 obj specified. rel type specified. par obj not specified
381 obj not specified. rel type not specified. par obj specified
382 obj not specified. rel type specified. par obj specified
383 obj specified. rel type not specified. par obj not specified
384 */
385 procedure get_bsc_olap_object_relation(
386 p_object varchar2,
387 p_object_type varchar2,
388 p_relation_type varchar2,
389 p_parent_object varchar2,
390 p_parent_object_type varchar2,
391 p_bsc_olap_object_relation out nocopy bsc_olap_object_relation_tb
392 ) is
393 --
394 cursor c1 is select * from bsc_olap_object_relation where object=p_object and object_type=p_object_type
395 and parent_object=p_parent_object and parent_object_type=p_parent_object_type
396 and context=g_context;
397 cursor c2 is select * from bsc_olap_object_relation where object=p_object and object_type=p_object_type
398 and parent_object=p_parent_object and parent_object_type=p_parent_object_type
399 and relation_type=p_relation_type and context=g_context;
400 cursor c3 is select * from bsc_olap_object_relation where object=p_object and object_type=p_object_type
401 and relation_type=p_relation_type and context=g_context;
402 cursor c4 is select * from bsc_olap_object_relation where parent_object=p_parent_object
403 and parent_object_type=p_parent_object_type
404 and context=g_context;
405 cursor c5 is select * from bsc_olap_object_relation where relation_type=p_relation_type
406 and parent_object=p_parent_object and parent_object_type=p_parent_object_type
407 and context=g_context;
408 cursor c6 is select * from bsc_olap_object_relation where object=p_object and object_type=p_object_type
409 and context=g_context;
410 --
411 Begin
412 default_context_if_null;
413 if g_debug and bsc_aw_utility.g_debug_level='all' then
414 log(' get_bsc_olap_object_relation object='||p_object||' type='||p_object_type||' rel_type='||
415 p_relation_type||' par_obj='||p_parent_object||' par_obj_type='||p_parent_object_type);
416 end if;
417 if p_object is not null and p_relation_type is null and p_parent_object is not null then
418 open c1;
419 loop
420 fetch c1 bulk collect into p_bsc_olap_object_relation;
421 exit when c1%notfound;
422 end loop;
423 close c1;
424 elsif p_object is not null and p_relation_type is not null and p_parent_object is not null then
425 open c2;
426 loop
427 fetch c2 bulk collect into p_bsc_olap_object_relation;
428 exit when c2%notfound;
429 end loop;
430 close c2;
431 elsif p_object is not null and p_relation_type is not null and p_parent_object is null then
432 open c3;
433 loop
434 fetch c3 bulk collect into p_bsc_olap_object_relation;
435 exit when c3%notfound;
436 end loop;
437 close c3;
438 elsif p_object is null and p_relation_type is null and p_parent_object is not null then
439 open c4;
440 loop
441 fetch c4 bulk collect into p_bsc_olap_object_relation;
442 exit when c4%notfound;
443 end loop;
444 close c4;
445 elsif p_object is null and p_relation_type is not null and p_parent_object is not null then
446 open c5;
447 loop
448 fetch c5 bulk collect into p_bsc_olap_object_relation;
449 exit when c5%notfound;
450 end loop;
451 close c5;
452 elsif p_object is not null and p_relation_type is null and p_parent_object is null then
453 open c6;
454 loop
455 fetch c6 bulk collect into p_bsc_olap_object_relation;
456 exit when c6%notfound;
457 end loop;
458 close c6;
459 end if;
460 Exception when others then
461 log_n('Exception in get_bsc_olap_object_relation '||sqlerrm);
462 raise;
463 End;
464
465 procedure create_kpi(p_kpi bsc_aw_adapter_kpi.kpi_r) is
466 Begin
467 default_context_if_null;
468 if g_debug then
469 log('create kpi metadata '||p_kpi.kpi||bsc_aw_utility.get_time);
470 end if;
471 --=======bsc olap objects====================
472 insert_olap_object(p_kpi.kpi,'kpi',null,null,p_kpi.kpi,'kpi','calendar='||p_kpi.calendar||',parent kpi='||p_kpi.parent_kpi);
473 for i in 1..p_kpi.dim_set.count loop
474 create_kpi(p_kpi.kpi,p_kpi.dim_set(i));
475 end loop;
476 --targets
477 for i in 1..p_kpi.target_dim_set.count loop
478 if p_kpi.target_dim_set(i).dim_set is not null then
479 create_kpi(p_kpi.kpi,p_kpi.target_dim_set(i));
480 end if;
481 end loop;
482 Exception when others then
483 log_n('Exception in create_kpi '||sqlerrm);
484 raise;
485 End;
486
487 procedure create_kpi(p_kpi varchar2,p_dim_set bsc_aw_adapter_kpi.dim_set_r) is
488 l_property varchar2(4000);
489 l_comp_added dbms_sql.varchar2_table; --so we insert into oo distinct composite names
490 l_dimset_name_property varchar2(400);
491 l_bsc_olap_object_relation bsc_olap_object_relation_tb;
492 Begin
493 default_context_if_null;
494 --=======bsc olap objects====================
495 --we need to have all the objects entered in bsc_olap_object that needs to be dropped
496 --dimension set
497 --we just need to knoow if there are targets or not, if there are targets we load, aggregate, load targets and again aggregate
498 --base dim set will be useful for target dimsets, for regular dimsets, this is will be null.
499 --in BSCAWLKB.pls, we have to see the base dim set for a target dimset. only then can we copy data from target cubes to actual cubes
500 l_dimset_name_property:='dim set name='||p_dim_set.dim_set_name||',';
501 l_property:='dim set='||p_dim_set.dim_set||',dim set type='||p_dim_set.dim_set_type||',base dim set='||p_dim_set.base_dim_set||',';
502 if p_dim_set.targets_higher_levels='Y' then
503 l_property:=l_property||'targets,';
504 end if;
505 l_property:=l_property||'measurename dim='||p_dim_set.measurename_dim||',partition dim='||p_dim_set.partition_dim||',cube design='||
506 p_dim_set.cube_design||',number partitions='||p_dim_set.number_partitions||',partition type='||p_dim_set.partition_type||
507 ',compressed='||p_dim_set.compressed||',pre calculated='||p_dim_set.pre_calculated;
508 insert_olap_object(p_dim_set.dim_set_name,'kpi dimension set',null,null,p_kpi,'kpi',l_property);
509 /*
510 insert the partition, composite info
511 */
512 for i in 1..p_dim_set.partition_template.count loop
513 l_property:=l_dimset_name_property;
514 l_property:=l_property||',template type='||p_dim_set.partition_template(i).template_type||',template use='||p_dim_set.partition_template(i).template_use||
515 ',template dim='||p_dim_set.partition_template(i).template_dim;
516 insert_olap_object(p_dim_set.partition_template(i).template_name,'partition template',
517 p_dim_set.partition_template(i).template_name,'partition template',p_kpi,'kpi',l_property);
518 end loop;
519 --register the measurename_dim...it also must be dropped
520 insert_olap_object(p_dim_set.measurename_dim,'measurename dim',p_dim_set.measurename_dim,'dimension',p_kpi,'kpi',l_property);
521 --composite name
522 --in 10g, this composite will not exist. each cube has its own
523 --we do not create an entry for dimension set composite. in 9i also, measure composite will create entry for the composite name
524 for i in 1..p_dim_set.composite.count loop
525 l_property:=l_dimset_name_property;
526 l_property:=l_property||',composite type='||p_dim_set.composite(i).composite_type;
527 insert_olap_object(p_dim_set.composite(i).composite_name,'measure composite',
528 p_dim_set.composite(i).composite_name,'composite',p_kpi,'kpi',l_property);
529 end loop;
530 --cubes
531 for i in 1..p_dim_set.cube_set.count loop
532 l_property:=l_dimset_name_property;
533 l_property:=l_property||',cube set type='||p_dim_set.cube_set(i).cube_set_type||',measurename dim='||p_dim_set.cube_set(i).measurename_dim;
534 insert_olap_object(p_dim_set.cube_set(i).cube.cube_name,'data cube',p_dim_set.cube_set(i).cube.cube_name,'cube',
535 p_kpi,'kpi',l_property||',cube type='||p_dim_set.cube_set(i).cube.cube_type||',cube data type='||p_dim_set.cube_set(i).cube.cube_datatype);
536 if p_dim_set.cube_set(i).countvar_cube.cube_name is not null then
537 insert_olap_object(p_dim_set.cube_set(i).countvar_cube.cube_name,'countvar cube',p_dim_set.cube_set(i).countvar_cube.cube_name,'cube',
538 p_kpi,'kpi',l_property||',cube type='||p_dim_set.cube_set(i).countvar_cube.cube_type||',cube data type='||
539 p_dim_set.cube_set(i).countvar_cube.cube_datatype);
540 end if;
541 if p_dim_set.cube_set(i).display_cube.cube_name is not null then
542 insert_olap_object(p_dim_set.cube_set(i).display_cube.cube_name,'display cube',p_dim_set.cube_set(i).display_cube.cube_name,'cube',
543 p_kpi,'kpi',l_property||',cube type='||p_dim_set.cube_set(i).display_cube.cube_type||',cube data type='||
544 p_dim_set.cube_set(i).display_cube.cube_datatype);
545 end if;
546 /*
547 right now, we do not create the fcst cube. so we do not register it in olap pbjects. if we register it there, in 10g, lock acquire
548 fails with Exception in get_lock ORA-34492: Analytic workspace object BUGLOG_2_4014_FCST does not exist.
549 */
550 end loop;
551 --formulas. we need it in the case where we use datacube design
552 for i in 1..p_dim_set.measure.count loop
553 if p_dim_set.measure(i).aw_formula.formula_name is not null then
554 l_property:=l_dimset_name_property;
555 insert_olap_object(p_dim_set.measure(i).aw_formula.formula_name,'measure formula',p_dim_set.measure(i).aw_formula.formula_name,'formula',
556 p_kpi,'kpi',l_property||',measure='||p_dim_set.measure(i).measure);
557 end if;
558 end loop;
559 --agg maps
560 insert_olap_object(p_dim_set.aggmap_operator.measure_dim,'agg map measure dim',p_dim_set.aggmap_operator.measure_dim,
561 'dimension',p_kpi,'kpi',l_dimset_name_property||'agg map');
562 insert_olap_object(p_dim_set.aggmap_operator.opvar,'agg map opvar',p_dim_set.aggmap_operator.opvar,
563 'variable',p_kpi,'kpi',l_dimset_name_property||'agg map');
564 insert_olap_object(p_dim_set.aggmap_operator.argvar,'agg map argvar',p_dim_set.aggmap_operator.argvar,
565 'variable',p_kpi,'kpi',l_dimset_name_property||'agg map');
566 --
567 if p_dim_set.agg_map.created='Y' then
568 insert_olap_object(p_dim_set.agg_map.agg_map,'agg map',p_dim_set.agg_map.agg_map,'agg map',p_kpi,'kpi',l_dimset_name_property||'agg map');
569 end if;
570 if p_dim_set.agg_map_notime.created='Y' then
571 insert_olap_object(p_dim_set.agg_map_notime.agg_map,'agg map',p_dim_set.agg_map_notime.agg_map,'agg map',p_kpi,'kpi',
572 l_dimset_name_property||'agg map notime');
573 end if;
574 --limit cubes of the dim
575 for i in 1..p_dim_set.dim.count loop
576 if p_dim_set.dim(i).limit_cube_composite is not null then
577 insert_olap_object(p_dim_set.dim(i).limit_cube_composite,'limit cube composite',p_dim_set.dim(i).limit_cube_composite,
578 'composite',p_kpi,'kpi',l_dimset_name_property);
579 end if;
580 if p_dim_set.dim(i).limit_cube is not null then
581 insert_olap_object(p_dim_set.dim(i).limit_cube,'dim limit cube',p_dim_set.dim(i).limit_cube,
582 'variable',p_kpi,'kpi',l_dimset_name_property);
583 end if;
584 if p_dim_set.dim(i).aggregate_marker is not null then
585 insert_olap_object(p_dim_set.dim(i).aggregate_marker,'dim aggregate marker',p_dim_set.dim(i).aggregate_marker,
586 'variable',p_kpi,'kpi',l_dimset_name_property);
587 end if;
588 if p_dim_set.dim(i).reset_cube is not null then
589 insert_olap_object(p_dim_set.dim(i).reset_cube,'dim reset cube',p_dim_set.dim(i).reset_cube,
590 'variable',p_kpi,'kpi',l_dimset_name_property);
591 end if;
592 end loop;
593 for i in 1..p_dim_set.std_dim.count loop
594 if p_dim_set.std_dim(i).limit_cube_composite is not null then
595 insert_olap_object(p_dim_set.std_dim(i).limit_cube_composite,'limit cube composite',p_dim_set.std_dim(i).limit_cube_composite,
596 'composite',p_kpi,'kpi',l_dimset_name_property);
597 end if;
598 if p_dim_set.std_dim(i).limit_cube is not null then
599 insert_olap_object(p_dim_set.std_dim(i).limit_cube,'dim limit cube',p_dim_set.std_dim(i).limit_cube,
600 'variable',p_kpi,'kpi',l_dimset_name_property);
601 end if;
602 --std dim and calendar do not have reset cubes
603 end loop;
604 --calendar limit cube
605 if p_dim_set.calendar.limit_cube_composite is not null then
606 insert_olap_object(p_dim_set.calendar.limit_cube_composite,'limit cube composite',p_dim_set.calendar.limit_cube_composite,
607 'composite',p_kpi,'kpi',l_dimset_name_property);
608 end if;
609 if p_dim_set.calendar.limit_cube is not null then
610 insert_olap_object(p_dim_set.calendar.limit_cube,'dim limit cube',p_dim_set.calendar.limit_cube,
611 'variable',p_kpi,'kpi',l_dimset_name_property);
612 end if;
613 if p_dim_set.calendar.aggregate_marker is not null then
614 insert_olap_object(p_dim_set.calendar.aggregate_marker,'dim aggregate marker',p_dim_set.calendar.aggregate_marker,
615 'variable',p_kpi,'kpi',l_dimset_name_property);
616 end if;
617 --dim agg maps
618 for i in 1..p_dim_set.dim.count loop
619 if p_dim_set.dim(i).agg_map.agg_map is not null then
620 insert_olap_object(p_dim_set.dim(i).agg_map.agg_map,'dim agg map',p_dim_set.dim(i).agg_map.agg_map,
621 'agg map',p_kpi,'kpi',l_dimset_name_property);
622 end if;
623 end loop;
624 /*calendar aggmap */
625 if p_dim_set.calendar.agg_map.agg_map is not null then
626 insert_olap_object(p_dim_set.calendar.agg_map.agg_map,'calendar agg map',p_dim_set.calendar.agg_map.agg_map,'agg map',p_kpi,'kpi',
627 l_dimset_name_property);
628 end if;
629 --program
630 insert_olap_object(p_dim_set.initial_load_program.program_name,'dml program',p_dim_set.initial_load_program.program_name,'dml program initial load',
631 p_kpi,'kpi',l_dimset_name_property||'DS='||p_dim_set.initial_load_program.ds_base_tables);
632 insert_olap_object(p_dim_set.inc_load_program.program_name,'dml program',p_dim_set.inc_load_program.program_name,'dml program inc load',p_kpi,'kpi',
633 l_dimset_name_property||'DS='||p_dim_set.inc_load_program.ds_base_tables);
634 if p_dim_set.initial_load_program_parallel.program_name is not null then
635 insert_olap_object(p_dim_set.initial_load_program_parallel.program_name,'dml program',p_dim_set.initial_load_program_parallel.program_name,
636 'dml program initial load parallel',p_kpi,'kpi',l_dimset_name_property||'DS='||p_dim_set.initial_load_program_parallel.ds_base_tables);
637 end if;
638 if p_dim_set.inc_load_program_parallel.program_name is not null then
639 insert_olap_object(p_dim_set.inc_load_program_parallel.program_name,'dml program',p_dim_set.inc_load_program_parallel.program_name,
640 'dml program inc load parallel',p_kpi,'kpi',l_dimset_name_property||'DS='||p_dim_set.inc_load_program_parallel.ds_base_tables);
641 end if;
642 if p_dim_set.LB_resync_program is not null then
643 insert_olap_object(p_dim_set.LB_resync_program,'LB resync program',p_dim_set.LB_resync_program,
644 'program',p_kpi,'kpi',l_dimset_name_property);
645 end if;
646 if p_dim_set.aggregate_marker_program is not null then
647 insert_olap_object(p_dim_set.aggregate_marker_program,'aggregate marker program',p_dim_set.aggregate_marker_program,'program',p_kpi,'kpi',
648 l_dimset_name_property);
649 end if;
650 --the relational types and views
651 for i in 1..p_dim_set.s_view.count loop
652 if p_dim_set.s_view(i).type_name is not null then
653 insert_olap_object(p_dim_set.s_view(i).type_name,'relational type',null,null,p_kpi,'kpi',l_dimset_name_property);
654 end if;
655 if p_dim_set.s_view(i).s_view is not null then
656 insert_olap_object(p_dim_set.s_view(i).s_view,'relational view',null,null,p_kpi,'kpi',l_dimset_name_property);
657 end if;
658 end loop;
659 --zero code mviews
660 for i in 1..p_dim_set.z_s_view.count loop
661 if p_dim_set.z_s_view(i).type_name is not null then
662 insert_olap_object(p_dim_set.z_s_view(i).type_name,'relational type',null,null,p_kpi,'kpi',l_dimset_name_property||'zero code');
663 end if;
664 if p_dim_set.z_s_view(i).s_view is not null then
665 insert_olap_object(p_dim_set.z_s_view(i).s_view,'relational view',null,null,p_kpi,'kpi',l_dimset_name_property||'zero code');
666 end if;
667 end loop;
668 --
669 --=======bsc olap object relations===========
670 /*
671 we enter the following
672 given a dim set, the dimensions. for each dim, the levels. for each dim set, the cubes and the programs.
673 we also say if the level has zero code
674 to make objects unique, we will do obj+dimset.
675 otherwise there will be confusion. example
676 BSC_CCDIM_100 dimension AW dim set dim level HRI_PER dimension level lowest level,zero code=,
677 BSC_CCDIM_100 dimension AW dim set dim level HRI_PER dimension level lowest level,zero code=,
678 these are the dim entries for 2 dim sets. one dim set may have geog with 2 levels. another with 3 levels. if we know only the dim name,
679 we cannot know how many levels are in this dim set
680 */
681 for i in 1..p_dim_set.partition_template.count loop
682 l_property:='template type='||p_dim_set.partition_template(i).template_type||',template use='||p_dim_set.partition_template(i).template_use||
683 ',template dim='||p_dim_set.partition_template(i).template_dim;
684 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.partition_template(i).template_name,'partition name',
685 'dim set partition template',p_kpi,'kpi',l_property);
686 end loop;
687 --partition template partition info
688 for i in 1..p_dim_set.partition_template.count loop
689 for j in 1..p_dim_set.partition_template(i).template_partitions.count loop
690 l_property:='partition dim value='||p_dim_set.partition_template(i).template_partitions(j).partition_dim_value;
691 insert_olap_object_relation(p_dim_set.partition_template(i).template_name,'partition template',
692 p_dim_set.partition_template(i).template_partitions(j).partition_name,'partition name',
693 'partition template partition',p_kpi,'kpi',l_property);
694 end loop;
695 end loop;
696 --composites
697 for i in 1..p_dim_set.composite.count loop
698 l_property:='composite type='||p_dim_set.composite(i).composite_type;
699 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.composite(i).composite_name,'measure composite',
700 'dim set measure composite',p_kpi,'kpi',l_property);
701 end loop;
702 --cube sets
703 for i in 1..p_dim_set.cube_set.count loop
704 l_property:='cube set type='||p_dim_set.cube_set(i).cube_set_type||',measurename dim='||p_dim_set.cube_set(i).measurename_dim;
705 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.cube_set(i).cube_set_name,'cube set',
706 'dim set cube set',p_kpi,'kpi',l_property);
707 end loop;
708 --cubes in the cube set
709 for i in 1..p_dim_set.cube_set.count loop
710 l_property:='cube type='||p_dim_set.cube_set(i).cube.cube_type||',cube datatype='||p_dim_set.cube_set(i).cube.cube_datatype;
711 insert_olap_object_relation(p_dim_set.cube_set(i).cube_set_name,'cube set',p_dim_set.cube_set(i).cube.cube_name,'measure cube',
712 'cube set measure cube',p_kpi,'kpi',l_property);
713 if p_dim_set.cube_set(i).countvar_cube.cube_name is not null then
714 l_property:='cube type='||p_dim_set.cube_set(i).countvar_cube.cube_type||',cube datatype='||
715 p_dim_set.cube_set(i).countvar_cube.cube_datatype;
716 insert_olap_object_relation(p_dim_set.cube_set(i).cube_set_name,'cube set',p_dim_set.cube_set(i).countvar_cube.cube_name,'countvar cube',
717 'cube set countvar cube',p_kpi,'kpi',l_property);
718 end if;
719 if p_dim_set.cube_set(i).display_cube.cube_name is not null then
720 l_property:='cube type='||p_dim_set.cube_set(i).display_cube.cube_type||',cube datatype='||
721 p_dim_set.cube_set(i).display_cube.cube_datatype;
722 insert_olap_object_relation(p_dim_set.cube_set(i).cube_set_name,'cube set',p_dim_set.cube_set(i).display_cube.cube_name,'display cube',
723 'cube set display cube',p_kpi,'kpi',l_property);
724 end if;
725 /*
726 right now, we do not create the fcst cube. so we do not register it in olap pbjects. if we register it there, in 10g, lock acquire
727 fails with Exception in get_lock ORA-34492: Analytic workspace object BUGLOG_2_4014_FCST does not exist.
728 */
729 end loop;
730 --cube info
731 for i in 1..p_dim_set.cube_set.count loop
732 for j in 1..p_dim_set.cube_set(i).cube.cube_axis.count loop
733 l_property:='axis type='||p_dim_set.cube_set(i).cube.cube_axis(j).axis_type;
734 insert_olap_object_relation(p_dim_set.cube_set(i).cube.cube_name,'cube',
735 p_dim_set.cube_set(i).cube.cube_axis(j).axis_name,'axis name','cube axis',p_kpi,'kpi',l_property);
736 --
737 if p_dim_set.cube_set(i).countvar_cube.cube_name is not null then
738 l_property:='axis type='||p_dim_set.cube_set(i).countvar_cube.cube_axis(j).axis_type;
739 insert_olap_object_relation(p_dim_set.cube_set(i).countvar_cube.cube_name,'cube',
740 p_dim_set.cube_set(i).countvar_cube.cube_axis(j).axis_name,'axis name','cube axis',p_kpi,'kpi',l_property);
741 end if;
742 end loop;
743 if p_dim_set.cube_set(i).display_cube.cube_name is not null then
744 for j in 1..p_dim_set.cube_set(i).display_cube.cube_axis.count loop
745 l_property:='axis type='||p_dim_set.cube_set(i).display_cube.cube_axis(j).axis_type;
746 insert_olap_object_relation(p_dim_set.cube_set(i).display_cube.cube_name,'cube',
747 p_dim_set.cube_set(i).display_cube.cube_axis(j).axis_name,'axis name','cube axis',p_kpi,'kpi',l_property);
748 end loop;
749 end if;
750 end loop;
751 --for each dim set, enter the dim
752 for i in 1..p_dim_set.dim.count loop
753 l_property:='limit cube='||p_dim_set.dim(i).limit_cube||',limit cube composite='||p_dim_set.dim(i).limit_cube_composite||
754 ',aggregate marker='||p_dim_set.dim(i).aggregate_marker||',agg map='||p_dim_set.dim(i).agg_map.agg_map||',agg level='||
755 p_dim_set.dim(i).agg_level||',';
756 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.dim(i).dim_name,'dimension',
757 'dim set dim',p_kpi,'kpi',l_property);
758 --we need the levels to know which levels to aggregate to
759 for j in 1..p_dim_set.dim(i).levels.count loop
760 l_property:=null;
761 if j=1 then --lowest level
762 l_property:='lowest level,';
763 end if;
764 l_property:=l_property||'zero code='||p_dim_set.dim(i).levels(j).zero_code||',position='||p_dim_set.dim(i).levels(j).position||','||
765 'aggregated='||p_dim_set.dim(i).levels(j).aggregated||',zero_aggregated='||p_dim_set.dim(i).levels(j).zero_aggregated||',';
766 insert_olap_object_relation(p_dim_set.dim(i).dim_name||'+'||p_dim_set.dim_set_name,'dimension',
767 p_dim_set.dim(i).levels(j).level_name,'dimension level','dim set dim level',p_kpi,'kpi',l_property);
768 end loop;
769 --we need to register the limit cube with object as the dim. this is for bsc_aw_load_dim.set_kpi_limit_variables
770 --we also register the aggregate markers
771 l_property:='dim set type='||p_dim_set.dim_set_type||',';
772 insert_olap_object_relation(p_dim_set.dim(i).dim_name,'dimension',p_dim_set.dim(i).limit_cube,'kpi limit cube','kpi limit cube',
773 p_kpi,'kpi',l_property);
774 if p_dim_set.dim(i).aggregate_marker is not null then
775 insert_olap_object_relation(p_dim_set.dim(i).dim_name,'dimension',p_dim_set.dim(i).aggregate_marker,'kpi aggregate marker','kpi aggregate marker',
776 p_kpi,'kpi',l_property);
777 end if;
778 if p_dim_set.dim(i).reset_cube is not null then
779 insert_olap_object_relation(p_dim_set.dim(i).dim_name,'dimension',p_dim_set.dim(i).reset_cube,'kpi reset cube','kpi reset cube',
780 p_kpi,'kpi',l_property);
781 end if;
782 --need to register the kpi as belonging to the dim
783 merge_olap_object_relation(p_kpi,'kpi',p_kpi,'kpi','dimension kpi',p_dim_set.dim(i).dim_name,'dimension',null);
784 end loop;
785 --target dim
786 --we dont need limit cubes or agg maps here. targets will have the same dim as actuals, levels though are diff. but when we
787 --load targets, the limit cubes will correctly catch the level and when we aggregate, only those levels are aggregated up
788 --say target is at state. when we aggregate after loading targets, we aggregate from state upwards
789 --std dimensions
790 --we dont need agg maps for std dim since they are single level dim
791 for i in 1..p_dim_set.std_dim.count loop
792 l_property:='limit cube='||p_dim_set.std_dim(i).limit_cube||',limit cube composite='||p_dim_set.std_dim(i).limit_cube_composite||
793 ',agg level='||p_dim_set.std_dim(i).agg_level||',';
794 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.std_dim(i).dim_name,'dimension',
795 'dim set std dim',p_kpi,'kpi',l_property);
796 --we need the levels to know which levels to aggregate to
797 for j in 1..p_dim_set.std_dim(i).levels.count loop
798 l_property:=null;
799 if j=1 then --lowest level
800 l_property:='lowest level,';
801 end if;
802 --initially we had "dim set std dim level". this is not reqd. type and projection are std dim. levels within them are
803 --just levels of a dim
804 insert_olap_object_relation(p_dim_set.std_dim(i).dim_name||'+'||p_dim_set.dim_set_name,'dimension',
805 p_dim_set.std_dim(i).levels(j).level_name,'dimension level','dim set dim level',p_kpi,'kpi',l_property);
806 end loop;
807 end loop;
808 --for each dim set, enter calendar info
809 --we need calendar info since we need to aggregate on time
810 l_property:='calendar='||p_dim_set.calendar.calendar||',limit cube='||p_dim_set.calendar.limit_cube||','||
811 'limit cube composite='||p_dim_set.calendar.limit_cube_composite||',aggregate marker='||p_dim_set.calendar.aggregate_marker||',agg map='||
812 p_dim_set.calendar.agg_map.agg_map;
813 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.calendar.aw_dim,'calendar',
814 'dim set calendar', p_kpi,'kpi',l_property);
815 --note>>> we are not adding an entry for "kpi aggregate marker" for calendar because hier changes in calendar always result in full
816 --refresh of the calendar. so we dont track hier changes in calendar
817 for i in 1..p_dim_set.calendar.periodicity.count loop
818 l_property:='periodicity='||p_dim_set.calendar.periodicity(i).periodicity||',';
819 --if i=1 then --lowest periodicity
820 if p_dim_set.calendar.periodicity(i).lowest_level='Y' then
821 l_property:=l_property||'lowest level,';
822 end if;
823 if p_dim_set.calendar.periodicity(i).missing_level='Y' then
824 l_property:=l_property||'missing level,';
825 end if;
826 l_property:=l_property||'aggregated='||p_dim_set.calendar.periodicity(i).aggregated||',periodicity_type='||
827 p_dim_set.calendar.periodicity(i).periodicity_type;
828 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.calendar.periodicity(i).aw_dim,
829 'periodicity','dim set periodicity',p_kpi,'kpi',l_property);
830 end loop;
831 --log the agg map info
832 l_property:=null;
833 if p_dim_set.agg_map.agg_map is not null then
834 if p_dim_set.agg_map.created='Y' then
835 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.agg_map.agg_map,'agg map','dim set agg map',
836 p_kpi,'kpi',l_property);
837 end if;
838 l_property:=null;
839 if p_dim_set.agg_map_notime.created='Y' then
840 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.agg_map_notime.agg_map,'agg map',
841 'dim set agg map notime',p_kpi,'kpi',l_property);
842 end if;
843 --aggmap_operator properties
844 l_property:=null;
845 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.aggmap_operator.measure_dim,
846 'agg map measure dim','agg map measure dim',p_kpi,'kpi',l_property);
847 l_property:=null;
848 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.aggmap_operator.opvar,
849 'agg map opvar','agg map opvar',p_kpi,'kpi',l_property);
850 l_property:=null;
851 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.aggmap_operator.argvar,
852 'agg map argvar','agg map argvar',p_kpi,'kpi',l_property);
853 end if;
854 --dim set cubes
855 for i in 1..p_dim_set.measure.count loop
856 l_property:='agg formula='||p_dim_set.measure(i).agg_formula.agg_formula||',std agg='||p_dim_set.measure(i).agg_formula.std_aggregation||','||
857 'avg agg='||p_dim_set.measure(i).agg_formula.avg_aggregation||',sql aggregated='||p_dim_set.measure(i).sql_aggregated||
858 ',forecast='||p_dim_set.measure(i).forecast||',forecast method='||p_dim_set.measure(i).forecast_method||',';
859 l_property:=l_property||'cube='||p_dim_set.measure(i).cube||',fcst cube='||
860 p_dim_set.measure(i).fcst_cube||',countvar cube='||p_dim_set.measure(i).countvar_cube||','||
861 'display cube='||p_dim_set.measure(i).display_cube||','||
862 'measure type='||p_dim_set.measure(i).measure_type||',';
863 if p_dim_set.measure(i).aw_formula.formula_name is not null then
864 l_property:=l_property||'aw formula='||p_dim_set.measure(i).aw_formula.formula_name||',';
865 end if;
866 --for non std aggregation, insert the agg formula cubes
867 if p_dim_set.measure(i).agg_formula.cubes.count>0 then
868 l_property:=l_property||'agg formula cubes=';
869 for j in 1..p_dim_set.measure(i).agg_formula.cubes.count loop
870 l_property:=l_property||p_dim_set.measure(i).agg_formula.cubes(j)||'+';
871 end loop;
872 l_property:=l_property||',';
873 end if;
874 if p_dim_set.measure(i).agg_formula.measures.count>0 then
875 l_property:=l_property||'agg formula measures=';
876 for j in 1..p_dim_set.measure(i).agg_formula.measures.count loop
877 l_property:=l_property||p_dim_set.measure(i).agg_formula.measures(j)||'+';
878 end loop;
879 l_property:=l_property||',';
880 end if;
881 l_property:=l_property||bsc_aw_utility.get_property_string(p_dim_set.measure(i).property);
882 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.measure(i).measure,'measure',
883 'dim set measure',p_kpi,'kpi',l_property);
884 end loop;
885 --programs
886 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.initial_load_program.program_name,'dml program',
887 'dml program initial load',p_kpi,'kpi',null);
888 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.inc_load_program.program_name,'dml program',
889 'dml program inc load',p_kpi,'kpi',null);
890 --
891 if p_dim_set.initial_load_program_parallel.program_name is not null then
892 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.initial_load_program_parallel.program_name,'dml program',
893 'dml program initial load parallel',p_kpi,'kpi',null);
894 end if;
895 if p_dim_set.inc_load_program_parallel.program_name is not null then
896 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.inc_load_program_parallel.program_name,'dml program',
897 'dml program inc load parallel',p_kpi,'kpi',null);
898 end if;
899 if p_dim_set.LB_resync_program is not null then
900 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.LB_resync_program,'LB resync program',
901 'LB resync program',p_kpi,'kpi',null);
902 end if;
903 --
904 if p_dim_set.aggregate_marker_program is not null then
905 insert_olap_object_relation(p_dim_set.dim_set_name,'kpi dimension set',p_dim_set.aggregate_marker_program,'aggregate marker program',
906 'aggregate marker program',p_kpi,'kpi',null);
907 end if;
908 -------------------
909 --given base tables, find the dimension sets they impact
910 --this is imp because, if we need to load a base table, we need tofind the dim set they impact and then load them
911 --data sources can share base tables. so first get the distinct list...this is not imp. if base table -> dim set repeats,
912 --its ok
913 bsc_aw_utility.init_is_new_value(1);
914 for i in 1..p_dim_set.inc_data_source.count loop
915 for j in 1..p_dim_set.inc_data_source(i).base_tables.count loop
916 if bsc_aw_utility.is_new_value(p_dim_set.inc_data_source(i).base_tables(j).base_table_name,1) then
917 --note>>>load kpi module (api load_kpi_dimset_base_table) has dependency on how property looks like.
918 --if l_property needs to be changed, make the change in load kpi module also
919 l_property:='base table periodicity='||p_dim_set.inc_data_source(i).base_tables(j).periodicity.periodicity||
920 ',current change vector=0,measures=';
921 for k in 1..p_dim_set.inc_data_source(i).measure.count loop
922 l_property:=l_property||p_dim_set.inc_data_source(i).measure(k).measure||'+';
923 end loop;
924 insert_olap_object_relation(p_dim_set.inc_data_source(i).base_tables(j).base_table_name,'base table',
925 p_dim_set.dim_set_name,'dimension set','base table dim set',p_kpi,'kpi',l_property);
926 --for each base table, create an entry that will hold the current load set id (in change_vector column)
927 l_bsc_olap_object_relation.delete;
928 get_bsc_olap_object_relation(p_dim_set.inc_data_source(i).base_tables(j).base_table_name,'base table','base table change vector',
929 p_dim_set.inc_data_source(i).base_tables(j).base_table_name,'base table',l_bsc_olap_object_relation);
930 --if the entry is new, create one, we enter 0 as the current change vector value
931 --these base table entries need to be periodically validated and cleaned up. a base table may no longer be used
932 if l_bsc_olap_object_relation.count=0 then
933 insert_olap_object_relation(p_dim_set.inc_data_source(i).base_tables(j).base_table_name,'base table',
934 '0','change vector','base table change vector',p_dim_set.inc_data_source(i).base_tables(j).base_table_name,'base table',null);
935 end if;
936 end if;
937 end loop;
938 end loop;
939 Exception when others then
940 log_n('Exception in create_kpi '||sqlerrm);
941 raise;
942 End;
943
944 procedure insert_olap_object(
945 p_object varchar2,
946 p_object_type varchar2,
947 p_olap_object varchar2,
948 p_olap_object_type varchar2,
949 p_parent_object varchar2,
950 p_parent_object_type varchar2,
951 p_property1 varchar2
952 ) is
953 Begin
954 default_context_if_null;
955 if p_object is not null then
956 insert into bsc_olap_object(object,object_type,olap_object,olap_object_type,property1,parent_object,parent_object_type,
957 CREATION_DATE,LAST_UPDATE_DATE,CREATED_BY,LAST_UPDATED_BY,LAST_UPDATE_LOGIN,CONTEXT)
958 values (p_object,p_object_type,p_olap_object,p_olap_object_type,p_property1,p_parent_object,p_parent_object_type,
959 sysdate,sysdate,g_who,g_who,g_who,g_context);
960 end if;
961 Exception when others then
962 log_n('Exception in insert_olap_object '||sqlerrm);
963 raise;
964 End;
965
966 /*
967 check
968 p_object varchar2,
969 p_object_type varchar2,
970 p_parent_object varchar2,
971 p_parent_object_type varchar2,
972 then insert if needed. later we will see if update is needed else.
973 we do not match olap_object also since given an object and object type, we must not have multiple olap objects for the same entity
974 */
975 procedure merge_olap_object(
976 p_object varchar2,
977 p_object_type varchar2,
978 p_olap_object varchar2,
979 p_olap_object_type varchar2,
980 p_parent_object varchar2,
981 p_parent_object_type varchar2,
982 p_property1 varchar2
983 ) is
984 --
985 l_bsc_olap_object bsc_olap_object_tb;
986 Begin
987 default_context_if_null;
988 get_bsc_olap_object(p_object,p_object_type,p_parent_object,p_parent_object_type,l_bsc_olap_object);
989 if l_bsc_olap_object.count>0 then
990 null;
991 /*update is risky here. we can have multiple rows of data in l_bsc_olap_object. so which rows do we update here?*/
992 else
993 insert_olap_object(p_object,p_object_type,p_olap_object,p_olap_object_type,p_parent_object,p_parent_object_type,p_property1);
994 end if;
995 Exception when others then
996 log_n('Exception in merge_olap_object '||sqlerrm);
997 raise;
998 End;
999
1000 procedure insert_olap_object_relation(
1001 p_object varchar2,
1002 p_object_type varchar2,
1003 p_relation_object varchar2,
1004 p_relation_object_type varchar2,
1005 p_relation_type varchar2,
1006 p_parent_object varchar2,
1007 p_parent_object_type varchar2,
1008 p_property1 varchar2
1009 ) is
1010 Begin
1011 default_context_if_null;
1012 if p_object is not null then
1013 insert into bsc_olap_object_relation(object,object_type,relation_object,relation_object_type,
1014 relation_type,parent_object,parent_object_type,property1,
1015 CREATION_DATE,LAST_UPDATE_DATE,CREATED_BY,LAST_UPDATED_BY,LAST_UPDATE_LOGIN,CONTEXT)
1016 values (p_object,p_object_type,p_relation_object,p_relation_object_type,
1017 p_relation_type,p_parent_object,p_parent_object_type,p_property1,
1018 sysdate,sysdate,g_who,g_who,g_who,g_context);
1019 end if;
1020 Exception when others then
1021 log_n('Exception in insert_olap_object_relation '||sqlerrm);
1022 raise;
1023 End;
1024
1025 /*
1026 check
1027 p_object varchar2,
1028 p_object_type varchar2,
1029 p_relation_object varchar2,
1030 p_relation_object_type varchar2,
1031 p_relation_type varchar2,
1032 p_parent_object varchar2,
1033 p_parent_object_type varchar2,
1034 then insert...later update?
1035 */
1036 procedure merge_olap_object_relation(
1037 p_object varchar2,
1038 p_object_type varchar2,
1039 p_relation_object varchar2,
1040 p_relation_object_type varchar2,
1041 p_relation_type varchar2,
1042 p_parent_object varchar2,
1043 p_parent_object_type varchar2,
1044 p_property1 varchar2
1045 ) is
1046 --
1047 l_bsc_olap_object_relation bsc_olap_object_relation_tb;
1048 Begin
1049 default_context_if_null;
1050 get_bsc_olap_object_relation(p_object,p_object_type,p_relation_type,p_parent_object,p_parent_object_type,l_bsc_olap_object_relation);
1051 if l_bsc_olap_object_relation.count>0 then
1052 null;
1053 else
1054 insert into bsc_olap_object_relation(object,object_type,relation_object,relation_object_type,
1055 relation_type,parent_object,parent_object_type,property1,
1056 CREATION_DATE,LAST_UPDATE_DATE,CREATED_BY,LAST_UPDATED_BY,LAST_UPDATE_LOGIN,CONTEXT)
1057 values (p_object,p_object_type,p_relation_object,p_relation_object_type,
1058 p_relation_type,p_parent_object,p_parent_object_type,p_property1,
1059 sysdate,sysdate,g_who,g_who,g_who,g_context);
1060 end if;
1061 Exception when others then
1062 log_n('Exception in insert_olap_object_relation '||sqlerrm);
1063 raise;
1064 End;
1065
1066 /*
1067 input:
1068 p_object varchar2,
1069 p_object_type varchar2,
1070 p_relation_type varchar2,
1071 p_parent_object varchar2,
1072 p_parent_object_type varchar2,
1073
1074 update:
1075 p_relation_object varchar2,
1076 p_relation_object_type varchar2,
1077 p_property varchar2
1078 */
1079 procedure update_olap_object_relation(
1080 p_object varchar2,
1081 p_object_type varchar2,
1082 p_relation_type varchar2,
1083 p_parent_object varchar2,
1084 p_parent_object_type varchar2,
1085 p_match_columns dbms_sql.varchar2_table,
1086 p_match_values dbms_sql.varchar2_table,
1087 p_set_columns dbms_sql.varchar2_table,
1088 p_set_values dbms_sql.varchar2_table
1089 ) is
1090 --
1091 l_stmt varchar2(8000);
1092 Begin
1093 default_context_if_null;
1094 l_stmt:='update bsc_olap_object_relation set ';
1095 for i in 1..p_set_columns.count loop
1096 l_stmt:=l_stmt||p_set_columns(i)||'='''||p_set_values(i)||''',';
1097 end loop;
1098 l_stmt:=substr(l_stmt,1,length(l_stmt)-1);
1099 l_stmt:=l_stmt||' where object=:1 and object_type=:2 and relation_type=:3 and parent_object=:4 and parent_object_type=:5 and context=:6';
1100 for i in 1..p_match_columns.count loop
1101 l_stmt:=l_stmt||' and '||p_match_columns(i)||'='''||p_match_values(i)||'''';
1102 end loop;
1103 if g_debug then
1104 log(l_stmt||' using '||p_object||','||p_object_type||','||p_relation_type||','||p_parent_object||','||p_parent_object_type||','||
1105 g_context);
1106 end if;
1107 execute immediate l_stmt using p_object,p_object_type,p_relation_type,p_parent_object,p_parent_object_type,g_context;
1108 if g_debug then
1109 log('Updated '||sql%rowcount||' rows');
1110 end if;
1111 Exception when others then
1112 log_n('Exception in update_olap_object_relation '||sqlerrm);
1113 raise;
1114 End;
1115
1116 /*
1117 input :
1118 p_object varchar2,
1119 p_object_type varchar2,
1120 p_parent_object varchar2,
1121 p_parent_object_type varchar2
1122
1123 update
1124 p_olap_object varchar2,
1125 p_olap_object_type varchar2,
1126 p_property varchar2,
1127 p_operation_flag varchar2
1128
1129 */
1130 procedure update_olap_object(
1131 p_object varchar2,
1132 p_object_type varchar2,
1133 p_parent_object varchar2,
1134 p_parent_object_type varchar2,
1135 p_match_columns dbms_sql.varchar2_table,
1136 p_match_values dbms_sql.varchar2_table,
1137 p_set_columns dbms_sql.varchar2_table,
1138 p_set_values dbms_sql.varchar2_table
1139 ) is
1140 --
1141 l_stmt varchar2(8000);
1142 Begin
1143 default_context_if_null;
1144 l_stmt:='update bsc_olap_object set ';
1145 for i in 1..p_set_columns.count loop
1146 l_stmt:=l_stmt||p_set_columns(i)||'='''||p_set_values(i)||''',';
1147 end loop;
1148 l_stmt:=l_stmt||'last_update_date=sysdate';
1149 l_stmt:=l_stmt||' where object=:1 and object_type=:2 and parent_object=:3 and parent_object_type=:4 and context=:5';
1150 for i in 1..p_match_columns.count loop
1151 l_stmt:=l_stmt||' and '||p_match_columns(i)||'='''||p_match_values(i)||'''';
1152 end loop;
1153 if g_debug then
1154 log(l_stmt||' using '||p_object||','||p_object_type||','||p_parent_object||','||p_parent_object_type||','||g_context);
1155 end if;
1156 execute immediate l_stmt using p_object,p_object_type,p_parent_object,p_parent_object_type,g_context;
1157 if g_debug then
1158 log('Updated '||sql%rowcount||' rows');
1159 end if;
1160 Exception when others then
1161 log_n('Exception in update_olap_object '||sqlerrm);
1162 raise;
1163 End;
1164
1165 /*
1166 delete oor
1167 any parameter can be null. if all are null, full delete happens
1168 */
1169 procedure delete_olap_object_relation(
1170 p_object varchar2,
1171 p_object_type varchar2,
1172 p_relation_type varchar2,
1173 p_relation_object varchar2,
1174 p_relation_object_type varchar2,
1175 p_parent_object varchar2,
1176 p_parent_object_type varchar2) is
1177 --
1178 Begin
1179 default_context_if_null;
1180 if g_debug then
1181 log('delete_olap_object_relation:object='||p_object||', object_type='||p_object_type||
1182 ', p_relation_type='||p_relation_type||', p_relation_object='||p_relation_object||
1183 ', p_relation_object_type='||p_relation_object_type||', p_parent_object='||p_parent_object||
1184 ', p_parent_object_type='||p_parent_object_type||bsc_aw_utility.get_time);
1185 end if;
1186 delete bsc_olap_object_relation
1187 where object=nvl(p_object,object)
1188 and object_type=nvl(p_object_type,object_type)
1189 and relation_type=nvl(p_relation_type,relation_type)
1190 and relation_object=nvl(p_relation_object,relation_object)
1191 and relation_object_type=nvl(p_relation_object_type,relation_object_type)
1192 and parent_object=nvl(p_parent_object,parent_object)
1193 and parent_object_type=nvl(p_parent_object_type,parent_object_type)
1194 and context=g_context;
1195 if g_debug then
1196 log('Deleted '||sql%rowcount||' rows'||bsc_aw_utility.get_time);
1197 end if;
1198 Exception when others then
1199 log_n('Exception in delete_olap_object_relation '||sqlerrm);
1200 raise;
1201 End;
1202
1203 procedure delete_olap_object(
1204 p_object varchar2,
1205 p_object_type varchar2,
1206 p_olap_object varchar2,
1207 p_olap_object_type varchar2,
1208 p_parent_object varchar2,
1209 p_parent_object_type varchar2) is
1210 --
1211 Begin
1212 default_context_if_null;
1213 if g_debug then
1214 log('delete_olap_object:object='||p_object||', object_type='||p_object_type||
1215 ', p_olap_object='||p_olap_object||', p_olap_object_type='||p_olap_object_type||
1216 ', p_parent_object='||p_parent_object||', p_parent_object_type='||p_parent_object_type||bsc_aw_utility.get_time);
1217 end if;
1218 delete bsc_olap_object
1219 where object=nvl(p_object,object)
1220 and object_type=nvl(p_object_type,object_type)
1221 and olap_object=nvl(p_olap_object,olap_object)
1222 and olap_object_type=nvl(p_olap_object_type,olap_object_type)
1223 and parent_object=nvl(p_parent_object,parent_object)
1224 and parent_object_type=nvl(p_parent_object_type,parent_object_type)
1225 and context=g_context;
1226 if g_debug then
1227 log('Deleted '||sql%rowcount||' rows'||bsc_aw_utility.get_time);
1228 end if;
1229 Exception when others then
1230 log_n('Exception in delete_olap_object '||sqlerrm);
1231 raise;
1232 End;
1233
1234 -------------------------------
1235 ---workspace metadata
1236 procedure create_workspace(p_name varchar2) is
1237 Begin
1238 default_context_if_null;
1239 insert into bsc_olap_object(object,object_type,olap_object,olap_object_type,property1,parent_object,parent_object_type,
1240 CREATION_DATE,LAST_UPDATE_DATE,CREATED_BY,LAST_UPDATED_BY,LAST_UPDATE_LOGIN,CONTEXT)
1241 values (p_name,'aw workspace',p_name,'aw workspace','BSC AW Workspace','BSC','APPS',
1242 sysdate,sysdate,g_who,g_who,g_who,g_context);
1243 Exception when others then
1244 log_n('Exception in create_workspace '||sqlerrm);
1245 raise;
1246 End;
1247
1248 procedure drop_workspace(p_name varchar2) is
1249 Begin
1250 default_context_if_null;
1251 delete bsc_olap_object where object=p_name;
1252 Exception when others then
1253 log_n('Exception in drop_workspace '||sqlerrm);
1254 raise;
1255 End;
1256
1257 /*
1258 managing info on loads, aggregations, locks etc
1259 in bsc_olap_object, we will use property9 and 10 (9 for now) to store the load start time, end time
1260 session id etc. it will be stored as
1261 load+start time=01:01:2000:12:12:12+end time=01:01:2000:12:12:12+session id=1022,aggregation+..
1262 groups are separated by comma. elements in each group are separated by +.
1263 this is read into a table of records format. then we can update, insert etc.
1264 its then saved back into this format
1265 we have 2 api
1266 get_runtime_parameters(obj,objtype,par obj,par objtype,table of records (output))
1267 update_runtime_parameters(table of records (input))
1268 table of records has obj,type,par obj and par obj type so we can update
1269 */
1270 /*
1271 types of input
1272 obj yes, obj type yes, par obj yes, par obj type yes
1273 obj yes, obj type yes, par obj no, par obj type no
1274 obj no, obj type no, par obj yes, par obj type yes
1275 obj no, obj type no, par obj no, par obj type no
1276
1277 procedure get_runtime_parameters(
1278 object varchar2,
1279 object_type varchar2,
1280 parent_object varchar2,
1281 parent_object_type varchar2,
1282 p_parameters out nocopy bsc_runtime_tb
1283 ) is
1284 --
1285 --
1286 Begin
1287 null;
1288 Exception when others then
1289 log_n('Exception in get_runtime_parameters '||sqlerrm);
1290 raise;
1291 End;
1292
1293 will implement at a later date
1294 */
1295
1296 procedure analyze_md_tables is
1297 Begin
1298 bsc_aw_utility.analyze_table('BSC_OLAP_OBJECT',60);
1299 bsc_aw_utility.analyze_table('BSC_OLAP_OBJECT_RELATION',60);
1300 Exception when others then
1301 log_n('Exception in analyze_md_tables '||sqlerrm);
1302 raise;
1303 End;
1304
1305 -------------------------------
1306 procedure init_all is
1307 Begin
1308 g_context:='AW';--default
1309 g_who:=bsc_aw_utility.get_who;
1310 g_debug:=bsc_aw_utility.g_debug;
1311 Exception when others then
1312 null;
1313 End;
1314
1315 procedure log(p_message varchar2) is
1316 Begin
1317 bsc_aw_utility.log(p_message);
1318 Exception when others then
1319 null;
1320 End;
1321
1322 procedure log_n(p_message varchar2) is
1323 Begin
1324 log(' ');
1325 log(p_message);
1326 Exception when others then
1327 null;
1328 End;
1329
1330 END BSC_AW_MD_WRAPPER;