Looping in BizTalk - oracle

On an Oracle database I got a customer table with at Id and Name and so, and a number of customerstuff tables all related a key.
With the Oracle WCF adapter in BizTalk a need to create a file with all the customers and there stuff
Like this:
<Root>
<Customers>
<Customer>
<Id>1</Id>
<Name>A</Name>
<Stuff1>
<data>
.
.
</data>
</Stuff1>
.
.
<Stuff6>
<data>
.
.
</data>
</Stuff6>
</Customer>
<Customer>
<Id>2</Id>
<Name>B</Name>
<Stuff1>
.
.
.
</Stuff6>
</Customer>
</Customers>
</Root>
I started out with a select of all the customers, and in Orchestration I loop over them, selecting from each customerstuff table with the key from the current customer getting me all the data ready for the first customer node in the result file.
Question: how do I build the result file? I have to add the current customer/customerstuff data to the result file, then do a new loop while still holding on to the result file, how can I do that in BizTalk ?

This may be possible with custom XSLT, but I am unsure without seeing more detail about the input and output schemas.
If you go with the looping approach, this is going to require 3 messages
Output Message (your eventual output)
Current Output Placeholder Message (same schema as your eventual output)
Customer Stuff (the data you want to Append to output on a given pass through the loop)
and a map that has two messages to one (or some XPATH based manipulation):
For Each Customer
Create "Customer Stuff"
Copy Output Message to Current Output Placeholder
Perform Map that takes Customer Stuff and Current Output Placeholder Message as input and maps to the "Output Message"

Try using something similar to "for xml" in sql server, when you read the data itself using query or stored procedure. In oracle you can return the result set as xml using dbms_xmlgen package:
select dbms_xmlgen.getxml('select * from emp where rownum <= 2') xmlstr from dual;

Related

Counting the number of tags in input XML file using talend

I am reading the data from XML file using tFileInputXML.Each row of data is present in the one element like <data columnName="[value]"/>. I want to count number of data tag in the XML using Talend tool. If there are more than one tag then only i want to proceed the operation of inserting to table.How can i achieve this is talend.
Try tFileInputXML->tJavaRow->tHashOutput
In tJavaRow, add 1 to a global var for each row.
Now you can a subjub (onSubjobOk) with tJava->if->tOracleOutput (or other).
For the "if" the condition should look like (Integer)globalMap.get("yourVariable") > 1
Hope this helps
TRF

Tibco BusinessWorks 6 Parsing CSV File

I am trying to parse a CSV file as an input for my process.
I used the FilePoller to detect any changes, made in the .csv file. The poller is connected to the ParseData Activity which is referenced by the DataFormat Ressource, where I am defining the structure of my data. The output of ParseData is used in the RenderXML activity to create an xml string.
I am facing the issue, that I am not able to loop through each line in the CSV file to parse it to an XML document structure.
Do you have a resolution, how to implement this?
Please find the "Demo" process attached to this post.
Link to Process
Thank you in advance
Adrian
Select both the RenderXml and WriteFile activities. You can do that by clicking one, and then holding the Shift button while you click on the second.
Right-click over the selected activities, and select Create Group > Iterate. This will create an Iterate Scope around the two selected activities.
Click on the Properties panel and select the output of the ParseData activity as the Variable List through which you would like to iterate.
I hope this helps!
As per my understanding you are getting repeated element in Parse Data Output and these repeated element you want to map to render xml schema . Which is not allowed until and unless in schema you have element to which you want to map is of repeated type. If that element is of repeated type then map element from the right side to left side and select for each option. Then for every element in Parse data it will map to schema element.
Hope Your doubt get resolved.

ODI 12c DB to XML

I am trying to map oracle db to an XML file and have come to a blocker.Would appreciate any help.My xml file has the following structure
<Root>
<Import>
<Add-Item1>
.
.
<Add-Item n></Add-Item n>
</Import>
Odi 12c xml driver generates a ParentElementFK CurrentElementPK and CurrentElementOrder,corresponding to every tag that is there in xml.
My issue is in spite of scouring oracle forums i have not found a good definition of what data we need to populate in these ODI generated columns. Are these only for maintaining the hierarchical relationship?if so,wouldn't they be populated automatically on reverse engineering?.suppose the data that i would fill in this xml structure would be of an item with properties-brand,description item id(child tags under ) .Do these generated columns play any role in the mapping?
I have tried multiple things and found the answer myself . here is what i understood. Suppose you have Import complex type and Add-Item complexType . It will generate two datastores in model one for Import and one for Add-Item. First populate the primary key of the Import Complex type. Then you will see IMport FK in the Add-item complex type populate this value with the same value as you populated above that works . All other order and can be left optional if you don't need any particular order of these

DB Insert if not present - Spring Integration

We have a int-jms:message-driven-channel-adapter --> a transformer --> a filter --> another transformer --> int-jdbc:outbound-channel-adapter (to insert in table_1)
(considering --> as channels)
I want to change this flow to insert into 2 tables instead of 1 but for table_2 I want to insert only if data corresponding to some fields in the message is already not present in the table i.e. insert if not present.
One thing I figured is that I will now need a pub-sub-channel with ignore-failures=false to split the flow into 2 tables.
My question is that what component should I use to select the data to check if data exists in table_2? I first thought inbound-channel-adapter is the right choice but couldn't figure out how to slide it between 2 components i.e. say a transformer and outbound-channel-adapter.
Some things I can think of are:
1. Use a filter, passing it jdbcTemplate so that the filter itself can fire a JDBC query to accept if record doesn't exist.
2. Use a outbound-channel-adapter and the insert query should have the check for data existence also, something like insert-if. I am not sure if Oracle has something like this. I am researching.
Please point me to an example or documentation or tell me the best way.
Thanks
Actually you can use
<chain>
<header-enricher>
<header name="original" expression="payload"/>
</header-enricher>
<int-jdbc:outbound-gateway query="SELECT count(*) from TABLE where ..."/>
<filter expression="payload == 0"/>
<transformer expression="headers.original"/>
</chain>
From other side <filter> with JdbcTemplate direct usage is good choice too.
Re. insert-if. It can work too if you have a unique constraint on the table. In this case an Exception will be thrown. And if you have <publish-subscribe-channel ignore-failures=false>, it would work too.

How to sort a list so that managers are always ahead of their subordinates (How do I do a topological sort in Groovy, or an FP language)

I am working on a project using Groovy, and I would like to take an array of employees, so that no manager follows their subordinates in the array. The reason being that I need to add people to a database and I would prefer not to do it in two passes.
So, I basically have:
<employees>
<employee>
<employeeid>12</employeeid>
<manager>3</manager>
</employee>
<employee>
<employeeid>1</employeeid>
<manager></manager>
</employee>
<employee>
<employeeid>3</employeeid>
<manager>1</manager>
</employee>
</employees>
So, it should be sorted as such:
employeeid = 1
employeeid = 3
employeeid = 12
The first person should have a null for managers.
I am thinking about a binary tree representation, but I expect it will be very unbalanced, and I am not certain the best way to do this using Groovy properly.
Is there a way to do this that isn't going to involve using nested loops?
http://en.wikipedia.org/wiki/Topological_sorting
Assuming that each employee other than the CEO has exactly one manager, I would insert all of the employee records into an associative structure that maps each employee ID to a list of their direct reports. Now we call the following recursive procedure on the CEO:
def recursiveinsert(e):
insert e into the database
for each direct report d of e:
recursiveinsert(d)

Resources