Uncategorized

I stumbled upon a post from Shiv Bharti and thought I’d expand a bit on this idea. First of all to prevent the necessity of using the “Advanced” tab; one of the “don’t do this at home, kids” parts of Answers. Secondly since just recently there was yet another question on OTN asking for advice on how to assign / force new values to a session variable during runtime.

Let’s do the example with an Essbase cube as a data source to showcase that this approach works with any data source. First, I create an initialization block which goes against an Oracle 10gR2 source to be able to write a simple dummy select statement from DUAL indicating CoFSM42 as my default Essbase server. CoFSM41 is a backup instance and hence my Essbase server which I want to switch to in order to see what the backup contains in terms of data loads (in this example, 42 will contain data until today whereas 41 will be the backup from last week, so no data this week).


select ‘CoFSM42’ from DUAL

Of course you can implement more elaborate solutions with control tables holding the servers and schemas of your different environment and instances.

In the connection pool to my Essbase source, I change the “Essbase Server” parameter to “VALUEOF(NQ_SESSION.Essbase_Server)

Starting the server, let’s to a quick check of the data through answers by using the approach Shiv proposed. First, I create the request on my standard subject area which currently points to CoFSM42 due to the session variable.

I see that the data I entered for this week is present. Using the SET VARIABLE prefix, I change the source to CoFSM41.

Ok, that’s empty. Now off to making this switch available on the dashboard through a prompt. The prompt is a fake prompt simply unioning my two server names. Here again, you may use a control table which holds your servers.

The important bit is to choose “Set Variable” as “Request Variable” and in the variable name “Essbase_Server” (my session variable used in the connection pool). Now I combine the prompt and the request in a dashboard to see the effect the “Set Variable” has on the request I’ve built. Bear in mind that there is no “is prompted” speficication or filter on that request apart from my week specification.

Here’s the results prompted with the current server:

And here the ones for the backup server:

So the prompt nicely switches between the different data sources for us without the need of Answers access or within Answers the need to play with the query prefix. Plus, it has shown the use of prompts to changes the values assigned to session variables during runtime.

Now for all those who were hoping for another OBIEE/Essbase post or are thinking about using this to switch cubes easily in their architecture:
Unfortunately this approach can NOT be used to easily switch between cubes. And who’s to blame? The substitution variables.

Essbase substitution variables, when defined on database level (“cube” in OBIEE terminology), arrive in the form of “server:application:database:varaiable”. E.g.: “CoFSM42:Sample:Basic:vCurQtr”.
The “CoFSM42” bit can’t be switched out using a variable since the variable name is always interpreted as a literal string. Taking the example from above, doing something like “VALUEOF(NQ_SESSION.Db_Server):Sample:Basic:vCurQtr” won’t work since the variable is then actually called “VALUEOF…”

Pity, since that would make your development and testing of different Essbase sources extremely flexible.

Cheers,
C.

Uncategorized

UDML constantly keeps popping up in conversartions, questions I receive and – as can be seen from a quick query – on the OBIEE OTN forum. So before I go on with this post, a reminder: UDML is NOT supported as an rpd modification mechanism! Everything you do is at your own risk.

Right-o. I’d like to tie my post to the official OBIEE-Essbase modelling guide which can be found here.

Page 8, paragraph 4.1 “Subsequent Changes to the Essbase Outline” mentions the following:

“Cube structure changes (that is, adding or deleting dimensions, and levels) require either a re-import of the cube, or manual modification to the BI Server physical metadata objects to reflect changes.”

This is something that quite some people have contacted me about and honestly, I doubt that there’s really any case which justifies re-import of a cube if you know your way around the Admin Tool and UDML. Even though it’s an Essbase source! (I’ll stick to using the term “cube” to denominate Essbase “databases” for this post.)
One thing needs to be noted though. It’s a small thing, but it basically forces you to use UDML rather than manual modification through the Admin Tool.

Let’s start with a basic cube which I have already imported into my RPD while I was still developing on the Essbase side. So far – where OBIEE is concerned – it only consists several accounts which I can analyze by time.

On the Essbase side, the cube has grown somewhat and I’ve added my “Scenario” dimension.

To get this into OBIEE, I have two possibilities: re-import of the cube of manual creation of the dimension in the physical layer. Not wanting to lose my work on the BMM and Presentation layers, I choose the latter.

Right-clicking on the “Physical Cube Table” object, select “New Object” -> “Hierarchy”.

Then create two new “Physical Cube Columns” below the physical cube table:

Now I have the hierarchy and the two columns:

