Welcome to All Things Data Integration: Announcements, Insights, Best Practices, Tips & Tricks, and Trend Related...

ODI 11g - Dynamic and Flexible Code Generation

David Allan

ODI supports conditional branching at execution time in its code generation framework. This is a little used, little known, but very powerful capability - this let's one piece of template code behave dynamically based on a runtime variable's value for example. Generally knowledge module's are free of any variable dependency. Using variable's within a knowledge module for this kind of dynamic capability is a valid use case - definitely in the highly specialized area.

The example I will illustrate is much simpler - how to define a filter (based on mapping here) that may or may not be included depending on whether at runtime a certain value is defined for a variable. I define a variable V_COND, if I set this variable's value to 1, then I will include the filter condition 'EMP.SAL > 1' otherwise I will just use '1=1' as the filter condition. I use ODIs substitution tags using a special tag '<$' which is processed just prior to execution in the runtime code - so this code is included in the ODI scenario code and it is processed after variables are substituted (unlike the '<?' tag).

 So the lines below are not equal ...

  • <$ if ( "#V_COND".equals("1")  ) { $> EMP.SAL > 1 <$ } else { $> 1 = 1 <$ } $>
  • <? if ( "#V_COND".equals("1")  ) { ?> EMP.SAL > 1 <? } else { ?> 1 = 1 <? } ?>

When the <? code is evaluated the code is executed without variable substitution - so we do not get the desired semantics, must use the <$ code. You can see the jython (java) code in red is the conditional if statement that drives whether the 'EMP.SAL > 1' or '1=1' is included in the generated code. For this illustration you need at least the ODI release - with the vanilla release it didn't work for me (may be patches?). As I mentioned, normally KMs don't have dependencies on variables - since any users must then have these variables defined etc. but it does afford a lot of runtime flexibility if such capabilities are required - something to keep in mind, definitely.

Join the discussion

Comments ( 8 )
  • Uli Bethke Tuesday, December 11, 2012

    Hi David.

    This is great stuff. Thanks for sharing. Couple of questions:

    - Is this documented anywhere?

    - Is this used in any of the out of the box KMs?

    This is really handy if you write a lot of Java code and rather than hand coding connections to the database to retrieve a vaule you could just use an ODI variable to do some.

    The <$ $> prints itself to the Operator. However, you need to use the full syntax. So <$="Stuff"$> won't work but <$ out.print("Stuff"$> will

  • guest Tuesday, December 11, 2012

    Actually this stuff was possible before in the <@ @> parse phase.

    However, it's nice that at the <$ $> stage it now prints out to the Operator

  • David Tuesday, December 11, 2012

    Hi Uli

    Yeh it was added in order to set the task name at runtime, and be able to see the code in the operator (and have variables substituted which is a nice bonus).

    There is an example in the documentation, but not much (ummm nothing on the meaning of the tags really);

    Some examples are included such as below, and the description gives a hint about it 'This method sets the name of a task to the taskName value. This value is set at run-time'. Runtime being the key word, because of the <$ tags.

    <$=odiRef.setTaskName("Create Error Table " + "<%=odiRef.getTable("L","ERR_

    NAME","W")%>") $>

    <$=odiRef.setTaskName("Insert Error for " + "<%=odiRef.getFK("FK_NAME")%>") $>

    <$=odiRef.setTaskName("Loading " + "<%=odiRef.getTable("L", "COLL_NAME", "W")%>" +

    " from " + "<%=odiRef.getSrcTablesList("", "RES_NAME", ",", ".")%>" ) $>



  • David Hecksel Saturday, January 5, 2013


    Nice post!

    Have you seen any use of that tag for "additional debug" capability since the output is automatically put in Operator? Perhaps "breadcrumb" trails in Operator?

  • Bhabani Thursday, January 10, 2013

    Thats great David. I got redirected to this post by looking the reply on OTN yesterday.I gave one alternative for this question in OTN https://forums.oracle.com/forums/thread.jspa?threadID=2483436 as i had no direct solution (i was unaware of above flexibility). But this <$$> solved everything.

    Thanks for sharing.

  • Hamid Monday, July 29, 2013

    Hi David,

    I have been trying to use the same technique to dynamically inject variable values when calling OdiStartScen. My situation is that I have a control table and a package that reads the table looking for jobs (scenarios) to run. Since my scenarios can have different input parameters I have a variable that it self holds the variables to be passed to the OdiStartScen for example #RESOURCE_VARIABLE containing value "-PROJ.START_DT=#SRC_START_DT" "-PROJ.END_DT=#SRC_END_DT". A code similar to what you have used i.e. <$ out.print("#RESOURCE_VARIABLE"); $> results in a "Error during task interpretation" message.

    Any thoughts or pointers how would it be possible to dynamically print the variable value in a OdiRunScenario command.

    Thanks in advance.

  • David Tuesday, July 30, 2013

    Hi Hamid

    There are two parts; one is to execute the scenarios, driving that processing from your table, you can use OdiStartScen for example for that, identify the scenario name. The other is to supply the inputs, the inputs will be setup by configuring the dependent variables, you can set or refresh the variables to the values you want prior to executing the screnario.



  • guest Tuesday, July 30, 2013

    Hi Hamid

    Something else that may be useful, to execute the latest scenario version, you can use -1 as the version number, see the post below;




Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.