Want to know The Truth About CPM?

10 July 2011

Stupid Planning queries #3 -- Accounts

Introduction

I said I would get all of Planning’s dimension queries out in a month, and I aim to meet that goal.

Without further ado, here’s the code to pull out the Account dimension from the sample Planning application in all of its glory.

Yes, I posted this on Network54, but here it is in my blog for completeness’ sake.

As always with these queries, they are 100% unsupported by Oracle and there’s a tremendous chance that I’ve gotten them wrong, so test, test, test and remember that you are hacking the tables and if anything blows up you are completely on your own.  Got it?  Good, let’s begin.

Code to query Accounts

--    Purpose:    Rewrite of Dave Farnsworth's sample Account query using
--                explicit INNER JOINS because I am a control freak.  Yes, it
--                really
isn't any better, I just like it that way.
--    Modified:   30 June 2011, first write Cameron Lackpour, cameron@clsolve.com
--    Notes:      Really written by Dave Farnsworth --              
--                http://www.solutionsexperts.com

--                Go to http://www.odtug.com, then Technical Resources, then go
--                find his white paper on hacking Planning tables, then have
--                fun.  :)

SELECT

    O.OBJECT_ID,
    O.OBJECT_NAME AS 'Member name',
    -- Use SQL Subquery to get aliases.
    -- NB --     The overall SELECT from HSP_MEMBER ensures that members
    --            with and without an alias are selected.
    -- ISNULL puts in zero length string in place of NULL
    ISNULL((SELECT OA.OBJECT_NAME
    FROM HSP_ALIAS A
        INNER JOIN HSP_OBJECT OA
            ON A.MEMBER_ID = O.OBJECT_ID AND
            OA.OBJECT_ID = A.ALIAS_ID), '') AS 'Alias',
    PO.OBJECT_NAME AS 'Parent',
    --    There are up to five Plan Types and operators
    --    can vary across Plan Types, so you will need to repeat
    --    this block if > 1 Plan Type.
    CASE M.CONSOL_OP1
        WHEN 0 THEN '+'
        WHEN 1 THEN '-'
        WHEN 2 THEN '*'
        WHEN 3 THEN '\'
        WHEN 4 THEN '%'
        WHEN 5 THEN '~'
        WHEN 6 THEN '^'
    END AS 'Operator',
    CASE M.DATA_STORAGE
        WHEN 0 THEN 'Store Data'
        WHEN 1 THEN 'Never Share'
        WHEN 2 THEN 'Label Only'
        WHEN 3 THEN 'Shared Member'
        WHEN 4 THEN 'Dynamic Calc and Store'
        WHEN 5 THEN 'Dynamic'
    END AS 'Storage',
    CASE M.TWOPASS_CALC
        WHEN 0 THEN 'NO'
        WHEN 1 THEN 'YES'
    END AS 'Twopass',
  --    The parent object type is either 2, which is the Account

  --    dimension or 32, which is a Account member    

   --    Comment this out as it doesn't really add anything to the

  --    query.   

   --    CASE PO.OBJECT_TYPE,
    CASE AA.USE_445
        WHEN 0 THEN 'None'
        WHEN 1 THEN '445'
        WHEN 2 THEN '454'
        WHEN 3 THEN '544'
        ELSE ''
    END AS 'Spread Type',
    CASE AA.TIME_BALANCE
        WHEN 0 THEN 'None'
        WHEN 1 THEN 'First'
        WHEN 2 THEN 'Last'
        WHEN 3 THEN 'Average'
        ELSE ''
    END AS 'Time Balance',
    CASE AA.SKIP_VALUE
        WHEN 0 THEN 'None'
        WHEN 1 THEN 'Skip missing'
        WHEN 2 THEN 'Skip zeroes'
        WHEN 3 THEN 'skip missing and zeroes'
        ELSE ''
    END AS 'Skip Value',
    CASE AA.ACCOUNT_TYPE
        WHEN 1 THEN 'Expense'
        WHEN 2 THEN 'Revenue'
        WHEN 3 THEN 'Asset'
        WHEN 4 THEN 'Liability'
        WHEN 5 THEN 'Equity'
        WHEN 6 THEN 'Statistical'
        WHEN 7 THEN 'Saved Assumption'
        ELSE ''
    END AS 'Account Type',
    CASE AA.VARIANCE_REP
        WHEN 1 THEN 'Expense'
        WHEN 0 THEN 'Non Expense'
        ELSE ''
    END 'Variance Reporting',
    CASE AA.CURRENCY_RATE
        WHEN 0 THEN 'None'
        WHEN 1 THEN 'Average'
        WHEN 2 THEN 'Ending'
        WHEN 3 THEN 'Historical'
        ELSE ''
    END AS 'Currency Rate',
    --    Bitmask indicating the cubes that use the account
    --    1=revenue
    --    2=net income
    --    4=balance sheet
    CASE AA.USED_IN
        WHEN 1 THEN 'Revenue'
        WHEN 2 THEN 'Net Income'
        WHEN 3 THEN 'Balance Sheet'
    END AS 'Where used',
    CASE M.DATA_TYPE
        WHEN 1 THEN 'Currency'
        WHEN 2 THEN 'Non Currency'
        WHEN 3 THEN 'Percentage'
        ELSE ''
    END AS 'Data Type',
    CASE AA.SRC_PLAN_TYPE
        WHEN 0 THEN 'NA'
        WHEN 1 THEN 'Revenue'
        WHEN 2 THEN 'Net Income'
        WHEN 4 THEN 'Balance Sheet'
    End AS 'Plan Type'
