Saturday, August 10, 2019

Interview Question - Optimization Context

Q:what is the Optimization Context used for?
Ans: ODI uses the Optimization Context to validate your Mapping at design time.
This means it will validate your filters,functions etc. against the environment setup in your Optimization Context.

How to use Select query inside ODI 12c mapping?



Scenario:
Need to populate employee hierarchy for that technical team provided the SQL. I have to build ODI mapping for that. I decided to use SQL as it is.

Steps:
1.       Drag and Drop Target datastore twice on to the Mapping editor
2.       Select first datastore and change the alias name as “SQ”
3.       Select Second datastore and change the alias name as “TRG”

4.       Go to Physical
5.       Select “SQ” and go to property inspector and expand “Extract Options” à Go to “Custom Template” and in place value provide your SQL


6.       Connect SQ output connector to TRG input connector
7.       Enable auto map
8.       Run the mapping it load the data to Target table

Thursday, April 18, 2019

Scripts - Range & Exchange Partition

Scripts:

/* Partition Table - If it is already exists then Drop the table*/
DROP TABLE RANGE_PARTITION;

/* Create range partition per fiscal year */
CREATE TABLE RANGE_PARTITION
(ROW_WID NUMBER,
MONTH_WID DATE)
PARTITION BY RANGE(MONTH_WID)
(PARTITION P_2015 VALUES LESS THAN(TO_DATE('01-06-2016','DD-MM-YYYY')),
PARTITION P_2016 VALUES LESS THAN(TO_DATE('01-06-2017','DD-MM-YYYY')),
PARTITION P_2017 VALUES LESS THAN(TO_DATE('01-06-2018','DD-MM-YYYY')),
PARTITION P_2018 VALUES LESS THAN(TO_DATE('01-06-2019','DD-MM-YYYY')),
PARTITION P_2019 VALUES LESS THAN(TO_DATE('01-06-2020','DD-MM-YYYY')),
PARTITION P_2020 VALUES LESS THAN(TO_DATE('01-06-2021','DD-MM-YYYY')),
PARTITION P_MAX VALUES LESS THAN(maxvalue));

/* Inserting records for all the partitions */
INSERT INTO RANGE_PARTITION
SELECT LEVEL ROW_WID,
TO_DATE('31-05-2015','DD-MM-YYYY')+LEVEL MONTH_WID
FROM DUAL
CONNECT BY LEVEL < = TO_DATE('31-05-2020','DD-MM-YYYY')-TO_DATE('31-05-2015','DD-MM-YYYY');


/* Retrieving partitioning records for the fiscal year 2019 */
SELECT *
FROM RANGE_PARTITION PARTITION(P_2019);


/* Truncating the Partition*/
ALTER TABLE RANGE_PARTITION TRUNCATE PARTITION P_2019;

/* Retrieving partitioning records for the fiscal year 2019 */
SELECT *
FROM RANGE_PARTITION PARTITION(P_2019);

/* Dropping table*/
DROP TABLE PARTITION_EXCHANGE;

/* Create a new table which hold all the records related to partition 2019 fiscal year*/
CREATE TABLE PARTITION_EXCHANGE
AS
SELECT LEVEL ROW_WID,
TO_DATE('31-05-2019','DD-MM-YYYY')+LEVEL MONTH_WID
FROM DUAL
CONNECT BY LEVEL < = TO_DATE('31-05-2020','DD-MM-YYYY')-TO_DATE('31-05-2019','DD-MM-YYYY');

/* Cross Check -  all records are populated as per my partition */
SELECT MIN(MONTH_WID) , MAX(MONTH_WID) FROM PARTITION_EXCHANGE;

/* Exchange Partition with table*/
ALTER TABLE RANGE_PARTITION EXCHANGE PARTITION P_2019 WITH TABLE PARTITION_EXCHANGE;

/* After exchange partition */
SELECT * FROM PARTITION_EXCHANGE;

/* Retrieving partitioning records for the fiscal year 2019 */
SELECT *
FROM RANGE_PARTITION PARTITION(P_2019);

Example on Flatten Component - ODI 12c

To process input data with complex structure and produces the flattened representation of the same data using standard datatypes

Scenario:
Input Data:

Output Data:

Scripts:

CREATE OR REPLACE TYPE node AS TABLE OF VARCHAR2(30);
/
CREATE TABLE nested_table (id NUMBER, NodeName node)
       NESTED TABLE NodeName STORE AS NodeName_tab;