Next we create the actual hierarchy tree out of them. “New Physical Level”:

And add the column:

And the same thing for level 2 giving us this:

Now this structure is correct, usable and transformable into a corresponding business model:

However in the background there is one little thing going wrong which can give you headache in Answers…especially since tracking down the source of the weird errors this produces is a real pain. I have to admit it took me a while to figure it out.

Let’s take both the time and the scenario hierarchy and copy+paste them into a text editor.

Looking at the top level of the exported UDML, the two hierarchies are alike and don’t differ:

DECLARE HIERARCHY “Demo”.”Sample”..”CustomDemo”.”Time” AS “Time” UPGRADE ID 2161957949 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen1,Time”,
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen2,Time”,
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen3,Time”,
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen4,Time”,
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen5,Time”,
“Demo”.”Sample”..”CustomDemo”.”Time”.”Gen6,Time” ) MEMBER TYPE ALL EXTERNAL “Time”
FULLY BALANCED
BELONGS TO TIME DIMENSION
DIMENSION UNIQUE NAME “Time” TYPE 1
ALIASES NOT UNIQUE
PRIVILEGES ( READ);
DECLARE PHYSICAL LEVEL “Demo”.”Sample”..”CustomDemo”.”Time”.”Gen1,Time” AS “Gen1,Time” UPGRADE ID 2161959167 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Gen1,Time” )
KEY “Demo”.”Sample”..”CustomDemo”.”Gen1,Time”
LEVEL NUMBER 0 EXTERNAL “Gen1,Time”
PRIVILEGES ( READ);

DECLARE HIERARCHY “Demo”.”Sample”..”CustomDemo”.”Scenario” AS “Scenario” UPGRADE ID 2161960605 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Scenario”.”Gen1,Scenario”,
“Demo”.”Sample”..”CustomDemo”.”Scenario”.”Gen2,Scenario” ) MEMBER TYPE ALL EXTERNAL “Scenario”
FULLY BALANCED
DIMENSION UNIQUE NAME “Scenario” TYPE 3
ALIASES NOT UNIQUE
PRIVILEGES ( READ);
DECLARE PHYSICAL LEVEL “Demo”.”Sample”..”CustomDemo”.”Scenario”.”Gen1,Scenario” AS “Gen1,Scenario” UPGRADE ID 2161960612 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Gen1,Scenario” )
KEY “Demo”.”Sample”..”CustomDemo”.”Gen1,Scenario”
LEVEL NUMBER 0 EXTERNAL “Gen1,Scenario”
PRIVILEGES ( READ);

Looking at the two respective extracts for the second level, we see the difference:

DECLARE PHYSICAL LEVEL “Demo”.”Sample”..”CustomDemo”.”Time”.”Gen2,Time” AS “Gen2,Time” UPGRADE ID 2161959169 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Gen2,Time” )
KEY “Demo”.”Sample”..”CustomDemo”.”Gen2,Time”
LEVEL NUMBER 1 EXTERNAL “Gen2,Time”
PRIVILEGES ( READ);

DECLARE PHYSICAL LEVEL “Demo”.”Sample”..”CustomDemo”.”Scenario”.”Gen2,Scenario” AS “Gen2,Scenario” UPGRADE ID 2161960614 HAVING
(
“Demo”.”Sample”..”CustomDemo”.”Gen2,Scenario” )
KEY “Demo”.”Sample”..”CustomDemo”.”Gen2,Scenario”
LEVEL NUMBER 0 EXTERNAL “Gen2,Scenario”
PRIVILEGES ( READ);

For the imported hierarchy “Time”, the “LEVEL NUMBER EXTERNAL” is correctly incremented and stored as “1” (and in fact represents the level number in Essbase) while for the manually created hierarchy “Scenario” the external level number stayed at “0”.
If you have hierarchies with more than 2 levels, each level from 1 to N has an external level number of “0”.

In the rpd, there is no way for you to affect the external level number, so UDML is your only choice. In all honesty, I normally write my new dimension hierarchies – which should be reflected in the rpd due to cube changes – simply inside a text editor. Starting with an existing hierarchy which I copy+paste, I then write the UDML to fit the Essbase outline and then adapt the external level number to fit the real Essbase level number.

With that problem out of the way there’s really nothing you can’t represent in terms of cube outline changes without having to re-import the whole thing.

So much for today. Until next time!

Uncategorized

I was just testing multiple web catalogs when I realized that it’s a bad idea to put version numbers into the web catalog name.

As an example, I have my web catalog “samplesales_paint_v1.3” sitting ready in OracleBIDatawebcatalog and my instanceconfig.xml looking like this:

