Introduction to the introduction
This thread on relational drill through on Network54 just won’t die. Is it a zombie? Nope, just an extremely popular subject. With that in mind, and as I’m the one that suggested that my fellow Developing Essbase Applications
author Joe Aultman ask the initial question over a year ago, an
overview into how easy drill through in Dodeca can be is long overdue.One other note – this is a long post, but that isn’t because doing relational drill through in Dodeca is hard, but because I want to document each and every step so you can see how easy it is. FWIW, I went from thinking it couldn’t be hard, to realizing I had no idea how to do this, to actually reading the documentation, to doing it for the very first time in about a day. And now you don’t even have to read the docs. You’re welcome.
How easy does Dodeca have to be?
Tim Tow has covered on his blog how easy it is to bring relational drill through to your Essbase-based application.That’s fine you say (These voices, voices, VOICES, ahhhhh!!!!!!!! Oh, you really are saying that? Okay, nothing to see, move along folks.), but Tim is well…Tim. And you (or would that be me?) are not a superstar, but a mere Essbase hacker. It’s easy for him, but isn’t his effortlessness more a product of his intimate familiarity with Dodeca, his knowledge level (I just spent a week in the patented Tim Tow Java-coding-is-so-cool reality distortion field and let me say this – if you think you’re smart, you really need to spend some time with Tim because you – or is that me? –, umm, aren’t), and maybe, just maybe, isn’t there a soupçon of demo spin behind what he does?
I’m here to tell you I am no Geek Idol, nor am I particularly smart (note the comment about being around Tim), nor am I even remotely capable of spin. I wish I were capable of the last trait as I would likely be a lot richer.
Nope, you’ve got old honest Cameron to take you through a simple and quick tour of how to incorporate SQL drill through from your Essbase database today with a minimum of effort. Do you need EIS or Studio to do drill through? Nope. The long-obsolete drill through package for Essbase? Nope. A programming talent the size of a 1965 Buick Electra 225? Nope. Just little old Sample.Basic and Dodeca.
Make Sample.Basic more Basic
Long time readers, all three of you, of my blog know that My Very Favorite Essbase Database In The Whole Wide World is none other than Sample.Basic, which I shall henceforth refer to as MVFEDITWWW. For those who care, it is pronounced “mfffeditwaa,” which I believe is akin to the initial sound made upon dropping a 14 pound sledgehammer on one’s foot. Other, less family-friendly sounds can then occur – imagine away.My future plans
One day I shall discover a company called The Beverage Company, they will sell soda pop (Michigan influence bubbling up there) in a few oddly distributed states, and will have a remarkably limited view of their chart of accounts. When this happy day occurs, I am going to be the most productive consultant ever. Interested packaged goods IT managers can contact me care of this blog.Back to reality
Love everlasting for Sample.Basic? Yes, but regardless I’m going to take the shears to my beloved MVFEDITWWW and remove most of the Product dimension (but not clear out the upper level data) as that is what we are going to drill from. A silly example as low level product information is already there in Essbase but hey, it’s a demo.Product in MVFEDITWWW
Product in Sample.DrilThru
Note the absence of the Caffeinated, Intro Date, Ounces, and Pkg Type attribute dimensions – they cannot be used because the corresponding base members in the Product dimension no longer exist.
Base data
Here’s the data I extracted out of the database-that-shall-not-be-named:I wanted each record to represent all dimensions with a data column at the end. I could have run two Essbase report scripts, one for Actual, one for Budget, back to back by placing an explanation mark “!” between the two report scripts but I am feeling all kinds of SQL so I used my child-like skills to do it in SQL Server and besides I wanted the member names “Actual” and “Budget” in the record. Yes, you can likely write this better than I can and I invite your suggestions – I will update this post to show a better way.
Here’s the SQL I used to create the drill through table:
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'dDrilThru')
DROP TABLE dDrilThru
GO
USE Blog_Dodeca
CREATE TABLE dDrilThru
(
Product nvarchar(80),
Market nvarchar(80),
Measure nvarchar(80),
[Year] nvarchar(80),
Scenario nvarchar(80),
[Data] float
)
INSERT INTO dDrilThru
SELECT
Product,
Market,
LTRIM(Measure),
[Year],
'Actual' AS "Scenario",
Actual AS "Data"
FROM
dImportSampleBasic
WHERE Actual IS NOT NULL AND
Actual <> 0
UNION
SELECT
Product,
Market,
LTRIM(Measure),
[Year],
'Budget' AS "Scenario",
Budget AS "Data"
FROM
dImportSampleBasic
WHERE Budget IS NOT NULL AND
Budget <> 0
ORDER BY
Product, Market, LTRIM(Measure), [Year]
And that gives me data that looks like this:
Supporting tables
hProductLookup
I also set up a table called hProductLookup that defined the relationship between the now-shortened Product dimension and the level 0 Products in dDrilThru. Yes, I could have used the leading three character member names but I wanted to take that dependency out.hProductDescription
Oh, I suppose I could have put the description for the formerly level 0 Products into hProductLookup, but I also wanted to completely normalize (maybe overly normalize) the tables and also I was going to need a relational description of what were the the level 1 Products, so I jammed that all into hProductDescription.What does that mean?
The above table, dDrilThru, is now ready to be drilled into. That wasn’t hard, was it?
Retrieving SQL in Dodeca
There are three components to a SQL retrieve in Dodeca: a SQL connection (what server/database is Dodeca querying/inserting/updating/deleting), the actual SQL statement, and its application in a Dodeca report. That’s it – it is all pretty straightforward and even a SQL idiot like yr. obdnt. srvnt. can figure it out.SQL Connections
All
that the SQL Connection defines (btw, I named mine Blog_Dodeca because I
am imagination-challenged – you can call it anything you like) is the
Dodeca name of the connection, the JDBC url to the database, and the SQL
username/password.
SQL Passthrough Data Sets
I really like the name Applied OLAP came up with for the query – “SQL Passthrough Data Set”. I guess it could have just been called “SQL Query” but you can do so much more than just a simple SELECT as we shall see.
In any case, we name it, and then we define a query to go with the object. That query will produce a DataTable that in turn will, when the View is defined, be related to a physical range in the target sheet.
Defining the query
Things get a wee bit more complicated here, but only a tiny bit.For the query to work, it needs:
- A SQLConnectionID –the login to SQL defined in the previous step and selectable through a dropdown control
- A DataTableName – a virtual table that receives the contents of the query results – name it whatever you like
- SelectSQL –all four (Delete, Insert, Select, and Update) queries could be defined; in our case, we just want a SELECT statement
What does that query look like?
This is where Dodeca shows off one of its many ultra super powers.Here’s a query that pulls all of the product information for product family 100.
SELECT
H.ProductFamily AS 'Product',
H.Product AS 'SKU',
PD.Description AS 'SKU Desc',
D.Market,
D.Measure,
D.[Year] AS 'Month',
D.Scenario,
D.Data
FROM
dDrilThru D
INNER JOIN hProductLookup H ON
D.Product = H.Product
INNER JOIN hProductDescription PD ON
D.Product = PD.Product
INNER JOIN hMonthSort M ON
D.[Year] = M.MonthDesc
WHERE H.ProductFamily = '100'
That returns a result set that looks like this:
SELECT
H.ProductFamily AS 'Product',
H.Product AS 'SKU',
PD.Description AS 'SKU Desc',
D.Market,
D.Measure,
D.[Year] AS 'Month',
D.Scenario,
D.Data
FROM
dDrilThru D
INNER JOIN hProductLookup H ON
D.Product = H.Product
INNER JOIN hProductDescription PD ON
D.Product = PD.Product
INNER JOIN hMonthSort M ON
D.[Year] = M.MonthDesc
WHERE H.ProductFamily = '100'
AND D.Market ='New York'
AND D.Measure = 'Sales'
AND D.Scenario = 'Actual'
ORDER BY H.Product, D.Market, D.Measure, D.Scenario, M.MonthNo
That query returns this:
12 records is a lot more like it. I want detail, but not too much. YMMV.
What’s the problem?
Well, one big problem with the query is that I’ve hardcoded the ProductFamily, Market, Measure, and Scenario dimensions. That isn’t exactly going to lead to drill through, is it? Unless of course I only ever queried 100, New York, Sales, and Actual and then why bother with drill through at all?Tokens to the rescue
Nope, not the ones you (used to) use on the NYC subway. I mean strings within the SQL statement that can be replaced with selected values from Essbase member selections. Of course (Of course? Of course I mean of course.) Dodeca already does this for the purposes of Essbase retrieves. Here’s what they look like in the Selectors editor:To make the SQL statement pick up these tokens, all we need to do is change the hardcoded WHERE clause to one that is tokenized. The query ends up looking like this:
SELECT
H.ProductFamily AS 'Product',
H.Product AS 'SKU',
PD.Description AS 'SKU Desc',
D.Market,
D.Measure,
D.[Year] AS 'Month',
D.Scenario,
D.Data
FROM
dDrilThru D
INNER JOIN hProductLookup H ON
D.Product = H.Product
INNER JOIN hProductDescription PD ON
D.Product = PD.Product
INNER JOIN hMonthSort M ON
D.[Year] = M.MonthDesc
WHERE H.ProductFamily = '[T.Product]'
AND D.Market ='[T.Market]'
AND D.Measure = '[T.Measures]'
AND D.Scenario = '[T.Scenario]'
ORDER BY H.Product, D.Market, D.Measure, D.Scenario, M.MonthNo
When we set up the Dodeca View correctly, it will pass [T.Product], [T.Market], [T.Measures], and [T.Scenario] right to the query and return only the items selected in the Essbase selectors. Sounds like drill through, doesn’t it?
Setting up the query
Before Dodeca can retrieve anything to a SQL sheet, we need to define the data source (that’s done in via the SQL Connection already described) and then the query(ies) for that connection. A SQL Passthrough Dataset is the place to define that. Note that a dataset can have multiple queries – we are defining only one and it’s just a SELECT.Here’s the definition of the dataset:
Click on the ellipses button to get the query window to pop up:
Define the SQLConnectionID via a dropdown control, the name of the virtual table to contain the results of the query (that is not the same as the name of the source table(s) and will be important in a bit), and the SelectSQL statement which is going to look awfully familiar:
That query needs to get tied to a base report that drives those tokens that in turn gets driven from an Essbase sheet.
Base SQL retrieve in Dodeca
Did you know that Dodeca is a really good SQL query and reporting tool? Yep, it is pretty impressive, and easy.SQL Setup in the View
Excel template
Setting up a SQL retrieve is very similar to the process for Essbase. The main difference from an Excel template perspective is that the retrieve range is called DataRange.1 (it could actually be called Rutabaga, but DataRange.1 makes a lot more sense – the .1 is to help identify the SQL source as you can easily have multiple SQL source retrieves on a sheet) instead of Ess.Retrieve.Range.1.NB – It’s a good idea to make ALL range names sheet level instead of workbook.
You will notice that the columns in this retrieve range look an awful lot like the query you saw above. That is not accidental.
SQL View properties
The SQL View is similar to the Essbase View but with a few minor differences, the most important being the DataSetRanges property. The purpose behind a DataSetRange is to associate a SQL Passthrough DataSet with a named range on the retrieve sheet.Click on the ellipsis button to define the DataSet Range.
DataSet Range
Once in the editor, select the SQLPassthroughDataSetID that defines the connection and the query via a dropdown control.Then define where the results of the query will be sent when the user builds the view by clicking on the ellipsis button.
DataTable Range
Define the name of the range that will receive the query results – that’s the DataSheetRangeName.Also define the name of the DataTable – that virtual table name is defined in the Query definition and its contents gets passed to the DataSheetRangeName on retrieval.
Once all of this has been input, confirm your way out of the DataTable Range Editor and the DataSet Range Editor and Commit the View changes.
Run that SQL report
And that’s it! Let’s retrieve some data and see what it looks like:Note the selectors at the top – we can make selections (New York, 100, Sales, Actual) and get all of the data associated with those parameters. Now it’s time to hook it up to Essbase and drill into this report.
Base Essbase retrieve in Dodeca
This is pretty simple stuff in Dodeca – the Essbase source sheet looks like this:Do you see the missing token? That’s right, [T.Product] isn’t on the sheet. That’s because we’re going to grab it from Colas, Root Beer, Cream Soda (ugh, I never liked that stuff), and Fruit Soda (A few years ago I tried a Faygo Red Pop on a trip back to Michigan. I LOVED it as a kid – now, I think I’d rather drink dishwashing detergent. But I digress yet again.) on the drill through.
Once the above template is imported into Dodeca, a simple View needs to be set up:
When that view is retrieved in Dodeca – magic redux. Note the dimension selectors at the top of the screen whose values replaced the tokens on the retrieve sheet. Sort of, kind of, the same as the SQL retrieve sheet.
Drill on through to the other side
Yes, yes, you had to read 2,416 words of my idiotic blathering to get to what you really wanted to see. Sorry, but I had to show world+dog all of the setup steps. It gets very simple, and very fast from now on.To define the data drill through from Essbase to SQL, go to the Essbase View’s Data DrillThrough settings block.
Data Drillthrough Settings
DataCellDoubleClickMemberFilters
I set up a filter on the Measures dimension to prevent drill through on upper level members like Profit, Margin, etc. as there are no corresponding values in my SQL drill through source. It’s really quite easy to put in and prevents drill through at those upper levels.DataCellDoubleClickPolicy
This property defines how the drill through will act. In this example, I wanted to open that SQL view I detailed above. There are however lots of options as you can see.DataCellDrillthroughMemberToTokenConversionRules
Dodeca doesn’t just have to pass the bottom level member as per this example. This is really pretty interesting as it means the drill through could grab a bunch of related SQL data as well if desired.DataDrillthroughSheetName
This sheet name only makes sense when the DataCellDoubleClickPolicy is set to AddSheetForDrillthrough. As this example opens a separate View, it stays blank.DataDrillthroughSheetNameMaxLength
The maximum length of a sheet name (that little tab at the bottom of an Excel workbook is 31 characters. Dodeca can support longer sheet names (huzzah! as that 31 character limit is…limiting) but you the Dodeca developer (you are all going to be Dodeca developers, right?) have to figure out if your Dodeca drill through awesomeness is ever going to be exported to Excel or not. If not, set this to zero (assuming you are using a new sheet) and it can be whatever length you like. Again, I am using a separate View, so it doesn’t apply.DataDrilltrhoughViewID
The name of the target View, i.e., Sample DrillThru SQL Results. Note that the tokens used in Essbase are automatically passed to the SQL View based on the cell used for drill through. Pretty damn cool is what I call that.EnforceEssbaseFilterOnOpenViewForDrillthrough
If I had any Essbase security on this application, this setting would enforce Essbase security on the drill through. In other words, if I didn’t have access to a data cell in Essbase, I would continue to not have it in the drill through sheet, and if I did, I would see it in the drill through sheet. Of course since this is running off of my laptop, all of the above isn’t happening, but it’s nice to know that it’s there.It’s demo time!
I am going to try something a little different with this blog post, and may rip it out if it doesn’t work.If a picture is worth a thousand words, how many words is a movie worth?
For those not content to watch the drill through in video form, here’s a sample of how this works.
Good for Essbase, bad for the drill through
I am purposely drilling through from Margin. Recall that I put a level zero filter on the Measures dimension.So what does an invalid drill through do when I double-click on cell B6?
Nothing to see, folks
Look down in the lower left hand corner of the picture – Dodeca has forbidden the drill through, as specified.A valid drill through
Now I will select Sales and double click on Qtr1 Colas.Isn’t it beautiful?
Ta da, drill through Nice n’ Easy.Is that it?
What, you want more? Hire me if you want that much of my time.I think I’ve shown that you can drill from an Essbase database with very little work (ignore the length of this post – I wanted to show you every single step but this is one of those “It takes longer to explain than to do” kinds of things).
Drill through to a source, as per FDM? Yep.
Drill through to a predefined table or series of tables as in Studio? Yep.
Drill through to anything you want, with less work than the above two tools (and a bunch I haven’t mentioned)? Yep.
Dodeca wins (is anyone surprised?) again. I love this product. Hmm, maybe I should see a doctor about that – I’m sure there’s a syndrome in the DSM that matches this somewhat unnatural, but completely understandable affection. :)
Dear
ReplyDeleteI am so new to Essbase 9.3.1
I am now working to add new dimension (data source) to existing dimensions in database outline. I would like to seek your advice that is any quick/easy to way to do this? And any resource for that? Thanks a lot
thomas
I was here :-)
ReplyDelete