FROM HSP_OBJECT O
INNER JOIN HSP_OBJECT PO ON
    PO.OBJECT_ID = O.PARENT_ID
INNER JOIN HSP_MEMBER M ON
    M.MEMBER_ID = O.OBJECT_ID
INNER JOIN HSP_ACCOUNT AA ON
    AA.ACCOUNT_ID = O.OBJECT_ID
WHERE O.OBJECT_TYPE = 32

Output

It’s too big to put in the blog, so download it here if you want or just run it against your own Planning application.  Happy 100% unsupported querying aka hacking!

01 July 2011

Stupid Planning Queries #2 --- Scenario dimension

Introduction

I am pretty sure I am insane.  There are many that would I agree, I think.

Oh, I am insane -- this blog was WRONG Are Aliases in the Scenario dimension?  Yup.  Why oh why did I think there weren't?  See point #1.  So, Godoy (see the comments for this post), whoever and wherever you are, thanks for reading and pointing out the error of my ways.  The code is corrected below.

Why am I nuts?  Well, maybe a better description is I am just suffering from too much enthusiasm.  An exhausting but exhilarating KScope11 (I will have a post on that but code first) just finished yesterday and when I woke up this morning after finally getting more than three or four hours of sleep (it’s a good thing the conference ended when it did – I couldn’t have taken too much more fun) all I could think about was writing SQL to export Planning dimensions.  See, ODTUG is inspirational that way.

Without further ado, let’s extract dimensions from Planning, starting with the Scenario dimension, which is harder than you think.  All examples are from the Planning Sample App and the inspiration comes from Dave Farnsworth’s excellent hacking Planning tables white paper he presented at last year’s Kaleidoscope in Washington, D.C.  You can get the white paper by going to http://www.odtug.com, then Tech Resources, then search for “Planning Tables”.

As always with these queries, they are 100% unsupported by Oracle and there’s a tremendous chance that I’ve gotten them wrong, so test, test, test and remember that you are hacking the tables and if anything blows up you are completely on your own.  Got it?  Good, let’s begin.

Code to pull Scenario

--    Purpose:    Query the Scenario dimension

--    Modified:   30 June 2011, first write Cameron Lackpour

--    Notes:      Now with Aliases!