< ?xml version="1.0" encoding="utf-8"?>
< WebConfig>
< ServerInstance>
< DSN>AnalyticsWeb
< CatalogPath>F:OracleBIDatawebcatalogsamplesales_paint_v1.3

Starting up the server will not load the refrenced catalog, but rather create a new one from scratch: “samplesales_paint_v1”

And the Oracle BI Presentation Services Administration duly notes:

Physical Presentation Catalog Path \?F:OracleBIDatawebcatalogsamplesales_paint_v1root

The sawlog0.log reads as follows:

Type: Error
Severity: 40
Time: Wed Jul 21 23:46:36 2009
File: project/webcatalog/localwebcatalog.cpp Line: 1507
Properties: ThreadID-4328
Location:
saw.catalog.local.loadCatalog
saw.webextensionbase.init
saw.sawserver
saw.sawserver.initializesawserver
saw.threads

Could not load catalog F:OracleBIDatawebcatalogsamplesales_paint_v1.3. Either it does not exist or insufficient permissions.
—————————————
Type: Warning
Severity: 40
Time: Wed Jul 21 23:46:36 2009
File: project/websubsystems/httpserverinit.cpp Line: 49
Properties: ThreadID-4328
Location:
saw.catalog.local.loadCatalog
saw.webextensionbase.init
saw.sawserver
saw.sawserver.initializesawserver
saw.threads

Creating Catalog F:OracleBIDatawebcatalogsamplesales_paint_v1.3.
—————————————

The log is incorrect on both accounts. “F:OracleBIDatawebcatalogsamplesales_paint_v1.3” does exist and the folder creation in the warning message may use the correct naming but actually creates folder “F:OracleBIDatawebcatalogsamplesales_paint_v1”.

XML normally accepts “.” inside the element content so I guess this is a legacy fragment from Siebel Analytics versions where the web catalog was a .webcat file. Why? Well, using this element:

< CatalogPath>F:OracleBIDatawebcatalogpaint.webcat

starts my “paint” folder 😉

Any comments on this are welcome.

Cheers,
Christi@n

Uncategorized

Hi guys,

Just quickly to let you all know. I’m not cutting you out of the loop by not writing on the details, but if I’d have to document all tests I run and all issues I find, I will still be here next month.

Bottom line:
– watch out for 10.1.3.4.0 with 734908
– watch out for 10.1.3.4.0 with 844119
– watch out for 10.1.3.4.1

With those three versions be VERY careful that you test each and every report you have running against Essbase.

I will update you as soon as I can with a finalized overview. Probably only once Oracle has come back…

Uncategorized

I noticed something very disturbing after applying 10.1.3.4.1 to our development environment: report grand totals for tables and row totals for pivots don’t yield any results anymore unless you manually set all fact columns to “Sum” or “Avg” in the report. The “Aggr_External” which has normally had its effect (by importing it from the cube through the physical to the BMM layer to presentation layer) no longer takes care of this.

Let’s look at the issue in detail:

Upgrading to 10.1.3.4.1, this is what we find as a default behaviour in a simple table report:

And in a pivot:

Now think about the concept behind building an rpd on top of an Essbase source for a second. Ponder what Venkat wrote about aggregations in for 4-article series here, here, here and here. No longer utilizing Aggr_External and just no longer aggregating at all is just plain stupid. (Yes, I’m on kind of a rant here…)

Now to correct that quick & dirty in the report, we assign an aggregation rule in the column formula:

And…oh miracle…we have data again:

Now as I said, I find this nothing but retarded.
Why has this been changed? Is this actually expected behaviour? If so…what’s the rationale behind that? Normally, aggregation rules set on the BMM layer always persist unless they are explicitly overwritten either in the column formula or for pivots in the measures. Why drop this all of a sudden?

My manual intervention is a workaround, but I’m facing several cubes and almost a hundred reports. Furthermore, one of the Account dimensions has more than 400 members. So manually changing 400 potentially mapped account members isn’t fun…

So the solution (if I will actually keep 10.1.3.4.1 and not just drop if for a downgrade) would be to modify the BMM layer and change all normal account members to “Sum” and all percentages to “Avg” as aggregation rule.

Stay tuned for my upcoming rant on dimension members and filters. Another extremely intelligent change with 10.1.3.4.1.

Update:
Venkat reacted to my post here. I tested it and it seems that despite having label only top level members like he mentioned, some analyses seem to work with totals and grand totals. This will need more investigating.

Cheerioh,
Christi@n