Job family, relationship to job
Hello together,
it is possible to assign one job(C) to several job families(JF)?
For example functional area "IT" has job families “IT development” and “IT support”. I have to assign job “Consultant” to both job families. Even though relationship A/B 450 has time constraint 3, I can assign the job “Consultant” either to “IT development” or to “IT support” but not to both JF’s.
Thanks
Regards
Dietrich
Hi Dietrich,
It's not possible in the standard system and there could be many repercussions if you change this.
Best regards,
Luke
Similar Messages
-
Job code to Job Family Relationship
Hi Experts,
I noticed that only one Job code can be related to a Job Family (via A450 relationship).
For example, if Job code 1 is linked to Job Family and later if I link Job code 2 to the same Job Family, the relationship between
Job code 1 and the Job Family is lost.
Is it possible to have several Job codes associated with one Job Family? Please list any config steps to do the same.
Thanks in advance.
PaulHi Paul,
Let me explain if I have understood you properly.
1. You create relationship between Job 1 and Job family on 01.01.2010
2. You create relationship between job 2 and job family on 01.01.2010
Now you after second step you the first relationship is erased, right.
This is because of the time constraints for relationship A 045. The time constraint must be 2 in your config. Make it to 3.
or you can also have time constraint based on the target object ID.
Steps to follow.
-Go to OOVK t-code
-select your relationship
- click on time constraints on the left hand side
- find the entry for your relationship. I think it should be 2 . Make it to 3
Hope it works
Ajay -
How do i get rid of Claro-Search taking over NEW TAB function?
Claro-Search took over our Firefox settings when opening NEW TAB.
I already took back the general internet search Navigation Bar and default sign on page. But I cannot find out how Claro-Search.com is using the New Tab.Hi Calrosearch (typo?), it's curious that the images on that page are hosted on babylon.com. Is there a family relationship between Claro search and the often discussed Babylon software?
The video only covers one of the steps on the removal page, so that certainly could be improved.
I noticed in the instructions on this separate page that users might also need to remove a toolbar (using the Firefox Add-ons > Extensions page): http://www.claro-search.com/uninstall.htm
I'm not sure it's fair to characterize the cleanup as "easy." Allow me to summarize:
''On Windows''
(0) Use the Control Panel Add/Remove Programs or Programs and Settings to uninstall the "Browser Manager" program.
''In Firefox''
(1) Check for any unwanted/unknown Extension (e.g., "Claro Toolbar" or "Browser Manager") here and remove it:
(WIN) orange Firefox button ''or'' classic Tools menu > Add-ons > Extensions<br>
(MAC)(LINUX) Tools > Add-ons > Extensions
(2) To remove any unwanted search engine plugin, click the icon at the left of the search bar and use Manage Search Engines. Then choose your preferred default search engine on the drop-down list.
(3) To reset your home page, use the "Restore to Default" button (if you want the built-in Firefox home page) here:
(WIN) orange Firefox button ''or'' classic Tools menu > Options > General tab<br>
(MAC) Firefox > Preferences > General tab<br>
(LINUX) Edit > Preferences > General tab
If you prefer a different home page, you can paste the URL there or if you are viewing the page(s) you want, you can click the Use Current Pages button to store all tabs in the current window as your home page(s). More info: [[How to set the home page]].
(4) To reset the behavior of the "new tab" you can use these steps:
(A) In a new tab, type or paste '''about:config''' in the address bar and press Enter. Click the button promising to be careful.
(B) In the filter box, type or paste '''newtab''' and pause while the list is filtered
(C) Double-click the '''browser.newtab.url''' preference and enter the desired value:
''(i) Page thumbnails (default)''
browser.newtab.url = about:newtab
''(ii) Blank tab''
browser.newtab.url = about:blank
''(iii) Built-in Firefox home page''
browser.newtab.url = about:home
''(iv) Any other page''
browser.newtab.url = full URL to the page
(5) While you have the about:config tab open, you can filter on '''claro''' and adjust any other relevant settings back to your preferred setting.
(6) If your changes are reverted after your next restart of Firefox, you may also need to edit or delete a settings file in your personal Firefox settings folder (AKA Firefox profile folder).
To access the folder, use:
Help > Troubleshooting Information > "Show Folder" button.
Switch back to Firefox and Exit
Pause while Firefox finishes its cleanup, then rename '''user.js''' to something like user.old (or just delete it).
Restart Firefox and repeat steps (3) - (5) if needed. Hopefully for the last time.
That's a lot to expect from a user who may not even have realized they were installing the product and if they did what that would mean for their browsing experience. I'm sure if this happened to you unexpectedly, you would be aggravated, too. -
Inserting multiple rows on one "Add Button"!
I have an appliation that tracks family members (address book type app).
form page that tracks "family relationships"
(http://apex.oracle.com/pls/otn/f?p=55283:2)
Page 2/3 are Master Details, where the detail reports are "relationships"
From page three, if I select "Create" it takes me to the Form page
(http://apex.oracle.com/pls/otn/f?p=55283:4) where I can create a relationship and hit "create" and the new record is now visible on page 3.
What I'm trying to do, is create the inverse tie record at the same time. For example.
If I say
record 1 is related to record 2 as "value 3"
I then want to at the same time, create an inverse record:
record 2 is related to record 1 as "value 4".
After researching the forum, I put my best effort into creating a button on page 4 called "Add New" (Thanks Andy for the idea!!) and a page process to run when this button is selected.
There is a PK for the table in questions, that uses a sequence. I'm just learning SQL AND APEX, so I may have totally missed the boat...either way, this errors out on my instance i have on a closed network.
(Unfortunately, my local firewall is not allowing me to post my SQL for the
Here's my page process that fails:
-- Take values from the three page items to create the first row:
INSERT INTO FAMILY_ASSOC
(FAMILY_ASSOC_ID, FAMILY_ID_1, FAMILY_ASSOC, FAMILY_ID_2) VALUES (
FAMILY_ASSOC_SEQ.nextval,
P4_FAMILY_ID_1,
P4_FAMILY_ASSOC,
P4_FAMILY_ID_2)
-- Now reverse the ID_1 and ID_2 to create the Inverse record
-- For example if the row input above is "X" is child of "Y"
-- Need to create record "Y" is parent of "X"
UNION (
FAMILY_ASSOC_SEQ.nextval,
P4_FAMILY_ID_1,
DECODE(P4_FAMILY_ASSOC,
'1','1',
'2','2',
'3','4',
'4','3',
'5','5',
'6','6',
'7','8',
'8','7',
'9','10',
'10','9'),
P4_FAMILY_ID_2)
I've included some reports on page 4 to show what the table looks like:
One report shows all the associations for the individual, and replaces the values with lookup values.
The next report is exactly the same, but without the lookups.
The last report is the same thing, but shows the inverse relationships for the same individual.
Appreciate any ideas!!!Heck! And there was me trying to keep things simple :D
In order for the reports to show data before it is written into the actual records, you would need to have a staging table or, at least, store the values on the page in session BEFORE the insert process runs. To do that, you would have to have a two-step process - one to create the temporary data or store the values and the second to actually write the records. The SQL statements that underlie the reports can easily be updated to refer to either the staging table or the session values. Of course, you would have to create at least one additional button on the page - to create/store the data temporarily - this would have to be conditional - and, the existing button would also have to be conditional, so that only one of the two buttons is displayed at any one time.
Andy -
Hi Experts,
If I want to calculate the Component scrap in percent at all the levels of BOM
What is the way to proceed for it.
Thanks in Advance.
Regards,
IFFYes, Planning items and related BOM structures should be supported in 11i10 ASCP. The process is fundamentally the same as it is for Model items.
A key consideration is how you want to consume the resulting forecasts. Planning items are never entered on sales orders, so you will be consuming forecast at the component level below, which are typically models.
You may also want to consider product family relationships for these items. You can consume the forecast at that level and then explode to the lower level items.
For true subassemblies or component forecasting, it is often better to use safety stock in the short term and use a demand time fence to drop the forecast for product family members during that period.
Regards,
Kevin Creel
www.inspirage.com -
Problem in loading data in OLAP 10.2.
I created a cube with 9 dimensions, one of the dimension has three hierarchies defined; It works fine until one day it gives me "Data for at least One of the Hierarchies for ***Dimension controdicts the Definition of such Hierarchy as Level Based"; However, I checked the data, the data actually hold the one-many relationship btw parent level and child level within those hierarchies. Even more strangely, all three hierarchies works if they were the only hierarchy in the dimension. Any clue of this error? is it some bug in oracle olap?
specifically, Do two level based hierarchies affect each other if they are in same dimension? what is exactly level based hierarchy?Hi, Brijesh
Thank you very much for the reply. That's exactly what I thought at my first glance; however, I checked the data in each of the three hierarchies, they all hold the (one-parent to many child && one child to one parent) relationship; actually, if I remove any two of the three, the rest one will work just fine; the dimension is defined as following:
1. five levels: l1, l2, l3, l4, l5, where l1 is the surrogatekey, l5 is total;
2. Three hierarchies:
1) h1: l1-->l2-->l5, where l5 is parent of l2, and l2 is parent of l1;
2) h2: l1-->l3-->l5,
3) h3: l1-->l4-->l5
The case is that, only when both h1 and h2 exist in the dimension, it gives data controdict error. i.e: if the dimension is defined as (h1), (h2), (h3), (h1, h3) or (h2, h3) it will just work fine; data load fails only for dimension (h1, h2) or (h1, h2, h3).
It seems to me that even it's two independent hierarchy, they will actually affect each other's data consistency. Could this be a bug when oracle is creating family relationship, or inhier relationship for dimenstion? Any idea of this?
Thank you.
Marshall
Edited by: user4939641 on Jul 9, 2009 11:23 AM -
Upgrading from 9.2 to 10.2
I have a Powerbook G3 Wallstreet (256MB RAM, 10GB HDD) with OS 9.2.2 preinstalled but I don't have the disks. I plan to upgrade to Jaguar 10.2 and understand that I will have to reformat the hard drive to create a <8GB partition. However, while researching the process online one poster who was using the Leopard "upgrade disks" reported that after repartitioning the hard drive he had to reinstall 9.2 before he could finish the upgrade process. Does anyone know if this is true because if it is I will obviously have to purchase the full install rather than upgrade disks.
Thanks is advance for any assistance.
BryanHi, Bryan -
There is no upgrade disk that can take OS 9.2.2 to OSX 10.2 . There is no software 'family' relationship between the two; OS 9.2.2 was the last of the 'old' series of OSs, and OSX 10.0 was the first of a new series.
If OS 9 (any version) is present on the hard drive when OSX (any version) is installed, OSX will be installed alongside of OS 9, leaving both OSs present, intact, and usable (separately).
In order to install OSX, you will need to get the full-install retail disk set for the version you wish to install.
Unfortunately, none of the retail disk sets for OSX include the ability to install OS 9 (any version). If you need to re-imnstall OS 9.2.2, you will need to use a retail disk for OS 9.2.1 and then apply the download update for OS 9.2.2 (installable only when the machine is booted to OS 9).
Re partitioning the disk -
Check to see whether it may already be partitioned. On that model, OS 9 is also restricted to booting from the first 8GB of hard drive space -
http://support.apple.com/kb/TA22193
Unlike OSX's installer, the installer for OS 9 does not check for verification that that limitation has been complied with, and will install on volumes larger than 8GB. In such cases serendipity often places all of the OS within the first 8GB of the drive - when that happens, it runs fine; when that doesn't happen, the OS will either refuse to run or some of its services will not be available.
If the drive has already been partitioned, you should be able to use it as-is, provided there is sufficient disk space for an install of OSX 10.2 (which likes at least 3GB left unused); yuo can reduce the disk space OSX needs by selecting to not install all language versions when setting up the install (all is the default; a reduced set can be defined in the installer).
If you do need to partition the drive, you will lose the OS 9 (and everything else) already on the hard drive - whether using OS 9's Drive Setup or OSX's Disk Utility to do the partitioning, the process will erase the entire drive. Note - if you use OSX's Disk Utility to do the partitioning, be sure to select the option to install OS 9 Drivers; if that option is not selected, OS 0 will not be able to mount the drive. This means that you will not be able to install OS 9 onto it from a CD, nor use it for booting to OS 9.
There is an alternative to having to get a retail OS 9 Install CD in order to re-install OS 9. OS 9 can be copied and remain functional (unlike OSX which requires the use of a cloning utility). This means that you can copy (via drag and drop) the OS 9 System Folder and its primary subordinate folders, "Documents" and "Applications (Mac OS 9)" to an external drive, partition the drive, then copy that stuff back to the hard drive - it should then still work.
Note - if you do this, be sure the external drive has been formatted as Mac OS Extended (also called HFS+). If it has been formatted as a PC volume (as many thumb drives are), you will lose certain file characteristics required in order for the OS to remain functional - the files will be rendered useless. -
SIRI won't call "the mother of my girlfriend"
SIRI won't call "the mother of my girlfriend" and says that an error occured or calls my own "mother"!
Please, help me out. I work my self by an Apple Reseller and no one of my collegas can help me out!
*the problem is not coming from my Contacts Book or Settings because everything is perfectly configured and this error is recent !
Thanks.
Paul.I think that I was able to do that before... Because I have defined the family relationships of my girlfriend and I can't use them with Siri.
Thanks. -
Planning Bill of Material to explode forecast in ASCP 11i.10 .
I like to know if in addition to product familly and model bill of material , the planning bill of material can be used to explode forecast to lower levels and through several levels optionally in ASCP 11i.10 ?
Yes, Planning items and related BOM structures should be supported in 11i10 ASCP. The process is fundamentally the same as it is for Model items.
A key consideration is how you want to consume the resulting forecasts. Planning items are never entered on sales orders, so you will be consuming forecast at the component level below, which are typically models.
You may also want to consider product family relationships for these items. You can consume the forecast at that level and then explode to the lower level items.
For true subassemblies or component forecasting, it is often better to use safety stock in the short term and use a demand time fence to drop the forecast for product family members during that period.
Regards,
Kevin Creel
www.inspirage.com -
Creating relational views over dimensions and cubes in an analytic workspace has never been easier. Check out the new sample plug-in for Analytic Workspace Manager 10.2.0.3 that makes creating views a snap.
1) Right-click a dimension or cube object, then choose Create Relational View...
2) Choose the columns you'd like to see in your view, then click Create View.
Your OLAP data is now available to any relational tool. Download the OLAP View Generator from OTN and give it a try. It's fun for the whole family!
http://www.oracle.com/technology/products/bi/olap/index.htmlI logged a TAR with Oracle and they gave me a pl/sql fix, which works for me now. It looked to be a bug of sorts.
This is the whole install_olap_view_generator.sql but beware it drops and creates things.....
prompt Installing OLAP View Generator sample - Version 1.0.2
prompt
prompt >> Turning off prompting for substitution variables (set scan off)
set scan off
prompt >> Removing the olap_views user. Ignore error if user does not exist.
drop user olap_views cascade;
prompt >> Creating OLAP_VIEWS tablespace...
CREATE TABLESPACE OLAP_VIEWS
DATAFILE 'OLAP_VIEWS.DBF' SIZE 20M AUTOEXTEND ON NEXT 5M;
prompt >> Creating OLAP_VIEWS_TEMP temporary tablespace...
CREATE TEMPORARY TABLESPACE OLAP_VIEWS_TEMP
TEMPFILE 'OLAP_VIEWS_TEMP.DBF' SIZE 20M AUTOEXTEND ON NEXT 5M
UNIFORM SIZE 256K;
prompt >> Creating OLAP_VIEWS user...
CREATE USER OLAP_VIEWS
IDENTIFIED BY OLAP_VIEWS DEFAULT TABLESPACE OLAP_VIEWS
TEMPORARY TABLESPACE OLAP_VIEWS_TEMP
QUOTA UNLIMITED ON OLAP_VIEWS;
grant olap_user to OLAP_VIEWS;
grant create public synonym to olap_views;
prompt >> Connecting as olap_views user
connect olap_views/olap_views
prompt >> Creating tables that store information about OLAP views and mappings
CREATE TABLE OLAP_VIEWS.OLAP_MAPPINGS
( LAST_UPDATED DATE,
AW_LAST_UPDATED DATE,
AW_OWNER VARCHAR2(30 BYTE),
AW_NAME VARCHAR2(30 BYTE),
CUBE_NAME VARCHAR2(30 BYTE),
CLAUSE VARCHAR2(30 BYTE),
OBJECT_NAME VARCHAR2(30 BYTE),
HIERARCHY VARCHAR2(30 BYTE),
LEVEL_NAME VARCHAR2(30 BYTE),
COLUMN_NAME VARCHAR2(30 BYTE),
AW_OBJECT VARCHAR2(100 BYTE),
DATA_TYPE VARCHAR2(30 BYTE),
DIMENSION_DESC VARCHAR2(100 BYTE),
POSITION NUMBER,
COLUMN_LABEL VARCHAR2(100 BYTE),
DESCRIPTION VARCHAR2(1000),
INCLUDE NUMBER DEFAULT 1
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.LAST_UPDATED IS 'Timestamp when the view was created';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.AW_LAST_UPDATED IS 'Timestamp of the AW when the view was created';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.AW_OWNER IS 'Schema containing the analytic workspace';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.AW_NAME IS 'Name of the analytic workspace';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.CUBE_NAME IS 'Name of the cube for the given measure';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.CLAUSE IS 'Clause in the limitmap (FAMILYREL, DIMENSION, etc.)';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.OBJECT_NAME IS 'The name of the object (measure or dimension) being mapped';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.HIERARCHY IS 'The hierarchy for the dimension. A dimension may have multiple hierarchies.';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.LEVEL_NAME IS 'A level within a hierarchy.';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.COLUMN_NAME IS 'Column name for an AW object';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.AW_OBJECT IS 'The mapped AW object';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.DATA_TYPE IS 'Relational data type for the column';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.DIMENSION_DESC IS 'AW object representing the description for a dimension member';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.POSITION IS 'Sort order for levels in a hierarchy (aggregate to detail)';
COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.COLUMN_LABEL IS 'Label that can be displayed to users in client tools';
CREATE TABLE OLAP_VIEWS.OLAP_VIEW_OBJECTS
( LAST_UPDATED DATE,
AW_OWNER VARCHAR2(30),
AW_NAME VARCHAR2(30),
VIEW_NAME VARCHAR2(61),
DIMENSION_NAME VARCHAR2(30),
CUBE_NAME VARCHAR2(30)
CREATE TABLE OLAP_VIEWS.OLAP_VIEW_LIMITMAP
( LAST_UPDATED DATE,
AW_OWNER VARCHAR2(30),
AW_NAME VARCHAR2(30),
VIEW_NAME VARCHAR2(61),
LIMITMAP CLOB
CREATE TABLE OLAP_VIEWS.OLAP_VIEW_LOG
( msg_key number,
MSG_ID TIMESTAMP (9),
MESSAGE VARCHAR2(4000)
create sequence OLAP_VIEWS.olap_log_seq
start with 1
increment by 1
nomaxvalue;
create trigger OLAP_VIEWS.olap_log_trigger
before insert on OLAP_VIEWS.OLAP_VIEW_LOG
for each row
begin
select OLAP_VIEWS.olap_log_seq.nextval into :new.msg_key from dual;
end;
CREATE or REPLACE VIEW olap_views.version as
SELECT 'Version 1.0.2' version
FROM dual;
prompt >> Create synonyms for the tables
CREATE OR REPLACE PUBLIC SYNONYM olap_mappings FOR olap_views.olap_mappings;
CREATE OR REPLACE PUBLIC SYNONYM OLAP_VIEW_LIMITMAP FOR olap_views.OLAP_VIEW_LIMITMAP ;
CREATE OR REPLACE PUBLIC SYNONYM OLAP_VIEW_OBJECTS FOR olap_views.OLAP_VIEW_OBJECTS;
CREATE OR REPLACE PUBLIC SYNONYM OLAP_VIEW_LOG FOR olap_views.OLAP_VIEW_LOG;
prompt >> Grant privileges on synonyms to PUBLIC
grant all on olap_mappings to public;
grant all on OLAP_VIEW_LIMITMAP to public;
grant all on olap_view_objects to public;
grant all on olap_view_log to public;
grant select on olap_views.version to public;
prompt >> Define PL/SQL Package OLAP_VIEWGENERATOR
create or replace PACKAGE OLAP_ViewGenerator authid current_user AS
-- Create a report of the views created over the cube
PROCEDURE reportViewInfo (
strOwner varchar2,
strAWname varchar2
-- Create views over all the dimensions and cubes in the AW
PROCEDURE createAWViews (
strOwner varchar2,
strAWname varchar2);
-- Generate a view over a cube
PROCEDURE createCubeView (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2);
-- Generate a view over a dimension
-- RETURN: name of generated view
PROCEDURE createDimensionView (
strOwner varchar2,
strAWname varchar2,
strDimname varchar2);
-- Get the limitmap text for a cube
-- RETURN: limitmap text
FUNCTION getCubeLimitmap (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2) return clob;
-- Get the limitmap text for a dimension
-- RETURN: limitmap text
FUNCTION getDimensionLimitmap (strOwner varchar2,
strAWname varchar2,
strDimname varchar2) return clob;
-- Updates the OLAP_MAPPINGS table with info describing a dimension, including the following:
-- AW object, column mapped to object, type of object (e.g. dimension, hierarchy, familyrel, etc.),
-- label for the object, etc
-- RETURN: true if successful, false if fails
FUNCTION generateDimensionMap (
strOwner varchar2,
strAWname varchar2,
strDimname varchar2) RETURN number;
-- Updates the OLAP_MAPPINGS table with the info describing a cube's measures:
-- AW object, column mapped to object, label for the object, etc
-- RETURN: true if successful, false if fails
FUNCTION generateCubeMap (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2) return number;
FUNCTION getDataType (
strOwner varchar2,
strAWname varchar2,
strPhysObj varchar2) return varchar2;
END OLAP_ViewGenerator;
create or replace PACKAGE BODY OLAP_ViewGenerator AS
cachedate date; -- Date for the current run of the generator
bad_limitmap exception;
ATTACHED_RW constant number := 2;
ATTACHED_RO constant number := 1;
NOT_ATTACHED constant number := 0;
INCLUDE_LEVEL_ID constant number := 0; -- 0=FALSE, 1=TRUE
type log_record_type is record (msg_key number, msg_id timestamp, message varchar2(4000));
type log_table_type is table of log_record_type INDEX BY BINARY_INTEGER;
log_table log_table_type;
-- PRIVATE METHODS and PROCEDURES
-- Update the OLAP_VIEW_LOG table with contents of PL/SQL table
PROCEDURE updateLogTable as
BEGIN
delete olap_view_log;
commit;
FORALL i IN INDICES OF log_table
INSERT INTO olap_view_log
VALUES log_table (i);
commit;
-- Clear the log table
log_table.delete;
END updateLogTable;
-- Shortcut for displaying output
PROCEDURE show (message varchar2) as
msg varchar2(4000);
i number;
log_record log_record_type;
BEGIN
msg := '>> ' || to_char(systimestamp, 'MON-DD-YYYY HH:MI:SS') || ' - ' || message;
dbms_output.put_line(substr(msg, 1, 254));
i := log_table.count + 1;
log_record.msg_id := systimestamp;
log_record.message := message;
log_table(i) := log_record;
END show;
FUNCTION getDataType (
strOwner varchar2,
strAWname varchar2,
strPhysObj varchar2) return varchar2 as
dataType varchar2(10);
objName varchar2(100);
BEGIN
objName := upper(strOwner || '.' || strAWname || '!' || strPhysObj);
dataType := dbms_aw.interp('show obj(data ''' || objName || ''')');
-- Return NUMBER for all the number types
if dataType in ('INTEGER', 'LONGINTEGER', 'SHORTINTEGER', 'DECIMAL', 'SHORTDECIMAL')
then dataType := 'NUMBER';
else dataType := null;
end if;
return dataType;
EXCEPTION
when others then
return null;
END getDataType;
-- Attaches the specified AW r/w first
-- Returns the previous state of the AW:
-- 2 : Attached r/w
-- 1 : Attached r/o
-- 0 : Not attached
-- This state will be passed to detachAW in order to restore the AW to the previous state
FUNCTION attachAW (
strOwner varchar2,
strAWName varchar2) return number as
owner varchar2(30);
awname varchar2(30);
awlongname varchar2(100);
cmd varchar2(400);
isAttached number;
BEGIN
owner := upper(strOwner);
awname := upper(strAWName);
awlongname := upper(strOwner || '.' || strAWname);
-- Check if the AW is attached:
-- 2 : Attached r/w
-- 1 : Attached r/o
-- 0 : Not attached
cmd := 'if aw(attached ''' || awlongname || ''') and aw(rw ''' || awlongname || ''') then ' || ATTACHED_RW ||
' else if aw(attached ''' || awlongname || ''') and aw(ro ''' || awlongname || ''') then ' ||
ATTACHED_RO || ' else ' || NOT_ATTACHED;
isAttached := dbms_aw.eval_number(cmd);
-- Attach the AW r/w first
if isAttached = NOT_ATTACHED then
dbms_aw.aw_attach(owner, awname, true, false, 'FIRST');
elsif isAttached = ATTACHED_RO then
dbms_aw.aw_detach(owner, awname);
dbms_aw.aw_attach(owner, awname, true, false, 'FIRST');
else
dbms_aw.aw_attach(owner, awname, true, false, 'FIRST');
end if;
return isAttached;
exception
when others then
show ('**');
show ('** ERROR: Unable to attach AW ' || owner || '.' || awname || ' read-write.');
show ('** Ensure that you have priviliges to access the AW in this mode.');
show ('**');
raise;
END attachAW;
-- "Detaches" the specified AW. Note - this is really a restore the attach
-- mode of the AW to its previous state. So, if the AW was previously attached R/W - then
-- the AW will remain attached.
-- This previous state was returned by the attachAW function
PROCEDURE detachAW (
strOwner varchar2,
strAWName varchar2,
awState number
) as
owner varchar2(30);
awname varchar2(30);
BEGIN
owner := upper(strOwner);
awname := upper(strAWName);
if awState = ATTACHED_RW
then return;
elsif awState = NOT_ATTACHED
then dbms_aw.AW_DETACH(owner, awname);
else
dbms_aw.AW_DETACH(owner, awname);
dbms_aw.aw_attach(owner, awname, false);
end if;
return;
exception
when others then
-- shouldn't hit this condition
show ('**');
show ('** ERROR: Unable to restore attach state to AW ' || owner || '.' || awname || '.');
show ('**');
raise;
END detachAW;
FUNCTION getLastUpdateDate (
strOwner varchar2,
strAWName varchar2) return date as
owner varchar2(30);
awname varchar2(30);
awlongname varchar2(100);
last_updated varchar2(100);
isAttached number;
BEGIN
awlongname := upper(strOwner || '.' || strAWname);
owner := upper(strOwner);
awname := upper(strAWName);
isAttached := attachAW(owner, awname);
last_updated := dbms_aw.interp('show to_char(aw(date, ''' || awlongname || '''), ''YYYY-MON-DD,HH:MI:SS AM'')');
detachAW(owner, awname, isAttached);
return to_date(last_updated, 'YYYY-MON-DD,HH:MI:SS AM');
exception
when others then
show ('**');
show ('** ERROR: Unable to retrieve last updated date for AW ' || awname || '.');
show ('** Ensure that you have priviliges to access the AW.');
show ('**');
raise;
return null;
END getLastUpdateDate;
FUNCTION getDepthVar (
strOwner varchar2,
strAWName varchar2,
strDimname varchar2,
strHierDim varchar2,
strParentRel varchar2) return varchar2 as
owner varchar2(30);
awname varchar2(30);
awlongname varchar2(100);
isAttached number;
varName varchar2(100);
shortName varchar2(100);
varExists number;
cmd varchar2(1000);
BEGIN
awlongname := upper(strOwner || '.' || strAWname);
awname := upper(strAWname);
owner := upper(strOwner);
shortName := strDimname || '_DEPTHVAR';
varName := awlongname || '!' || shortName;
isAttached := attachAW(owner, awname);
-- Check if the depth variable exists
cmd := 'convert(exists(''' || varName || '''), int)';
varExists := dbms_aw.eval_number(cmd);
-- Define variable if it does not exist
-- DEFINE [dim]_DEPTHVAR VARIABLE INTEGER <[dim] [hierdim]>
-- PROPERTY '$NATRIGGER' 'statlen(limit(limit(organization to organization + 0 ) to ancestors using organization_parentrel))+1'
-- PROPERTY '$VARCACHE' 'VARIABLE'
if varExists = 0 then
show ('..... creating ' || shortname || ' object to support value hierarchies');
cmd := 'define ' || varName || ' variable integer <' || strDimname || ' ' || strHierDim || '>';
dbms_aw.execute(cmd);
cmd := 'PROPERTY ''$NATRIGGER'' ''statlen(limit(limit(' ||
strDimname || ' to ' || strDimname || ' + 0 ) to ancestors using ' || strParentRel || '))+1''';
dbms_aw.execute(cmd);
cmd := 'PROPERTY ''$VARCACHE'' ''VARIABLE''';
dbms_aw.execute(cmd);
show ('..... populating depth information in variable ' || shortName);
cmd := 'limit ' || strDimname || ' to ' || varName || ' eq 1';
dbms_aw.execute(cmd);
dbms_aw.AW_UPDATE(strOwner, strAWName);
end if;
detachAW(owner, awname, isAttached);
return shortName;
exception
when others then
show ('**');
show ('** ERROR: Unable to set up depth object for value based hierarchy in dimension ' || strDimname || '.');
show ('**');
show (sqlerrm);
raise;
return null;
END getDepthVar;
-- Return the generated column name for an AW object.
FUNCTION getColumnName (
parent varchar2,
awObj varchar2,
objType varchar2) return varchar2 as
displayName varchar2(100);
retval varchar2(100);
i number;
j number;
BEGIN
case
when objType = 'MEMBER_PARENTREL' then
retval := substr(parent, 1, 10) || '_' || substr(awObj, 1, 12) || '_PRNT';
when objType = 'LEVEL_LONG_DESCRIPTION' then
-- retval := substr(awObj, 1, 20) || '_LDSC';
retval := substr(parent, 1, 10) || '_' || substr(awObj, 1, 10) || '_LDSC';
when objType = 'MEMBER_LONG_DESCRIPTION' then
retval := substr(parent, 1, 10) || '_LDSC';
when objType = 'MEMBER_SHORT_DESCRIPTION' then
retval := substr(parent, 1, 10) || '_SDSC';
when objType = 'END_DATE' then
retval := substr(parent, 1, 10) || '_END_DATE';
when objType = 'TIME_SPAN' then
retval := substr(parent, 1, 10) || '_TIME_SPAN';
when objType = 'MEMBER_LEVELREL' then
retval := substr(parent, 1, 10) || '_' || substr(awObj, 1, 10) || '_LVL';
when objType = 'MEMBER_LEVELREL_DESC' then
retval := substr(parent, 1, 10) || '_' || substr(awObj, 1, 10) || '_LVLDSC';
when objType = 'LEVEL_ATTRIBUTE' then
retval := substr(parent, 1, 10) || '_LEVEL';
when objType = 'USER' then
retval := substr(parent, 1, 10) || '_' || substr(awObj, 1, 19);
else
retval := awObj;
end case;
return retval;
END getColumnName;
-- Generate a limitmap for a dimension based on the information in the cache
FUNCTION getDimensionLimitmap (
strOwner varchar2,
strAWname varchar2,
strDimname varchar2) return clob as
owner varchar2(30);
awname varchar2(30);
dimname varchar2(30);
limitmap clob;
ov_rec olap_mappings%ROWTYPE;
type hier_table is table of olap_mappings.hierarchy%TYPE INDEX BY BINARY_INTEGER;
hierlist hier_table;
target varchar2(2500);
aw_source varchar2(2500);
label_var varchar2(100);
run_date date;
no_values boolean;
yesno number;
aw_date date;
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
dimname := upper(strDimname);
no_values := false;
show('... generating limitmap for ' || dimname);
-- Update the olap_mappings table if nec.
begin
aw_date := getLastUpdateDate(owner, awname);
SELECT aw_last_updated
INTO run_date
FROM olap_mappings
WHERE aw_name = awname and
aw_owner = owner and
object_name = dimname and
rownum = 1;
exception
when NO_DATA_FOUND then
no_values := true;
end;
-- Check if the dimension mapping table needs to be updated.
-- This occurs if this current run is newer than the AW timestamp (i.e. an update
-- has occurred in the AW)
if no_values or run_date < aw_date
then
show ('..... mapping table out of date for dimension ' || dimname || '. Updating mapping table.');
yesno := generateDimensionMap(owner, awname, dimname);
if yesno = 0
then return null;
end if;
end if;
-- DIMENSION clause
-- e.g. DIMENSION category_id AS varchar2(100) FROM category WITH
SELECT *
INTO ov_rec
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
CLAUSE = 'DIMENSION';
limitmap := 'DIMENSION ' || ov_rec.column_name || -- ' AS ' || ov_rec.data_type ||
' FROM ' || dimname || ' WITH ';
-- Process each dimension hierarchy.
-- Begin by retrieving the list of hierarchies for the dimension
SELECT hierarchy
BULK COLLECT
INTO hierlist
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
CLAUSE = 'HIERARCHY' and
include = 1;
for i in 1 .. hierlist.count loop
-- HIERARCHY clause
-- e.g. HIERARCHY category_primary_parent AS varchar2(100) FROM category_parentrel(category_hierlist 'PRIMARY')
SELECT *
INTO ov_rec
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
hierarchy = hierlist(i) and
CLAUSE = 'HIERARCHY' and
include = 1;
limitmap := limitmap || '-' || chr(10) || ' HIERARCHY ' || ov_rec.column_name ||
-- || ' AS ' || ov_rec.data_type ||
' FROM ' || ov_rec.aw_object;
-- INHIERARCHY clause
-- e.g. INHIERARCHY category_inhier
SELECT *
INTO ov_rec
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
clause = 'INHIERARCHY' and
include = 1;
limitmap := limitmap || ' -' || chr(10) || ' INHIERARCHY ' || ov_rec.aw_object;
-- HATTRIBUTE clause (hierarchical attributes)
-- e.g HATTRIBUTE time_end_date FROM aw_time_end_date
DECLARE CURSOR hattr_cur is
SELECT *
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
clause = 'HATTRIBUTE' and
include = 1;
BEGIN
for ov_rec in hattr_cur loop
limitmap := limitmap || ' -' || chr(10) || ' HATTRIBUTE ' || ov_rec.column_name ||
' FROM ' || ov_rec.aw_object;
end loop;
end;
-- FAMILYREL clause
-- e.g. FAMILYREL total_category_id AS varchar2(10),
-- category_id AS varchar2(10),
-- item_id AS varchar2(10)
-- FROM category_familyrelval (category_levellist 'TOTAL_CATEGORY'),
-- category_familyrelval (category_levellist 'CATEGORY'),
-- category_familyrelval (category_levellist 'ITEM')
-- show('..... FAMILYREL clause');
DECLARE CURSOR familyrel_cur is
SELECT *
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
hierarchy = hierlist(i) and
clause = 'FAMILYREL' and
include = 1
ORDER BY position;
BEGIN
target := null;
aw_source := null;
for ov_rec in familyrel_cur loop
if target is null
then
target := ' -' || chr(10) || ' FAMILYREL ' || ov_rec.column_name; -- || ' AS ' || ov_rec.data_type;
aw_source := ' -' || chr(10) || ' FROM ' || ov_rec.aw_object;
else
target := target || ', -' || chr(10) || ' ' || ov_rec.column_name; -- || ' AS ' || ov_rec.data_type;
aw_source := aw_source || ', -' || chr(10) || ' ' || ov_rec.aw_object;
end if;
end loop;
end;
limitmap := limitmap || target || aw_source;
-- FAMILYREL LABEL clause
-- e.g. FAMILYREL total_category_id AS varchar2(10),
-- category_id AS varchar2(10),
-- item_id AS varchar2(10)
-- FROM category_familyrelval (category_levellist 'TOTAL_CATEGORY'),
-- category_familyrelval (category_levellist 'CATEGORY'),
-- category_familyrelval (category_levellist 'ITEM')
DECLARE CURSOR familyrel_cur is
SELECT *
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
hierarchy = hierlist(i) and
clause = 'FAMILYREL_LONG_DESC' and
include = 1
ORDER BY position;
BEGIN
target := null;
aw_source := null;
for ov_rec in familyrel_cur loop
if target is null
then
target := ' -' || chr(10) || ' FAMILYREL ' || ov_rec.column_name; -- || ' AS ' || ov_rec.data_type;
aw_source := ' -' || chr(10) || ' FROM ' || ov_rec.aw_object;
else
target := target || ', -' || chr(10) || ' ' || ov_rec.column_name; -- || ' AS ' || ov_rec.data_type;
aw_source := aw_source || ', -' || chr(10) || ' ' || ov_rec.aw_object;
end if;
label_var := ov_rec.dimension_desc;
end loop;
end;
if aw_source is not null
then aw_source := aw_source || ' -' || chr(10) || ' LABEL ' || label_var;
end if;
limitmap := limitmap || target || aw_source;
end loop; -- Hierarchy loop
-- ATTRIBUTE clause
-- e.g ATTRIBUTE category_long_description AS varchar2(100) FROM category_long_description
DECLARE CURSOR attr_cur is
SELECT *
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname and
clause = 'ATTRIBUTE' and
include = 1;
BEGIN
for ov_rec in attr_cur loop
limitmap := limitmap || ' -' || chr(10) || ' ATTRIBUTE ' || ov_rec.column_name ||
-- ' AS ' || ov_rec.data_type ||
' FROM ' || ov_rec.aw_object;
end loop;
end;
return limitmap;
show ('.. completed genrating limitmap for dimension ' || dimname);
END getDimensionLimitmap;
-- Returns the limitmap for a cube
FUNCTION getCubeLimitmap (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2) return clob as
type dim_table is table of all_olap2_aw_cube_dim_uses.dimension_aw_name%TYPE INDEX BY BINARY_INTEGER;
dimlist dim_table;
limitmap clob;
owner varchar2(30);
awname varchar2(30);
cubename varchar2(30);
meas_rec olap_mappings%ROWTYPE;
meas_clause varchar2(1000);
run_date date;
no_values boolean;
yesno number;
dimmap clob;
aw_date date;
BEGIN
show('... generating limitmap for cube ' || cubename);
owner := upper(strOwner);
awname := upper(strAWname);
cubename := upper(strCubename);
-- Update the metadata cache if nec.
begin
-- Get the timestamp for when the AW was last updated
aw_date := getLastUpdateDate(owner, awname);
SELECT aw_last_updated
INTO run_date
FROM olap_mappings
WHERE aw_name = awname and
aw_owner = owner and
cube_name = cubename and
rownum = 1;
exception
when NO_DATA_FOUND then
no_values := true;
end;
-- Check if the cube cache needs to be updated.
-- This occurs if the AW has been updated since the view was created
if no_values or run_date < aw_date
then
show ('..... mapping table out of date for cube ' || cubename || '. Updating mapping table.');
yesno := generateCubeMap(owner, awname, cubename);
if yesno = 0
then return null;
end if;
end if;
-- Get the limitmap for each of the cube's dimensions
show('..... retrieving dimensions for the cube. Need limitmap for each dimension.');
SELECT dimension_aw_name
BULK COLLECT
INTO dimlist
FROM all_olap2_aw_cube_dim_uses
WHERE aw_owner = owner and
aw_name = awname and
aw_logical_name = cubename;
for i in 1 .. dimlist.count loop
dimmap := getDimensionLimitmap(owner, awname, dimlist(i));
if dimmap is null
then return null;
end if;
if limitmap is null
then limitmap := dimmap;
else limitmap := limitmap || '-' || chr(10) || dimmap;
end if;
end loop;
-- Get the limitmap for the measures in the cube
-- e.g. MEASURE amount AS number FROM expense_amount
-- show ('..... MEASURE clause');
DECLARE CURSOR meas_cur is
SELECT *
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
cube_name = cubename and
include = 1;
BEGIN
for meas_rec in meas_cur
loop
meas_clause := ' MEASURE ' || meas_rec.column_name;
-- Add data type if necessary (for numeric columns)
if meas_rec.data_type is not null then
meas_clause := meas_clause || ' AS ' || meas_rec.data_type;
end if;
meas_clause := meas_clause || ' FROM ' || meas_rec.aw_object;
limitmap := limitmap || '-' || chr(10) || meas_clause;
end loop;
END;
-- Add the ROW2CELL calc. This enables arbitrary OLAP DML calcs dynamically thru sql
limitmap := limitmap || '-' || chr(10) || ' ROW2CELL olap_calc';
show ('... completed generating limitmap for cube ' || cubename);
return limitmap;
END getCubeLimitmap;
-- Returns the SQL Model Clause or Comments for a Dimension or Cube View
FUNCTION getSQLText (
strOwner varchar2,
strAWName varchar2,
strObjType varchar2, -- CUBE or DIMENSION
strObject varchar2, -- Name of cube or dimension
strType varchar2, -- MODEL or COMMENT
strViewName varchar2
) return varchar2 as
clause varchar2(10000);
comments varchar2(32000);
type om_table_type is table of olap_mappings%ROWTYPE;
dimlist om_table_type;
measlist om_table_type;
owner varchar2(30);
awname varchar2(30);
objtype varchar2(30);
obj varchar2(30);
comma varchar2(2);
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
objtype := upper(strObjType);
obj := upper(strObject);
-- Need to generate a model clause that looks like the following:
/* MODEL
DIMENSION BY(
channel_id
MEASURES(
channel_primary_parent,
channel_total_channel_id,
channel_total_channel_desc,
channel_channel_id,
channel_channel_desc,
channel_level,
channel_long_description,
channel_short_description
RULES UPDATE SEQUENTIAL ORDER(); */
clause := 'MODEL ' || chr(10) || ' DIMENSION BY (';
-- Collect dimension list
if objtype = 'DIMENSION' then
-- Retrieve the dimension's column
SELECT *
INTO dimlist(1)
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = obj and
clause = 'DIMENSION';
else
-- Retrieve the columns for each of the dimensions for this cube
SELECT *
BULK COLLECT
INTO dimlist
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
clause = 'DIMENSION' and
object_name in (
SELECT dimension_aw_name
FROM all_olap2_aw_cube_dim_uses
WHERE aw_owner = owner and
aw_name = awname and
aw_logical_name = obj);
end if;
-- Populate the clause with the dimension id column
-- Populate the comments if there are any... (e.g. COMMENT ON COLUMN OLAP_VIEWS.OLAP_MAPPINGS.LAST_UPDATED IS 'Timestamp when the view was created'; )
comments := '';
for i in 1 .. dimlist.count loop
if dimlist(i).description is not null
then comments := comments || chr(10) || 'COMMENT ON COLUMN ' || strViewName || '.' || dimlist(i).column_name
|| ' IS ''' || dimlist(i).description || ''';';
end if;
if i = 1 then
clause := clause || chr(10) || ' ' || dimlist(i).column_name;
else
clause := clause || ',' || chr(10) || ' ' || dimlist(i).column_name;
end if;
end loop;
-- Close DIMENSION BY clause and add MEASURES clause
clause := clause || ')' || chr(10) || ' MEASURES (';
-- Begin by adding all the dimension attributes
-- This is required for both dimensions and cubes
comma := null;
for i in 1 .. dimlist.count loop
SELECT *
BULK COLLECT
INTO measlist
FROM olap_mappings
WHERE clause in ('HIERARCHY', 'FAMILYREL', 'FAMILYREL_LONG_DESC', 'ATTRIBUTE', 'HATTRIBUTE' ) and
aw_name = awname and
aw_owner = owner and
include = 1 and
object_name in (SELECT object_name
FROM olap_mappings
WHERE column_name = dimlist(i).column_name);
for j in 1 .. measlist.count loop
clause := clause || comma || chr(10) || ' ' || measlist(j).column_name;
comma := ',';
end loop;
end loop;
-- If this is a cube, then get all the measures as well
measlist.delete;
if objtype = 'CUBE'
then
SELECT *
BULK COLLECT
INTO measlist
FROM olap_mappings
WHERE cube_name = obj and
aw_name = awname and
aw_owner = owner and
include = 1;
for i in 1 .. measlist.count loop
clause := clause || ',' || chr(10) || ' ' || measlist(i).column_name;
end loop;
-- Add the olap_calc column
clause := clause || ',' || chr(10) || ' ' || 'OLAP_CALC';
end if;
clause := clause || chr(10) || ' ) RULES UPDATE SEQUENTIAL ORDER()';
if strType = 'MODEL'
then return clause;
else return comments;
end if;
return null;
END getSQLText;
-- Returns the SQL Model Clause for a Dimension or Cube View
FUNCTION getModelClause (
strOwner varchar2,
strAWName varchar2,
strObjType varchar2, -- CUBE or DIMENSION
strObject varchar2 -- Name of cube or dimension
) return varchar2 as
clause varchar2(10000);
type col_table is table of olap_mappings.column_name%TYPE INDEX BY BINARY_INTEGER;
dimlist col_table;
measlist col_table;
owner varchar2(30);
awname varchar2(30);
objtype varchar2(30);
obj varchar2(30);
comma varchar2(2);
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
objtype := upper(strObjType);
obj := upper(strObject);
-- Need to generate a model clause that looks like the following:
/* MODEL
DIMENSION BY(
channel_id
MEASURES(
channel_primary_parent,
channel_total_channel_id,
channel_total_channel_desc,
channel_channel_id,
channel_channel_desc,
channel_level,
channel_long_description,
channel_short_description
RULES UPDATE SEQUENTIAL ORDER(); */
clause := 'MODEL ' || chr(10) || ' DIMENSION BY (';
-- Collect dimension list
if objtype = 'DIMENSION' then
-- Retrieve the dimension's column
SELECT column_name
INTO dimlist(1)
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = obj and
clause = 'DIMENSION';
else
-- Retrieve the columns for each of the dimensions for this cube
SELECT column_name
BULK COLLECT
INTO dimlist
FROM olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
clause = 'DIMENSION' and
object_name in (
SELECT dimension_aw_name
FROM all_olap2_aw_cube_dim_uses
WHERE aw_owner = owner and
aw_name = awname and
aw_logical_name = obj);
end if;
-- Populate the clause with the dimension id column
for i in 1 .. dimlist.count loop
if i = 1 then
clause := clause || chr(10) || ' ' || dimlist(i);
else
clause := clause || ',' || chr(10) || ' ' || dimlist(i);
end if;
end loop;
-- Close DIMENSION BY clause and add MEASURES clause
clause := clause || ')' || chr(10) || ' MEASURES (';
-- Begin by adding all the dimension attributes
-- This is required for both dimensions and cubes
comma := null;
for i in 1 .. dimlist.count loop
SELECT column_name
BULK COLLECT
INTO measlist
FROM olap_mappings
WHERE clause in ('HIERARCHY', 'FAMILYREL', 'FAMILYREL_LONG_DESC', 'ATTRIBUTE', 'HATTRIBUTE' ) and
aw_name = awname and
aw_owner = owner and
include = 1 and
object_name in (SELECT object_name
FROM olap_mappings
WHERE column_name = dimlist(i));
for j in 1 .. measlist.count loop
clause := clause || comma || chr(10) || ' ' || measlist(j);
comma := ',';
end loop;
end loop;
-- If this is a cube, then get all the measures as well
measlist.delete;
if objtype = 'CUBE'
then
SELECT column_name
BULK COLLECT
INTO measlist
FROM olap_mappings
WHERE cube_name = obj and
aw_name = awname and
aw_owner = owner and
include = 1;
for i in 1 .. measlist.count loop
clause := clause || ',' || chr(10) || ' ' || measlist(i);
end loop;
-- Add the olap_calc column
clause := clause || ',' || chr(10) || ' ' || 'OLAP_CALC';
end if;
clause := clause || chr(10) || ' ) RULES UPDATE SEQUENTIAL ORDER()';
return clause;
END getModelClause;
-- PUBLIC FUNCTIONS and PROCEDURES
-- Populates the olap_mappings table with the structure of the limitmap
FUNCTION generateDimensionMap (
strOwner varchar2,
strAWname varchar2,
strDimname varchar2) RETURN number as
owner olap_views.OLAP_MAPPINGS.AW_OWNER%TYPE;
awname olap_views.OLAP_MAPPINGS.AW_NAME%TYPE;
dimname olap_views.OLAP_MAPPINGS.OBJECT_NAME%TYPE;
qdr varchar2(100);
success boolean;
columnName olap_views.OLAP_MAPPINGS.COLUMN_NAME%TYPE;
displayName varchar2(100); -- Name displayed to users in end user tools
dimDisplayName varchar2(100); -- For a dimension, name displayed to users in end user tools
parent_obj varchar2(100); -- AW object that contains parent-child relation
hierlist_obj varchar2(100); -- AW object containing list of hierarchies
inhier_obj varchar2(100); -- AW object specifying members in a hierarchy
familyrel_obj varchar2(100); -- AW object specifying family relationship for level-based hiers
familyrelval_obj varchar2(100); -- AW object specifying family relationship for value-based hiers
levelrel_obj varchar2(100); -- AW object specifying the level for a dimension member
levelList_obj varchar2(100);
gidDimension_obj varchar2(100);
long_desc_obj varchar2(100);
depth_obj varchar2(100);
currentvalue varchar2(100);
hier_levels all_olap2_aw_dim_hier_lvl_ord%ROWTYPE;
attrib_record all_olap2_aw_attributes%ROWTYPE;
str varchar2(100);
TYPE awinfo_table IS TABLE OF all_olap2_aw_phys_obj_prop.aw_prop_value%TYPE
INDEX BY varchar2(100);
level_list awinfo_table;
physobj_list awinfo_table;
TYPE awinfo_type is RECORD (
prop_value all_olap2_aw_phys_obj_prop.aw_prop_value%TYPE,
prop_name all_olap2_aw_phys_obj_prop.AW_PROP_NAME%TYPE);
propValue_record awinfo_type;
isValueBased boolean;
aw_date date;
type olapCur is ref cursor;
physObjCur olapCur;
isAttached number;
maxdepth number;
i number;
gid_value number;
description varchar2(1000);
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
dimname := upper(strDimname);
show ('... populating dimension map for ' || dimname);
-- Ensure the AW is attached R/W first
isAttached := attachAW (owner, awname);
-- Get the timestamp for the last time the AW was updated
aw_date := getLastUpdateDate(owner, awname);
* Begin by caching key metadata objects and physical objects that will be required
* for the dimension table cache.
show ('..... clearing mappings for the dimension');
DELETE olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
object_name = dimname;
* Retrieve physical AW objects that represent the hierarchies, levels, descriptions, etc.
* Will retrieve information directly from the AW dictionary
show ('..... retrieving physical objects');
-- Begin by defining a shadow dimension for the NAME dimension and a formula highlighting the object type.
-- Populate this shadow dimension with the appropriate AW objects for this dimension
-- Note: it's okay if the name_id dimension already exists - the define will simply
-- cause a benign error. name_id is a temporary structure that does not need to be persisted
begin
dbms_aw.execute('oknullstatus = yes');
dbms_aw.execute('define name_id dimension text temp session');
-- list of AW objects
dbms_aw.execute('define EXPRESS!name_obj_type formula text <name_id> session');
dbms_aw.execute('eq if obj(property ''AW$ROLE'', name_id) eq ''ATTRDEF'' then obj(property ''AW$TYPE'', name_id) else obj(property ''AW$ROLE'', name_id)');
-- list of physical level names
dbms_aw.execute('define EXPRESS!level_physicalname formula text <name_id> session');
dbms_aw.execute('eq obj(property ''PHYSICALNAME'', name_id)');
-- list of level display names
dbms_aw.execute('define EXPRESS!level_displayname formula text <name_id> session');
dbms_aw.execute('eq obj(property ''DISPLAYNAME'', name_id)');
-- list of value hierarchy names
dbms_aw.execute('define valuehiers dimension text temp session');
dbms_aw.execute('define EXPRESS!hier_logicalname formula text <valuehiers> session');
dbms_aw.execute('eq obj(property ''AW$LOGICAL_NAME'', valuehiers)');
-- maximum depth of a value hierarchy
dbms_aw.execute('define EXPRESS!hier_maxdepth formula int <valuehiers> session');
dbms_aw.execute('eq numlines(obj(property ''HIERARCHY_LEVELS'', valuehiers))');
-- Check for exceptions..... occurs if the object supporting objects already exist.
exception
when others then
null;
end;
-- Clear the cached list of names
dbms_aw.execute('mnt name_id delete all');
-- Populate the shadow dimension with all the dimension related objects
dbms_aw.execute('mnt name_id merge limit(name to obj(property ''AW$PARENT_NAME'') eq ''' ||
dimname || ''' or obj(property ''AW$ROLE'') eq ''GID_DIMENSION'')');
-- Retrieve the objects and their properties
open physObjCur for 'SELECT prop_value, prop_name
FROM table(OLAP_TABLE(''EXPRESS duration session'', null, null,
''DIMENSION prop_name FROM name_id
MEASURE prop_value FROM name_obj_type''))';
BEGIN
loop
fetch physObjCur into propValue_record;
exit when physObjCur%NOTFOUND;
physobj_list(propValue_record.prop_value) := propValue_record.prop_name;
end loop;
close physObjCur;
END;
parent_obj := physobj_list('MEMBER_PARENTREL');
hierlist_obj := physobj_list('HIERLIST');
inhier_obj := physobj_list('MEMBER_INHIER');
familyrel_obj := physobj_list('MEMBER_FAMILYREL');
familyrelval_obj := physobj_list('MEMBER_FAMILYRELVAL');
levelList_obj := physobj_list('LEVELLIST');
levelrel_obj := physobj_list('MEMBER_LEVELREL');
gidDimension_obj := physobj_list('GID_DIMENSION');
long_desc_obj := physobj_list('MEMBER_LONG_DESCRIPTION');
-- Populate the value hierarchy collection
-- Use a similar technique to the one above to find the hierarchies
show ('..... checking for value hierarchies');
dbms_aw.execute('mnt valuehiers delete all');
-- Populate the valuehiers dimension with all the value hierarchies for this dimension
dbms_aw.execute('mnt valuehiers merge limit(name to obj(property ''AW$PARENT_NAME'') eq ''' ||
dimname || ''' and obj(property ''AW$ROLE'') eq ''HIERDEF'' and obj(property ''VALUE_HIERARCHY'') eq True)');
-- Populate the LEVEL labels collection
-- Again, use techniques similar to the one above ** CHECK VALUE HIERARCHIES **
show ('..... retrieving label for dimension levels');
-- Populate the shadow dimension with all the dimension related objects
dbms_aw.execute('mnt name_id delete all');
dbms_aw.execute('mnt name_id merge limit(name to obj(property ''AW$PARENT_NAME'') eq ''' ||
dimname || ''' and obj(property ''AW$ROLE'') eq ''LEVELDEF'')');
-- Retrieve the objects and their properties
open physObjCur for 'SELECT display_name prop_value, physical_name prop_name
FROM table(OLAP_TABLE(''EXPRESS duration session'', null, null,
''DIMENSION level_name FROM name_id
MEASURE physical_name FROM level_physicalname
MEASURE display_name FROM level_displayname''))';
BEGIN
loop
fetch physObjCur into propValue_record;
exit when physObjCur%NOTFOUND;
level_list(propValue_record.prop_name) := propValue_record.prop_value;
end loop;
close physObjCur;
END;
-- Update the cache with DIMENSION clause
-- Example:
-- DIMENSION category_id AS varchar2(100) FROM category WITH
show ('..... populating mapping info for the DIMENSION clause');
dimDisplayName := dbms_aw.eval_text('obj(property ''DISPLAYNAME'' ''' || dimname || ''')') || ' member';
-- DIMENSION clause
description := dimname || ' dimension member values';
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'DIMENSION',
dimname, dimname, dimname,
dimDisplayName, description);
-- Update the cache with INHIER clause
-- Example:
-- INHIERARCHY category_inhier
-- INHIERARCHY clause
show ('..... populating mapping info for the INHIERARCHY clause');
description := 'Identifies dimension members that are in a given hierarchy';
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'INHIERARCHY',
dimname, null, inhier_obj,
null, description);
-- Loop over the HIERARCHIES for this dimension
-- Update the cache with HIERARCHY and FAMILYREL clauses
-- Example:
-- HIERARCHY category_standard_prnt AS varchar2(100) FROM category_parentrel(category_hierlist \'STANDARD\')
currentvalue := ' ';
show ('..... retrieving hierarchy information');
DECLARE
CURSOR hier_levels_cur is
SELECT *
FROM all_olap2_aw_dim_hier_lvl_ord
WHERE aw_owner = owner and
aw_name = awname and
aw_dimension_name = dimname and
length(aw_hierarchy_name) > 0
ORDER BY aw_hierarchy_name asc, position asc;
BEGIN
for hier_levels in hier_levels_cur
loop
str := hier_levels.aw_hierarchy_name;
-- If there is a change in hierarchy, then add the HIERARCHY clause
if str != currentvalue
then
show ('..... populating mapping info for the HIERARCHY and FAMILYREL clauses for hierarchy ' || str);
currentvalue := hier_levels.aw_hierarchy_name;
columnName := getColumnName (dimname, currentvalue, 'MEMBER_PARENTREL');
qdr := parent_obj || '(' || hierlist_obj || ' \''' || currentvalue || '\'')';
description := dimname || ' member''s parent in hierarchy ' || currentvalue;
displayName := dimDisplayName || ' Parent';
-- HIERARCHY clause
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, hierarchy, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'HIERARCHY',
dimname, currentvalue, columnName, qdr,
displayName, description);
-- Check if current hierarchy is value based
dbms_aw.execute('limit valuehiers to hier_logicalname eq ''' || currentvalue || '''');
if dbms_aw.eval_number('statlen(valuehiers)') = 0
then isValueBased := false;
else isValueBased := true;
end if;
-- Get the maximum depth of a value hierarchy
-- Also, set up the depth variable for a value-based hierarchy
if isValueBased then
maxdepth := dbms_aw.eval_number('hier_maxdepth');
i := maxdepth;
-- The depth object represents a level in a value based hierarchy
-- This object is not in standard form and will be created if nec by
-- getDepthVar
if depth_obj is null then
depth_obj := getDepthVar(owner, awname, dimname, hierlist_obj, parent_obj);
end if;
-- Add a LEVEL hierarchy attribute
-- There must be a level (or depth) attribute by hierarchy, since the level may change by hierarchy
columnName := substr(dimname, 1, 10) || '_' || substr(currentvalue, 1, 10) || '_LEVEL';
description := 'Depth of ' || dimname || ' member in hierarchy ' || currentvalue;
displayName := dimDisplayName || ' level';
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'HATTRIBUTE',
dimname, columnName, depth_obj,
displayName, description);
end if;
end if;
-- Add the FAMILYREL clause for this level
if isValueBased
then
i := i - 1;
gid_value := power(2, i) - 1;
-- columnName := getColumnName(dimname, hier_levels.aw_level_name, 'MEMBER_LEVELREL');
qdr := familyrelval_obj || '(' || gidDimension_obj || ' ' || gid_value || ')';
displayName := currentvalue || ' Level ' || hier_levels.position;
str := substr(currentvalue, 1, 8) || hier_levels.position;
columnName := getColumnName(dimname, str, 'MEMBER_LEVELREL');
description := dimname || ' member''s ancestor value for level ' || hier_levels.position || ' in hierarchy ' || currentvalue;
-- FAMILYREL clause
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, hierarchy, level_name, column_name, aw_object,
position, column_label, description, include)
VALUES (cachedate, aw_date, owner, awname, 'FAMILYREL',
dimname, currentvalue, str, columnName, qdr,
hier_levels.position, displayName || ' ID', description, include_level_id);
-- FAMILYREL description clause
description := dimname || ' member''s ancestor descriptive value for level ' || hier_levels.position || ' in hierarchy ' || currentvalue;
columnName := getColumnName(dimname, str, 'MEMBER_LEVELREL_DESC');
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, hierarchy, level_name, column_name, aw_object,
dimension_desc, position, column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'FAMILYREL_LONG_DESC',
dimname, currentvalue, str, columnName, qdr,
long_desc_obj, hier_levels.position, displayName || ' Description', description);
else
-- Level based hierarchies use the level list object
-- They also use the FAMILYREL as the hierarchy structure
-- columnName := getColumnName(dimname, hier_levels.aw_level_name, 'MEMBER_LEVELREL');
columnName := getColumnName(dimname, hier_levels.aw_level_name, 'MEMBER_LEVELREL');
qdr := familyrel_obj || '(' || levelList_obj || ' \''' ||
hier_levels.aw_level_name || '\'')';
displayName := level_list(hier_levels.aw_level_name);
description := dimname || ' member''s ancestor value for level ' || hier_levels.aw_level_name || ' in hierarchy ' || currentvalue;
-- FAMILYREL clause
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, hierarchy, level_name, column_name, aw_object,
position, column_label, description, include)
VALUES (cachedate, aw_date, owner, awname, 'FAMILYREL',
dimname, currentvalue, hier_levels.aw_level_name, columnName, qdr,
hier_levels.position, displayName || ' ID', description, INCLUDE_LEVEL_ID);
-- FAMILYREL description clause
-- columnName := getColumnName(dimname, hier_levels.aw_level_name, 'LEVEL_LONG_DESCRIPTION');
columnName := getColumnName(dimname, hier_levels.aw_level_name, 'MEMBER_LEVELREL_DESC');
description := dimname || ' member''s ancestor descriptive value for level ' || hier_levels.aw_level_name || ' in hierarchy ' || currentvalue;
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, hierarchy, level_name, column_name, aw_object,
dimension_desc, position, column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'FAMILYREL_LONG_DESC',
dimname, currentvalue, hier_levels.aw_level_name, columnName, qdr,
long_desc_obj, hier_levels.position, displayName || ' Description', description);
end if;
END LOOP; -- Loop over hierarchy levels
END; -- Cursor for hierarchy levels
-- Add ATTRIBUTES for the dimension
show ('..... populating mapping info for the ATTRIBUTE clause');
DECLARE
CURSOR attributes_cur is
SELECT *
FROM all_olap2_aw_attributes
WHERE aw_owner = owner and
aw_name = awname and
aw_dimension_name = dimname;
BEGIN
for attrib_record in attributes_cur
loop
columnName := getColumnName(attrib_record.aw_dimension_name,
attrib_record.aw_logical_name,
attrib_record.attribute_type);
description := attrib_record.description;
displayName := attrib_record.display_name;
/* if attrib_record.attribute_type in ('MEMBER_SHORT_DESCRIPTION', 'MEMBER_LONG_DESCRIPTION')
then
description := attrib_record.description;
displayName := attrib_record.display_name;
else
description := attrib_record.aw_dimension_name || ' attribute ' || attrib_record.aw_physical_object;
displayName := attrib_record.display_name;
end if;
-- ATTRIBUTE clause
-- Throwing column name
show ('Attribute clause column name= ' || columnName);
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'ATTRIBUTE',
dimname, columnName, attrib_record.aw_physical_object,
displayName, description);
end loop;
END;
-- Add the LEVELREL object as an attribute of the dimension.
columnName := getColumnName(dimname, null, 'LEVEL_ATTRIBUTE');
description := dimDisplayName || ' level';
displayName := description;
-- Throwing column name
show ('Levelrel clause column name= ' || columnName);
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, clause,
object_name, column_name, aw_object,
column_label, description)
VALUES (cachedate, aw_date, owner, awname, 'ATTRIBUTE',
dimname, columnName, levelrel_obj,
displayName, description);
-- Finally, ensure that the columns are unique across the the AW.
-- For example, if month_lvl is in two hierarchies, there will need to be two
-- columns: 1) month_lvl and 2) month_lvl1. Or, if there is a product dimension
-- and a product measure, these will also be uniquely identified
UPDATE olap_mappings map
SET map.column_name =
(SELECT case when (b.cum_occurrence > 1) then b.column_name || (b.cum_occurrence - 1)
else b.column_name
end as column_name
FROM
(SELECT a.aw_owner,
a.aw_name,
a.cube_name,
a.column_name,
SUM(a.occurrence) over(PARTITION BY cube_name, column_name ORDER BY occurrence ROWS unbounded preceding) cum_occurrence
FROM
(SELECT aw_owner,
aw_name,
cube_name,
column_name,
1 occurrence
FROM olap_mappings
WHERE aw_name= awname and
aw_owner=owner) a
) b
WHERE map.rowid = b.rowid)
WHERE map.aw_name = awname and
map.aw_owner = owner;
commit;
show ('... completed populating mapping for ' || dimname);
detachAW(owner, awname, isAttached);
return 1;
exception
when NO_DATA_FOUND then
rollback;
show ('**');
show ('** Error retrieving metadata for dimension ' || dimname);
show ('** You do not have access to the data in the AW.');
show ('** View creation failed');
show ('**');
show (SQLERRM);
detachAW(owner, awname, isAttached);
return 0;
when others then
rollback;
show ('**');
show ('** Error retrieving metadata for dimension ' || dimname);
show ('** View creation failed');
show ('**');
show (SQLERRM);
detachAW(owner, awname, isAttached);
return 0;
END generateDimensionMap;
-- Updates the OLAP_MAPPINGS table with information about a cube
FUNCTION generateCubeMap (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2) return number as
owner varchar2(30);
awname varchar2(30);
cubename varchar2(30);
aw_date date;
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
cubename := upper(strCubename);
aw_date := getLastUpdateDate(owner, awname);
show ('... populating mapping for cube ' || cubename);
show ('..... clearing mappings for the cube');
DELETE olap_mappings
WHERE aw_owner = owner and
aw_name = awname and
cube_name = cubename;
-- Retrieve each of the measures
show ('..... collecting metadata for measures in cube');
INSERT INTO olap_mappings(last_updated, aw_last_updated, aw_owner, aw_name, cube_name, clause,
object_name, column_name, aw_object,
data_type,
column_label, description)
(SELECT cachedate, aw_date, aw_owner, aw_name, aw_cube_name, 'MEASURE',
aw_measure_name, aw_measure_name, aw_physical_object,
olap_views.olap_viewGenerator.getDataType(aw_owner, aw_name, aw_physical_object),
display_name, 'Measure ' || aw_measure_name
FROM all_olap2_aw_cube_measures);
commit;
return 1;
exception
when others then
rollback;
show ('**');
show ('** Error retrieving metadata for cube ' || cubename);
show ('** View creation failed');
show ('**');
show (SQLERRM);
return 0;
END generateCubeMap;
PROCEDURE createCubeView (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2,
commitLog boolean) as
owner varchar2(30);
awname varchar2(30);
cubename varchar2(30);
limitmap clob;
cmd varchar2(4000);
output varchar2(4000);
varname varchar2(100);
sql_text varchar2(32767);
viewname varchar2(61);
cube_rec all_olap2_aw_cubes%rowtype;
type dim_table is table of all_olap2_aw_cube_dim_uses.dimension_aw_name%TYPE INDEX BY BINARY_INTEGER;
dimlist dim_table;
isAttached number;
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
cubename := upper(strCubename);
varname := cubename || '_CUBE_LIMITMAP';
viewname := owner || '.' || substr(cubename, 1, 21) || '_CUBEVIEW';
show ('. Creating view for cube ' || cubename);
-- Validate the arguments
begin
SELECT *
INTO cube_rec
FROM all_olap2_aw_cubes
WHERE aw_name = awname and
aw_owner = owner and
aw_logical_name = cubename;
exception
when NO_DATA_FOUND then
show ('**');
show ('** ERROR: View not created.');
show ('** Invalid arguments. Ensure that the schema, AW and cube names are valid.');
show ('** In addition, ensure that you have r/w priviliges to the AW.');
show ('**');
if commitLog
then updateLogTable();
end if;
raise;
end;
-- Attach the AW
begin
isAttached := attachAW(owner, awname);
exception
when others then
show ('**');
show ('** ERROR: View not created.');
show ('** Unable to attach AW r/w. Ensure no other users have the AW attached RW - then try again.');
show ('** In addition, ensure that you have r/w priviliges to the AW.');
show ('**');
if commitLog
then updateLogTable();
end if;
raise;
end;
-- Define the limitmap variable in the AW and assign the limitmap text to it
show ('..... generating limitmap for cube');
limitmap := getCubeLimitmap(owner, awname, cubename);
if limitmap is null
then
if commitLog then
updateLogTable();
raise bad_limitmap;
end if;
end if;
-- Define the variable
show ('..... assigning limitmap to variable in the AW');
begin
dbms_aw.execute('define ' || varname || ' variable text');
-- If the variable already exists, simply update it
exception
when others then
show ('..... ' || varname || ' found. Will update the variable');
end;
-- Assign the limitmap. Update and commit changes
begin
output := dbms_aw.interpclob(varname || ' = ''' || limitmap || '''');
dbms_aw.aw_update(owner, awname);
commit;
detachAW(owner, awname, isAttached);
exception
when others then
show ('**');
show ('** ERROR: View not created.');
show ('** CAUSE: Unable to assign the limitmap variable in the AW.');
show (SQLERRM);
detachAW(owner, awname, isAttached);
-- if commitLog
-- then updateLogTable();
-- end if;
raise;
end;
-- Create the view over the AW
-- Example:
CREATE or REPLACE VIEW channel_dimview AS
SELECT *
FROM table(OLAP_TABLE('GLOBAL.GLOBAL duration session',
'&(CHANNEL_LIMITMAP)' ))
show ('..... defining view ' || viewname || ' over the cube');
sql_text := 'CREATE OR REPLACE VIEW ' || viewname || ' AS ' || chr(10) ||
' SELECT * ' || chr(10) ||
' FROM table(OLAP_TABLE (''' || owner || '.' || awname || ' duration session'',' || chr(10) ||
''''',' || chr(10) ||
''''',' || chr(10) ||
'''&(' || varname || ')''))';
-- Add SQL Model clause
sql_text := sql_text || chr(10) ||
getSQLText(owner, awname, 'CUBE', cubename, 'MODEL', null);
begin
execute immediate sql_text;
exception
when others then
show ('**');
show ('** ERROR: View not created.');
show ('** CAUSE: CREATE VIEW statement failed');
show (SQLERRM);
show ('*** DEBUG INFORMATION ***');
show ('VIEW CREATION DDL ((truncated after 3900 characters)');
show (substr(sql_text, 1, 3900));
show ('LIMITMAP (truncated after 3900 characters):');
show (substr(limitmap, 1, 3900));
raise;
end;
-- Update the catalog containing the views and their contents
begin
-- Update the limitmap catalog
DELETE olap_view_limitmap
WHERE aw_owner = owner and
aw_name = awname and
view_name = viewname;
INSERT INTO olap_view_limitmap(last_updated, aw_owner, aw_name,
view_name, limitmap)
VALUES (cachedate, owner, awname,
viewname, limitmap);
-- Update the object catalog with the cube
DELETE olap_view_objects
WHERE aw_owner = owner and
aw_name = awname and
view_name = viewname and
cube_name = cubename;
INSERT INTO olap_view_objects(last_updated, aw_owner, aw_name,
view_name, cube_name)
VALUES (cachedate, owner, awname,
viewname, cubename);
-- Update the object catalog with the dimensions for the cube
SELECT dimension_aw_name
BULK COLLECT
INTO dimlist
FROM all_olap2_aw_cube_dim_uses
WHERE aw_owner = owner and
aw_name = awname and
aw_logical_name = cubename;
for i in 1 .. dimlist.count loop
DELETE olap_view_objects
WHERE aw_owner = owner and
aw_name = awname and
view_name = viewname and
dimension_name = dimlist(i);
INSERT INTO olap_view_objects(last_updated, aw_owner, aw_name,
view_name, dimension_name)
VALUES (cachedate, owner, awname,
viewname, dimlist(i));
end loop;
commit;
exception
when others then
rollback;
show ('**');
show ('** ERROR: Unable to update the OLAP_VIEW_OBJECTS and/or OLAP_VIEW_LIMITMAP catalog tables.');
show (SQLERRM);
show ('** NOTE: View ' || viewname || ' was successfully created.');
if commitLog
then updateLogTable();
end if;
return;
end;
show ('View ' || viewname || ' successfully created');
if commitLog
then updateLogTable();
end if;
return;
exception
when others then
rollback;
show ('**');
show ('** ERROR: Unable to create view over cube ' || cubename || '.');
show (SQLERRM);
if commitLog
then updateLogTable();
end if;
raise;
END createCubeView;
PROCEDURE createCubeView (
strOwner varchar2,
strAWname varchar2,
strCubename varchar2) as
BEGIN
createCubeView(strOwner, strAWname, strCubename, true);
END createCubeView;
PROCEDURE createDimensionView (
strOwner varchar2,
strAWname varchar2,
strDimname varchar2,
commitLog boolean) as
owner varchar2(30);
awname varchar2(30);
dimname varchar2(30);
limitmap clob;
cmd varchar2(4000);
output varchar2(4000);
varname varchar2(100);
sql_create varchar2(32767);
viewname varchar2(61);
dim_rec all_olap2_aw_dimensions%ROWTYPE;
isAttached number;
BEGIN
owner := upper(strOwner);
awname := upper(strAWname);
dimname := upper(strDimname);
varname := dimname || '_LIMITMAP';
viewname := owner || '.' || substr(dimname, 1, 22) || '_DIMVIEW';
show ('. Creating view for dimension ' || dimname);
begin
SELECT *
INTO dim_rec
FROM all_olap2_aw_dimensions
WHERE aw_name = awname and
aw_owner = owner and
aw_logical_name = dimname;
exception
when NO_DATA_FOUND then
show ('**');
show ('** ERROR: View not created.');
show ('** Invalid arguments. Ensure that the schema, AW and dimension names are valid.');
show ('** In addition, ensure that you have r/w priviliges to the AW.');
show ('**');
if commitLog
then updateLogTable();
end if;
raise;
end;
-- Attach the AW
begin
isAttached := attachAW(owner, awname);
exception
when others then
show ('**');
show ('** ERROR: View not created.');
show ('** Unable to attach AW r/w. Ensure no other users have the AW attached RW - then try again.');
show ('** In addition, ensure that you have r/w priviliges to the AW.');
show ('**');
if commitLog
then updateLogTable();
end if;
raise;
end;
-- Define the limitmap variable in the AW and assign the limitmap text to it
limitmap := getDimensionLimitmap(owner, awname, dimname);
if limitmap is null
then
show ('Error defining limitmap.');
if commitLog
then updateLogTable();
end if;
raise bad_limitmap;
end if;
-- Define the variable
begin
dbms_aw.execute('define ' || varname || ' variable text');
-- If the variable already exists, simply update it
exception
when others then
show ('..... will update variable ' || varname);
end;
-- Assign the limitmap. Update and commit changes
begin
output := dbms_aw.interpclob(varna -
Using Windows 7 and LR 5, when I look at the Keyword List a certain keyword has 7 pictures but when I check the Library Filter with that keyword 350 pictures are shown which includes the 7 pictures that have the keyword. Why does the Library Filter showing pictures that do not match the query
Dan,
Here's what's going on in the catalog you sent me, "Joel & Caitlin's Wedding". There is the keyword "gwenn", which is explicitly assigned to 7 pics. But keyword "schwartz" has a number of synonyms, including "gwenn", and it is assigned to 25 pics. There is no overlap between the two sets of pics.
I discovered these two occurrences by doing Metadata > Export Keywords, opening the exported file in an editor, and then searching for "gwenn". I found two occurrences of "gwenn":
gwenn
schwartz
{gwenn}
From this, you can see that the keyword "schwartz" has 9 synonyms, of which "gwenn" is one.
The filter criterion "Keywords Contain gwenn" will match the 7 pics that are explicitly assigned the keyword "gwenn", and it will also match the 25 pics assigned the keyword "schwartz", because that keyword has a synonym "gwenn".
This illustrates the behavior I mentioned above: The criterion "Keywords contains x" will match against any of a pic's assigned keywords, any of those keywords' ancestor keywords, and any of the synonyms of the assigned keywords and their ancestors.
So LR is operating correctly here, if not in a way that's easy to understand.
It appears that you are using the synonyms of "schwartz" to represent individual members of the Schwartz family. A better way of representing family relationships is to have a parent keyword "Schwartz", with subkeywords for each family member, e.g. "Gwenn Schwartz", "Joe Schwartz", "Jane Schwartz", etc. Repeating the family name in the subkeywords has a couple of advantages. LR usually only displays the "leaf" name of a keyword, so instead of showing you just "Joe", it will show you "Joe Schwartz", helpful when there are a number of different people whose first name is "Joe". Also, if you ever export your pics to other software, it may not understand the LR hierarchy and won't show the parent keywords, so again it's more informative to see a keyword named "Joe Schwartz" rather than "Joe". -
What is the BISAC category to get into Parenting?
Now working on Flash card books...
Last time it get me many tries (and many books end up in the wrong categories) to find the right BISAC category finally get into Children & Teens category... does anybody know what is the BISAC category to choose to go into Parenting? Is it Family & Relationships / Child Development? or...?K T wrote:
I think the key is how you rank your choices. That and it seems logical that the review teams may have some idea (or cheat sheet to work off of), and as long as your selections match, they'll drop it in the first one you want.
But if your settings conflict, they may override and decide on their own.
I expect so, yes.
When I decided on the categories for my book, I found it quite difficult and non-intuitive. The BISAC categories are quite limited in what they offer.
My book is essentially a DYI guide (drum making). The BISAC "Education" category was one of the first I looked at. But all the sub-categories of that relate to essentially school teaching, which isn't applicable. "Crafts & Hobbies" is another option, but there really isn't any appropriate sub-category in that. (The closest is "Woodwork", but that doesn't really capture it accurately.) "House and Home" has a "General" sub-category, but it's not really about house and home…
"Music" sort of works, but doesn't have a sub-category for instrument building and repair. And so on…
In the end, I settled on a few BISAC and BIC2 categories that matched the topic as best as possible.
The biggest problem with the BISAC and BIC2 categories is that there is no obvious mapping to the categories in the iBookstore. And, as a publisher, I probably care about what section in the iBookstore the book is published in much more than the BISAC or BIC2 categories (which appear to be invisible in the store).
It probably would help if publishers could at least suggest appropriate iBookstore categories when they submit a book.
Michi. -
Has anyone noticed a flaw with contacts?
I cannot associate my mother and father it keeps changing them to manager and assistant?
I am using iOS6 and an iPhone5.Are you syncing with Gmail contacts?
I think there might be a flaw in the way associations are synchronised using Gmail. I noticed the same thing where familial relationships get changes to "Manager" or something similar. -
I've recently bought an iPhone4s but now Siri won't call any contact it says sorry icant call - mobile any advise I need help please
I think that I was able to do that before... Because I have defined the family relationships of my girlfriend and I can't use them with Siri.
Thanks. -
Font Resizing use Baseline by Default
I think font resizing could be inproved by not changing the resize box larger when clicking the bounding box that surrounds a font and also by resizing from the baseline rather than center of bounding box.
Just my thoughts.The internal "family" structure of a font ie what is considered Roman, Italic, Bold and Bold Italic is set in an internal table in the font, by the designer. Frequently there is no such "family" relationship.
You may have to edit the font yourself, there is a short list of applications that will do this. Make sure you clearly label them afterwards to distinguish them from the current set.
Peter
Maybe you are looking for
-
Payment & Deduction Calculation
The no loss / no gain principle is a payroll process ensuring that an employee doesnt receive more or less pay when they are absent for sickness reasons than if they were at work. The No loss / no gain principle applies to the following employees
-
Is there Any way to get TomTom Traffic info From 3G
Having purchased the 3Gi phone and being assured it is compatable with TomTom Go 720 I was gutted to find that a great phone does not support Tom Tom traffic inf & Updates. Great Phone, Great Sat Nav,No Compatability. Whats Going On!! My previuos "SI
-
my ipod touch 4g becomes very hot when play games or surf the web for more than 30 minutes. does any body know why?
-
hi there, I have created a report, here I need to show ordinal date. Could anyone plz tell me how to add ordinal date in SSRS 2008. Eg: 1st , 2nd , 3rd etc I want date in following format Todays date : 16th or
-
Apple earpods not working well
When i listen to music with my headphones if i move or press the cable right above the jack voice control starts or when i move around the music stops or changes..the problem is mainly that the headphone commands start randomly when the cable moves o