Feeds:
Posts
Comments

Problem and challenge came up recently to pull and set a multiple value parameter from OVD (or LDAP source) and set session variable (row-wise session variable to be specific) to be used by report writing.  Well in OBI 10g, I usually have done that by using my custom LDAP table function to use along with setting row-wise variable(s) in an init block.  I looked to see if anything has changed along the lines of accessing LDAP data sources and pulling parameters.  There is no problem pulling scalar parameters and mapping them to session variables, only when it is comes to trying to pull multi-value parameters and setting a row-wise session variable.  I tried the interface in the admin tool to see if I could do it with no avail.  So I was going to revert to my old approach of using the table function and setting the row-wise session var using that.  Problem is, the client wanted to see if we could do so without using this table function at all.  The challenge!!!!  So I agreed, lets do it.

First, I would need them to set a scalar parameter in the LDAP source as a delimited string of all the values (We chose the notorious ‘,’ delimiter).   And since we will not be dealing with an extensive list of values, I do not foresee length or size issues. It is easy enough to extract this delimited value string now. No problem.  Now we could theoretically stop there and use this delimited value in reports; but it is more tedious as users would need to use and perform a LIKE operator on this session variable and the column compared to.  Not so eloquent if you ask me.  I would prefer the row-wise session variables and let bi server use that to build the physical query proper.

So what now! How do we take a session variable that is a delimited string and get a row-wise session variable out of it!?  Well here is my approach and the solution:

1) I set an init block to query against the LDAP data source to extract the delimited value list string. Also if need be make sure there is default value in case the parameter is not found for that user.

2) Create a new init block, used for setting the row-wise session variable.  This new init block will need to specify the other init block (in step one above) as a dependent using the execution precedence section of the init block properties.  This ensures the proper firing of the init blocks and the dependency between the two.  Then also specify it as being row-wise session variable.  Lastly, I used a pure SQL solution to parse and pivot the string into rows of the individual elements. Now, there could be many approaches to doing this including create custom functions and looking to see if there is such a function already in another package.  But, I just wanted a pure SQL solution.  Here is that SQL query solution (using MODEL clause):

 

