Sunday, August 17, 2014

OBIEE 11g repository on READ ONLY mode



If  there is a requirement to make OBI repository as read only—
To give READ ONLY access to users please navigate to following and check to disable online updates on repository. Bounce the server to activate changes.

Login to Oracle Enterprise Manager Goto -> Business Intelligence -> coreapplication
Click - Capicity Managment Tab in Right side -> Performance -> Check Disable Disallow Online RPD Updates

In order to make any development work then enable the option and bounce the server to activate the changes and repository will be opened for modifications.

Check to disable the option once development work is done else this will allow users to modify the repository knowingly or unknowingly.




Sunday, August 3, 2014

Type of Dimensions (Conformed/Junk/Degenerate)


                                     Type of Dimensions


Conformed Dimension:

When a dimension can be used with multiple Facts, more precisely with multiple facts from multiple Data Marts. Conformed dimension provide the ability to perform the analytics across multiple subject ares of the Enterprise.

Most common example is Date Dimension.

Others are Product  Dim, Customer Dim.
Junk Dimension:

Its a way to store flags and indicators that are associated to transnational data. By creating Junk dimension these flags and indicators can be removed from the corresponding Fact table and placed in Junk dimension. 

The transaction table (in OLTP) may have several yes/no, true/false, indicator or  comments fields or columns with low carnality values.

If we leave these in Fact table then the row length would  be unnecessary large (and so the I/O).  


While creating a respective Fact table in Data Warehouse, one way is to those columns in the Fact table as it is, other way is use a junk dimension that holds all the unique combinations of those indicator fields into a single dimension and assigns a unique key.  This key is what is stored in the fact table.  So you will have only one additional dimension table and will reduce the number of fields in the fact table. 


Lets say there is Order Transaction Table that contains flags like Created (yes/no), Shipped(Yes/no), Returned ( Yes/No), Cancelled (Yes/No). These flags are related to status of the Order (or Order Line). There would be Order Key in the Fact Table that is linked to Order Dimension. There is no need to store Flags in the Fact table. In this case there is no need for Junk Dimension.

But at times there could be flags that are not associated to any dimension, and if there are plenty then keeping them in a Junk dimension would be more appropriate rather than storing them in the Fact table.  

(Let me find out some real life example of such flags and indicators and I will update here)


Wednesday, July 16, 2014

Report Bursting in OBIEE

What is bursting?

Bursting is a process of
-          Splitting data into blocks
-          Generating document for each block
-          Delivering the document to one of more destinations

The data for the report is generated by executing query once and then splitting the data based on a key value. For each block on data, a separate document is generated and delivered.

Using BI Publisher’s bursting feature we can split a single report based on an element in the data model, and deliver the report based on a second element in the data model. Driven by the delivery element, we can apply a different template, output format, delivery method and locale to each split segment of the report. Example implementation are –
-          Report generation for customer with their own company logo on the report.

-          Generation of pay slips to all employees based on one report and delivered to them by email.

Monday, June 16, 2014

Change Data Capture in Oracle

Publisher/Subscriber Approach

1)     SYS
a.       The database should run in Archive Log mode
b.      Force Logging should be on.
c.       Create table space for three users (Albert, Publ_cdc and Subs_cdc). Separate table space is not mandatory and but is recommended for clean administration.
d.      Create three users – owner, publisher and subscriber
e.       Grant create session/table/sequence/procedure to three users. Grant connect/resource to three users.
f.        Grant execute_catalog_role and select_catalog_role to publisher and subscriber
g.       Grant execute permission on following DBMS packages to publisher and subscriber
                                                               i.      DBMS_CDC_PUBLISH
                                                             ii.      DBMS_CDC_SUBSCRIBE
                                                           iii.      DBMS_LOCK
h.      Make publisher as stream administrator
i.         Make user table(s) as capture enabled tables.
j.         Important SQL to check status on various things
2)     User/Owner
a.       Create table whose changes needs to be captured
b.      Grant select permission on the  table to publisher and subscriber
c.       Ensure all changes are recorded in redo logs
3)     Publisher
a.       Define CHANGE_SET, SOURCE TABLE and Publication
b.      Grant access of Change table to Subscriber
4)     Subscriber
a.       Create subscription to the publication
b.      Create subscribers view
c.       Activate subscription