SELECT

      O1.OBJECT_NAME AS 'Scenario',

      -- NB -- The overall SELECT from HSP_MEMBER ensures that members

      --       with and without an alias are selected.

      -- ISNULL puts in zero length string in place of NULL

      ISNULL((SELECT OA.OBJECT_NAME

      FROM HSP_ALIAS A

            INNER JOIN HSP_OBJECT OA

                  ON A.MEMBER_ID = O1.OBJECT_ID AND

                  OA.OBJECT_ID = A.ALIAS_ID), '') AS 'Alias',

      O2.OBJECT_NAME AS 'Start Year',

      O4.OBJECT_NAME AS 'Start Period',

      O3.OBJECT_NAME AS 'End Year',

      O5.OBJECT_NAME AS 'End Period',

      --    ISNULL to get rid of ugly Null when there is no fx table.

      ISNULL(O6.OBJECT_NAME, '') AS 'Exchange Rate Table',

      CASE M.DATA_STORAGE

            WHEN 0 THEN 'Store Data'

            WHEN 1 THEN 'Never Share'

            WHEN 2 THEN 'Label Only'

            WHEN 3 THEN 'Shared Member'

            WHEN 4 THEN 'Dynamic Calc and Store'

            WHEN 5 THEN 'Dynamic'

      END AS 'Storage',

      CASE S.USEBEGBAL

            WHEN 0 THEN 'False'

            WHEN 1 THEN 'True'

      END AS 'Include BegBalance',

      CASE O1.MARKED_FOR_DELETE

            WHEN 0 THEN 'False'

            WHEN 1 THEN 'True'

      END AS 'Marked for delete',

      CASE M.DATA_TYPE

            WHEN 1 THEN 'Currency'

            WHEN 2 THEN 'Non Currency'

            WHEN 3 THEN 'Percentage'

            WHEN 4 THEN 'Smartlist'

            WHEN 5 THEN 'Date'

            WHEN 6 THEN 'Text'

            ELSE 'Unspecified'

      END AS 'Data Type',

      --    No way to show the Plan Type.  Remember, a given Scenario is

      --    in ALL Plan Types.

      --    This could vary by Plan Type, so you may need to repeat this CASE.

      CASE M.CONSOL_OP1

            WHEN 0 THEN '+'

            WHEN 1 THEN '-'

            WHEN 2 THEN '*'

            WHEN 3 THEN '\'

            WHEN 4 THEN '%'

            WHEN 5 THEN '~'

            WHEN 6 THEN '^'

      END AS 'Operator'

FROM

      HSP_SCENARIO S

INNER JOIN HSP_OBJECT O1 ON

      S.SCENARIO_ID = O1.OBJECT_ID

INNER JOIN HSP_OBJECT O2 ON

      S.START_YR_ID = O2.OBJECT_ID

INNER JOIN HSP_OBJECT O3 ON

      S.END_YR_ID = O3.OBJECT_ID

INNER JOIN HSP_OBJECT O4 ON

      S.START_TP_ID = O4.OBJECT_ID

INNER JOIN HSP_OBJECT O5 ON

      S.END_TP_ID = O5.OBJECT_ID

INNER JOIN HSP_MEMBER M ON

      M.MEMBER_ID = O1.OBJECT_ID

LEFT OUTER JOIN HSP_OBJECT O6 ON

      S.FX_TBL = O6.OBJECT_ID



Output



ScenarioAlias
Start YearStart PeriodEnd YearEnd PeriodExchange Rate TableStorageInclude BegBalanceMarked for deleteData TypeOperator
CurrentCur
FY09JanFY12DecTestStore Data

FALSE

FALSE

Unspecified~
Actual
FY09JanFY12Jun
Store Data

FALSE

FALSE

Unspecified~
Forecast
FY09JulFY12Dec
Store Data

FALSE

FALSE

Unspecified~
Plan
FY09JanFY12Dec
Store Data

TRUE

FALSE

Unspecified~

Conclusion

The Scenario dimension looks simple, but there is a fair amount of detail in there.  And who knew that Scenarios can’t have aliases?  It even has aliases.

Happy Planning table hacking and keep reading and correcting.