SELECT ‘ROW_WISE_SESS_VAR_NAME‘, SUBSTR(str, start_pos, end_pos-start_pos) as value
FROM (
SELECT *
FROM (
SELECT ‘,’||’VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’||’,’ as str,
1 as start_pos,
LENGTH(‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’) as end_pos,
LENGTH(‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’) – LENGTH(REPLACE(‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’,',’))+1 as elem_cnt,
0 AS elem_no,
rownum as rn
FROM dual
)
MODEL
PARTITION BY (rn,str)
DIMENSION BY (elem_no)
MEASURES (start_pos, end_pos, elem_cnt)
RULES
ITERATE (4000)
UNTIL (ITERATION_NUMBER+1 = elem_cnt[0])
(
start_pos[ITERATION_NUMBER+1] = INSTR(CV(str), ‘,’, 1, CV(elem_no)) + 1,
end_pos[ITERATION_NUMBER+1] = INSTR(CV(str), ‘,’, 1, CV(elem_no) + 1)
)
)
WHERE elem_no != 0
ORDER BY str, elem_no

This worked like a charm and can be another solution, if the ldap table function cannot be used in order to get the same results.  Which is multiple value session var from an LDAP source.  Obviously the SQL query above can be used and modified for any such way to parse and pivot delimited string into multiple values.  Note: I am using modeling clause that I believe started to be available in Oracle 10g DB, and this is strictly an Oracle based solution.

I like using the modeling clause as I like to use advanced oracle sql and learn and keep knowledge of all the capabilities available to me.  For those not too familiar with these types of clauses I am adding an alternative SQL solution:

 
SELECT ‘ROW_WISE_SESS_VAR_NAME
, SUBSTR(str, start_pos, (next_pos-start_pos)) AS value
FROM
(
SELECT ds.str
, ne.rn AS element_no
, INSTR(ds.str, ‘,’, DECODE(ne.rn, 1, 0, 1) , DECODE(ne.rn, 1, 1, ne.rn-1)) + 1 AS start_pos
, INSTR(ds.str, ‘,’, 1, DECODE(ne.rn, 1, 1, ne.rn)) AS next_pos
FROM
(select ‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’||’,’ as str from DUAL) ds
, ( SELECT ROWNUM as rn
FROM dual
CONNECT BY ROWNUM <= (LENGTH(‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’) – LENGTH(REPLACE(‘VALUEOF(NQ_SESSION.LDAP_DELIM_STR)’, ‘,’))+1)
) ne
)

 

Thought some developers may find this useful and save time trying to work around, fix or look for answers. Users of the latest OBIEE 11g release 11.1.1.5 may get this error going against OLAP source systems.

State: HY000. Code: 10058. [NQODBC] [SQL_STATE: HY000] [nQSError: 10058] A
general error has occurred. [nQSError: 43113] Message returned from OBIS.
[nQSError: 22068] No more than 1 hierarchy from the same dimension Instrument
can be referenced.

If so, this is a Bug (#12628039) in the latest release, and is currently fixed in a patch (#12628039) for linux-64bit.  However other platforms are in the works for the fix and should be available shortly.

The current global go script I have not only produces one ‘go’ button for all prompts on a page; but, it also has code to create required fields and required field validations. The one thing that was brought to my attention was that my current script treated the prompt collective on the page to have dashboard scope. To read about prompt scope, read here. So whether or not you had one or all set for page scope the global go button disregarded and made it act like dashboard scope. So that any selections on the page would carry over on other dashboard pages. So I have updated my script so that it will use the scope from the first prompt as the entire pages scope for its prompts.  I have added and updated the script on my 2nd blog posting which had the new required field validation, here. For the instructions, on how to setup look here.

-Cheers

Some may think that the scope of the prompts do not work and are broken; but, they do work and are not broken! You just need to know what it really does.  So when you specify a dashboard prompt as scope-> ‘page’, what this does is say that any selections made for this prompt will not be used to set other prompts within the dashboard.  When you specify a dashboard prompt’s scope-> ‘dashboard’, this says that any selection of this prompt will be reflected in other prompts within the dashboard.  I think people get it confused and think that the ‘page’ scope shields the prompt from receiving selections from other ‘dashboard’ scope prompts; but, it does not.  The scope is only there to specify if the selection within the prompt will be local (page) or global (dashboard).

So for any issues where your prompt is still being set by other page prompts within the dashboard, the reason is due to the other prompt having scope-> ‘dashboard’.  If you do not want this behavior within the dashboard, set all the prompts’ scope to ‘page’.  So with this knowledge you will know when to set a prompt to ‘dashboard’ or ‘page’.  ‘Overview’ or ‘Summary’ dashboard pages are a good example of using ‘dashboard’ scope for its prompts, while the other pages in the dashboard are set for  ‘page’ scope.

How does the Dimensions get their ROW_WID(s), which are the dimensions PKs?  Well it is not done by the database systems.  Instead, the PKs are controlled by Informatica using Sequence transformations.  These Sequence transformations are within the mplt_SIL_XXX(s) within the SIL mappings.  Remember in my prior post on mapplets defined in OBIA, these *_SIL_* mapplets are used for lookups for any FKs for the target table and also for getting and setting the PK(s) or ROW_WID(s).  These mapplets are usually after any filter transformations and before the update strategy transformation within the SIL mappings.  Even though these transformations are set as reusable does not mean that all the mappings are using only one and the same sequence transformation.  Each dimension and updatable facts will have their own sequence transformation and they do not share.  However, if the same mapping is being run in parallel for some reason they will use the same sequence transformation and avoid any duplicate PKs in the target table.

These sequences are kept and maintained in the Informatica Repository.  In order to find or see them, you can use the following query which also breaks them into their subjects (aka folders):

SELECT OS.SUBJ_NAME
, OM.MAPPING_NAME
, RWI.INSTANCE_NAME
, OWA.ATTR_VALUE
FROM REP_WIDGET_INST RWI
INNER JOIN OPB_MAPPING OM ON (RWI.MAPPING_ID=OM.Mapping_id)
INNER JOIN OPB_WIDGET_ATTR OWA ON (RWI.widget_type=owa.widget_type AND OWA.widget_id=RWI.widget_id )
INNER JOIN OPB_SUBJECT OS ON (OS.SUBJ_ID = OM.SUBJECT_ID)
WHERE 1=1
AND RWI.widget_type_name like ‘Sequence%’
AND OWA.attr_id=4
ORDER BY OM.mapping_name

attr_id in the predicate above is for the transformation’s properties.  To find these you would open up designer and edit the sequence transformation->properties.  The attr_ids are read top down.  Since the “Current Value” is the 4th down from the top it has attr_id = 4.

1 – Start Value
2 – Increment By
3 – End Value
4 – Current Value
5 – Cycle
6 – Number of Cached Values
7 – Reset
8 – Tracing Level

Remember if you copy over a mapping into your custom folder and it includes a sequence transformation, then make sure when you finally setup the DAC and run the new custom mapping, that the sequence transformation is updated with the correct/current value for the target table.  Or you may create records in the target with duplicate row_wids!  Obviously, full loads will not have this problem as the target table is truncated.

There are pretty much 4 predominant types of mapplets in OBIA Infa ETL.

Business Component (ex: mplt_BC_XXX) – These mapplets are used to extract the data from the source systems.  They are only found in the SDE folders and start off the majority of the mappings.  Within these mapplets, you will find the Source Tables and the Source Qualifier, which has the SQL Overridden. Some  SDE mappings might not use these and have the Source(s) and Source Qualifiers straight within them.

Source Adapter (ex: mplt_SA_XXX) – These mapplets are used for source specific transformations, such as standardizing column formats.  Since they are source specific, they are only found within the SDE folders.

Analytic Data Interface (ex: mplt_ADI_XXX) – These mapplets are source system independent and resolves the codes (code lookup) for the target table.  You will not find much of these, but they are re-usable.

Source Independent Load (ex: mplt_SIL_XXX) – These mapplets are responsible for transforming specific types of columns in the target table. For fact tables, it predominately performs the lookups to the dimensions FK(s) (row_wids).  It also functions to do Code-Name resolutions, dimension surrogate key generation via Sequence transformations, SCDs handling of effective dates,….  There are pretty much a lot of transformation logic that is performed in these.  Since they are encapsulated mapplets and flagged for upgrades, care must be taken to update these for customizations such as extensions.  Refer to ch. 17 within the OBIA config guide for more details on customizing the OBAW.

Just came across this one today.  This appears to be only in v7.9.6.2 as I have not seen before.  Here is the snippet of error message from DAC:

2011-05-12 08:43:50.358 INFORMATICA TASK:SILOS:@DAC_SIL_PositionDimension_FULL_TD_CMD:(Source : FULL Target : FULL) has started.

ANOMALY INFO::: Error while executing : INFORMATICA TASK:SILOS:@DAC_SIL_PositionDimension_FULL_TD_CMD:(Source : FULL Target : FULL)
MESSAGE:::
Irrecoverable Error
Request to start workflow : ‘@DAC_SIL_PositionDimension_FULL_TD_CMD’ has completed with error code 2
Error Message : The specified task name, workflow name, or folder name does not exist.

Pretty much it could not find the workflow as the full command for the task is defined in DAC metadata (OOTB) as ‘@DAC_SIL_PositionDimension_FULL_TD_CMD’.  In my most recent experience, with v7.9.6.1, this particular SIL task has the full command set as ‘SIL_PositionDimension_Full’.  So what is this ‘@DAC_’ value?  Well they were introduced recently to be utlized more and are DAC parameters.  Mostly you see them as a way to do parameter nesting.  This is the first time I have seen used in this way instead of the actual Informatica workflow names.

The cause for this DAC parameter not being substituted with its value? I searched around and got this from Oracle “COMMANDS FOR FULL AND INCREMENTAL SHOULD ALLOW DB SPECIFIC TEXTS”.  So I guess the task commands utilizing these DAC params are not properly passing and replacing those DAC params with their values.

Resolution: Use cumulative Patch 10052370.  Looking at the v7.9.6.2 release notes, this is a mandatory patch for the DAC for this release of OBIA.  Unfortunately, they do not go into great details for this bug.

UPDATE: PATCH ABOVE HAS BEEN DEPRECATED BY ORACLE AND YOU WILL BE REDIRECTED TO USE PATCH 12968641.

The other day while working on data level security within OBIEE (BI Server), I found something very interesting I would like to share.  While testing my data level security for various combinations of groups, I noticed that for one subject area I was not having my security filters applied.

That should not and can not be, I said to myself.  I looked into and traced the presentation column I was using to the related logical tables.  It just came up with the logical table which I applied the filter on.  So why did it not add the filters?  I must have tried different things, looked here and there with no avail.  So I called it a night and would come back in the morning and try something different.

Behold the next day, with a fresh mind I found the culprit!  It was a logical table (“Fact – Fins – AP Activity Compound”) which has no LTS (As seen below)!

Instead the entire logical table and its logical columns are derived off of other logical table columns and thus inherit their definitions. [To find out I selected all the logical columns and ran display related->logical columns.  Below is what came back]

So that is why I was seeing my physical table (alias) which I applied the data level filter on within the physical queries in the NQSQuery.log. But, and here is the kicker, since it was not coming from the logical table that I added the filter too, it did not apply the filter.

Solution:  I looked at all the logical tables which were used by that logical table which make up its logical columns to gather the conformed dimensions I want to filter on.  Then I added the filter on this logical table.  Viola, it is now added the filters to the query as expected.

Lesson Learned: If you apply data level security to a logical table, then it will be for that table and nothing that derives off of it.

I came across this bug/issue that some may encounter.  The issue is with the page controls for the table view and them not working.  If you come across it that the page controls do not work or navigate to the next page of records, then the first thing to look at is your compound view which is the default view set within dashboard pages.  This only happens in compounds views!  Look to see if there are any other views that have been deleted but not deleted in the compound view like here:

Now within the compound view, if you delete a view it just deletes it from the compound view and not the actual view itself.  It also stands that if you delete the actual view it does not remove the reference within the compound view and thus what you see above may result and paging within table views will no longer work for those dashboards using this compound view.  Reference is the key as compound views just store a reference to the views that compromise the compound view itself.  So when a view is deleted, make sure that if it was referenced in the compound view, that the reference is also deleted.

Its been a very, long time since I posted.  And for just cause, as I have been very busy working OBIEE and OBIA projects.  I have noted down along the past year interesting finds which I will post in the coming months.  Of which, I will begin with an issue I came across using Oracle 10GR2, STAR_TRANSFORMATION_ENABLED = TRUE and the WITH Clause.  I came across this via one of the reports generated in OBIA within the Financial Analytics.

While testing reports, I came across this error: ORA-32036: unsupported case for inlining of query name in WITH clause.  From Oracle what this means: “There is at least one query name which is inlined more than once because it’s definition query is too simple and references another query name. This is currently unsupported yet.”  The Solution from Oracle: “remove such query name and retry”.  Upon further investigation within Metalink and on the web this was a bug within the RDBMS and is fixed with the 11.2 patch set.  Or is included within release 12.1.  So how does this help me?  We are not even on 11G db yet.

The one thing I noted was, this did not exist before within this environment.  So what did I change?  The only thing was that I added ALTER SESSION SET STAR_TRANSFORMATION_ENABLED=TRUE within the database conn pool connection script.  Before, the instance did not have this set within the db init params and I wanted to utilized the star schema setup using bitmaps and such for OBIA and its best practice for this setup.  Viola! This error pops up.  Take off it goes away.

Solution for me, was one of 2 things, as there is no upgrade path in the near future for us to move up to 11G with that patchset in the near future.

1) Don’t use the STAR_TRANSFORMATION_ENABLED and potentially have slower performance than I would get with it.

2) Keep the STAR_TRANFORMATION_ENABLED = TRUE and turn off the support for the WITH clause.  I opted for #2 as I did see better performance with this enabled and to me the WITH clause was not that important as it just recreates the SQL query not using the WITH clause.

Older Posts »

Follow

Get every new post delivered to your Inbox.