5)     Test Asynchronous CDC


1)     SYS
a.       The database should run in Archive Log mode
b.      Force Logging should be on (below command should be run while database is in mont state (not in open)
                                                                           i.      alter database force logging;
                                                                         ii.      alter database add supplemental log data;
c.       Create table space for three users (Albert, Publ_cdc and Subs_cdc).
CREATE TABLESPACE TS_CDC DATAFILE 'C:\ORACLE\ORADATA\TEST10G\TS_CDC.DBF' SIZE 50M
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
SEGMENT SPACE MANAGEMENT AUTO
LOGGING
FORCE LOGGING;

d.      Create three users – owner, publisher and subscriber
create user albert identified by albert
default tablespace ts_cdc
temporary tablespace temp ;

create user publ_cdc identified by publ_cdc
default tablespace ts_cdc
temporary tablespace temp ;

create user subs_cdc identified by subs_cdc
default tablespace ts_cdc
temporary tablespace temp;

e.       Grant create session/table/sequence/procedure to three users. And connect/resource also.

GRANT create session TO albert;
GRANT create table TO albert;
GRANT create sequence TO albert;
GRANT create procedure TO albert;
GRANT connect TO albert;
GRANT resource TO albert;

GRANT create session TO publ_cdc;
GRANT create table TO publ_cdc;
GRANT create sequence TO publ_cdc;
GRANT create procedure TO publ_cdc;
GRANT connect TO publ_cdc;
GRANT resource TO publ_cdc;

GRANT create session TO subs_cdc;
GRANT create table TO subs_cdc;
GRANT create sequence TO subs_cdc;
GRANT create procedure TO subs_cdc;
GRANT connect TO subs_cdc;
GRANT resource TO subs_cdc;
f.        Grant execute_catalog_role and select_catalog_role to publisher and subscriber since they need to access the dictionary i.e. views in SYS schema-
GRANT execute_catalog_role TO publ_cdc;
GRANT select_catalog_role TO publ_cdc;

GRANT execute_catalog_role TO subs_cdc;
GRANT select_catalog_role TO subs_cdc;
g.       Grant execute permission on following DBMS packages to publisher and subscriber

GRANT execute ON DBMS_CDC_PUBLISH TO publ_cdc;
GRANT execute ON DBMS_CDC_SUBSCRIBE TO publ_cdc;
GRANT execute ON DBMS_LOCK TO publ_cdc; -- not mandatory

GRANT execute ON DBMS_CDC_PUBLISH TO subs_cdc;
GRANT execute ON DBMS_CDC_SUBSCRIBE TO subs_cdc;
GRANT execute ON DBMS_LOCK TO subs_cdc; -- not mandatory

h.      Make publisher as stream administrator
execute dbms_streams_auth.grant_admin_privilege('publ_cdc');
The last statement makes PUBL_CDC a streams Administrator.
Let's see if that’s really true:

SQL> select * FROM dba_streams_administrator;

USERNAME LOC ACC
------------------------------ --- ---
PUBL_CDC YES YES
i.         Make user table(s) as capture enabled tables
exec dbms_capture_adm.prepare_table_instantiation(table_name => 'ALBERT.PERSOON');
j.         Important SQL to check status on various things
                                                                           i.      Check capture enabled tables
SQL> SELECT * FROM dba_capture_prepared_tables;

                                                                         ii.      Check if change set, source table or publication is defined?
SQL> SELECT * FROM DBA_SOURCE_TABLES;
SQL> SELECT * FROM cdc_change_sets$;
SQL> SELECT * FROM cdc_change_tables$;
                                                                       iii.      Check if change set is enabled?
SQL> SELECT * FROM CHANGE_SETS;
SQL> SELECT * FROM DBA_PUBLISHED_COLUMNS;
                                                                       iv.      Check if subscription exists?
SQL> SELECT * FROM cdc_subscribers$;
SQL> SELECT * FROM user_subscriptions;
SQL> SELECT * FROM DBA_SUBSCRIPTIONS;
2)     User/Owner
a.       Create table whose changes needs to be captured
create table PERSOON
(
userid number,
name varchar(30),
lastname varchar(30),
constraint pk_userid primary key (userid)
);
               SQL> insert into PERSOON  values (1,'john','west');
                               SQL> insert into PERSOON  values (2,'mary','east');