/
INSERT INTO nested_table VALUES (1, node('A'));
INSERT INTO nested_table VALUES (2, node('B', 'C'));
INSERT INTO nested_table VALUES (3, node('D', 'E', 'F'));
COMMIT;
/
SELECT * FROM nested_table;


ODI Steps:
-------------

1. Create Mapping
2. Drag and drop source data store (NESTED_TABLE) from source model.
3. Drag and drop flatten component from component palette into mapping editor
4. Drag and drop Target data store (CONVERTED_NESTED_TABLE) from target Model
5. Connect output connector of flatten component to input connector of Target data Store
6. Connect output connector of Source data store to input connector of flatten Component as mentioned below
7. Map ID column from source data store to Flatten component directly
8. Map Node Column as mentioned below


9. Select complex attribute type as mentioned below on flatten component


10. Execute it

Output:

Saturday, February 16, 2019

How to bypass procedure the step in ODI 11g?

Scenario:
Based on the option value I need to execute that step or skip that step.

Example:
IKM whenever we select create target table true then only target table will be created. Similar functionality even we can provide to procedure as well.

Process:


  1. Create an option for an procedure
  2. Disable always execute option as mentioned below:

and select SKIPSTEP option
      3. Option value is True. So that I will skip that step



How to trigger scenario from jython code in ODI?

Triggering Scenario from Jython code:

In this example I am consider all the scenario's whose name starts with SCN_INT.
Path provided here is where standalone agent is installed in my machine. You have to specify according to your machine.

Note: If it is windows make sure that your using '\\' instead of '\' in the path
Oracle won't recommends using directly metadata tables in your script. It is just for your information.


import java.util.Date as Date
from com.ziclix.python.sql import zxJDBC
import java.sql as sql
import os
import thread

def ins(path):
os.chdir("D:\\SoftwareInstalled\\Oracle\\Middleware\\Oracle_ODI\\oracledi\\agent\\bin")
list=os.system(path)

URL = "<%=odiRef.getInfo("SRC_JAVA_URL")%>"
userName = "<%=odiRef.getInfo("SRC_USER_NAME")%>"
password = "<%=odiRef.getInfo("SRC_PASS")%>"
Driver = "oracle.jdbc.driver.OracleDriver"

myCon = sql.DriverManager.getConnection(URL,userName,password)
myStmt = myCon.createStatement()

sqlQry = "SELECT SCEN_NAME,SCEN_VERSION FROM DEV_ODI_REPO.SNP_SCEN WHERE SCEN_NAME LIKE 'SCN_INT%'"

jobRs = myStmt.executeQuery(sqlQry)

while (jobRs.next()):
path = 'startscen.bat '+jobRs.getString("SCEN_NAME")+' '+jobRs.getString("SCEN_VERSION")+' GLOBAL'
thread.start_new_thread(ins,(path,))
myCon.close()











How to connect to Oracle DB and raise user defined exception using Jython from ODI ?

Jython Code: In this example I am just connecting to DB and raising an user exception

For this you have to create a procedure and copy below code on target on command and on source on command you have to select corresponding logical schema and database to which you want to connect.

import java.util.Date as Date
from com.ziclix.python.sql import zxJDBC

# Getting credentials using API's
URL = "<%=odiRef.getInfo("SRC_JAVA_URL")%>"
userName = "<%=odiRef.getInfo("SRC_USER_NAME")%>"
password = "<%=odiRef.getInfo("SRC_PASS")%>"

#Driver we are using to connect to Database
Driver = "oracle.jdbc.driver.OracleDriver"

#Connecting to database
db = zxJDBC.connect(URL,userName,password,Driver)
c = db.cursor()

sqlQry = "SELECT TO_TIMESTAMP(TO_CHAR(SYSTIMESTAMP,'dd/mm/yyyy hh24:mi:ss'),'dd/mm/yyyy hh24:mi:ss') ,  TO_TIMESTAMP(TO_CHAR(SYSTIMESTAMP+2,'dd/mm/yyyy hh24:mi:ss'),'dd/mm/yyyy hh24:mi:ss') FROM dual"

#Executing the query
c.execute(sqlQry)

#Fetching values
for cur in c.fetchall():
time1 = cur[0].time()
time2 = cur[1].time()

        #Raising user defined exception to the check values in operator
if (time1 <= time2):
try:
raise ValueError("Time1:"+str(time1)+" Time2:"+str(time2))
except:
raise
db.close()
else:
try:
raise ValueError("Time1:"+str(time1)+" Time2:"+str(time2))
except:
raise
db.close()