b.      Grant select permission on the  table to publisher and subscriber

GRANT SELECT ON PERSOON TO publ_cdc;
GRANT SELECT ON PERSOON TO subs_cdc;

c.       Ensure all changes are recorded in redo logs

      ALTER TABLE persoon ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;

3)     Publisher

a.       Define CHANGE_SET, SOURCE TABLE and Publication

exec DBMS_CDC_PUBLISH.CREATE_CHANGE_SET('CDC_DEMO_SET', 'CDC Demo 2 Change Set', 'HOTLOG_SOURCE', 'Y', NULL, NULL);

b.      Create Change Table

SQL> BEGIN
DBMS_CDC_PUBLISH.CREATE_CHANGE_TABLE('publ_cdc', 'CDC_PERSOON', 'CDC_DEMO_SET',
 'ALBERT', 'PERSOON', 'userid number, name varchar(30), lastname varchar(30)',
 'BOTH', 'Y', 'Y', 'Y', 'Y', 'N', 'N', 'Y', 'TABLESPACE TS_CDC');
 END;
 /
c.       Grant Select on Change Table to subscriber

SQL> GRANT select ON CDC_PERSOON TO subs_cdc;

d.      Enable Capture on Change Table

SQL> exec DBMS_CDC_PUBLISH.ALTER_CHANGE_SET(change_set_name=>'CDC_DEMO_SET', enable_capture=> 'Y');

4)     Subscriber

a.       Create subscription to the publication

exec DBMS_CDC_SUBSCRIBE.create_subscription('CDC_DEMO_SET', 'cdc_demo subx', 'CDC_DEMO_SUB');

b.      Create subscribers view

SQL> BEGIN
 DBMS_CDC_SUBSCRIBE.subscribe('CDC_DEMO_SUB', 'ALBERT', 'PERSOON',
 'userid, name, lastname', 'CDC_DEMO_SUB_VIEW');
 END;
 /

c.       Activate subscription

exec DBMS_CDC_SUBSCRIBE.activate_subscription('CDC_DEMO_SUB');

5)     Logon to user (Albert) and make an insert –
First let’s see what is there in PRASOON table-
SQL> select * from PERSOON;

 USERID NAME LASTNAME
---------- ------------------------------ --------------
 1 john west
 2 mary east

Two records.

Now make an isert –

SQL> insert into PERSOON values (3,'harry','north');

1 row created.

SQL> commit;

connect subs_cdc/sub_cdc

Now lets see what we have and what we can retrieve from the CDC objects:

SQL> select * from PUBL_CDC.CDC_PERSOON;

OP CSCN$ COMMIT_TI XIDUSN$ XIDSLT$ XIDSEQ$ RSID$ ROW_ID$ USERNAME$
-- ---------- --------- ---------- ---------- ---------- ---------- ------------------ -------------
I 1176467 29-MAR-08 2 19 488 1 AAAMlmAAGAAAAAgAAA ALBERT

Indeed, Albert inserted 1 record, and so that information must be recorded in the Change Table CDC_PERSOON.  But we cannot see anything yet from the Subscribers View:

SQL> select * from CDC_DEMO_SUB_VIEW;

no rows selected

This is correct behavior. The Subscriber needs to use the DBMS_CDC_SUBSCRIBE.extend_window and DBMS_CDC_SUBSCRIBE.purge_window  procedures for populating and purging the view that shows the changes to Albert's PERSOON table.

                                                                           i.      So Subscriber uses following statement to populate the view
SQL> exec dbms_cdc_subscribe.extend_window('CDC_DEMO_SUB');
SQL> select * from CDC_DEMO_SUB_VIEW;

OP CSCN$ COMMIT_TI XIDUSN$ XIDSLT$ XIDSEQ$ RSID$ ROW_ID$ USERNAME$
-- ---------- --------- ---------- ---------- ---------- ---------- ------------------ -------------
I 1176467 29-MAR-08 2 19 488 1 AAAMlmAAGAAAAAgAAA ALBERT
Now here is the trick: The Subscriber should use the two forementioned procedures in a "loop" so to speak:

use DBMS_CDC_SUBSCRIBE.extend_window Be very "careful" and "disciplined"
 in using extend_window and purge_window
 use the information from the view for obvious reasons.

use DBMS_CDC_SUBSCRIBE.purge_window

If the Subscriber now purges the window, by using DBMS_CDC_SUBSCRIBE.purge_window
the view does not show entries anymore.

SQL> exec dbms_cdc_subscribe.purge_window('CDC_DEMO_SUB');

PL/SQL procedure successfully completed.

SQL> select * from CDC_DEMO_SUB_VIEW;

no rows selected
Now Albert connects again and does another insert.

connect albert/albert

SQL> select * from PERSOON;

 USERID NAME LASTNAME
---------- ------------------------------ --------------
 1 john west
 2 mary east
 3 harry north

SQL> insert into PERSOON
 2 values
 3 (4,'betty','south');

1 row created.

SQL> commit;

Commit complete.

connect subs_cdc/sub_cdc

SQL> select * from CDC_DEMO_SUB_VIEW;

no rows selected

There is nothing to view here, because the Subscriber needs to execute DBMS_CDC_SUBSCRIBE.extend_window

SQL> exec dbms_cdc_subscribe.extend_window('CDC_DEMO_SUB');

PL/SQL procedure successfully completed.

SQL> select * from CDC_DEMO_SUB_VIEW;

OP CSCN$ COMMIT_TI XIDUSN$ XIDSLT$ XIDSEQ$ RSID$ ROW_ID$ USERNAME$
-- ---------- --------- ---------- ---------- ---------- ---------- ------------------ -------------
I 1184151 29-MAR-08 10 6 511 10001 AAAMlmAAGAAAAAdAAA ALBERT

Now we are able to view the new change, that is record no 4, inserted by Albert.

Note that the Change Table does not get purged.

SQL> select * from publ_cdc.cdc_PERSOON;

OP CSCN$ COMMIT_TI XIDUSN$ XIDSLT$ XIDSEQ$ RSID$ ROW_ID$ USERNAME$
-- ---------- --------- ---------- ---------- ---------- ---------- ------------------ -------------
I 1176467 29-MAR-08 2 19 488 1 AAAMlmAAGAAAAAgAAA ALBERT
I 1184151 29-MAR-08 10 6 511 10001 AAAMlmAAGAAAAAdAAA ALBERT

Which shows the two changes from Albert since the activation of Async CDC

Now there REALLY is some sort of a "timing issue" with CDC, which you need to be very carefull of.  According to Oracle, you are supposed to use the data from the Subscribers View.
Ofcourse, you could use the information from the Change table(s), because its just another table  which you could query as usual. But that is NOT recommended.  Now, the view, or the Window, gets populated and purged. So, if you use the view(s), for example to populate Data Warehouse tables, you need to be very disciplined in using "extend_window" and "purge_window".
A "good" way of dealing with this potential problem, is in creating functions or procedures that work like

..
BEGIN
dbms_cdc_subscribe.extend_window();
..
YOUR CODE
..
dbms_cdc_subscribe.purge_window();
EXCEPTION
..
END;


Note: Above steps are for Oracle RDBMS as source. What if Source is non-Oracle RDBMS or a flat file??

Below is link implementing CDC using Informatica utilizing CheckSUM.
http://www.disoln.org/2012/12/Change-Data-Capture-CDC-Implementation-Using-CHECKSUM-Number.html