Looping in Buildop

Post questions here relative to DataStage Enterprise/PX Edition for such areas as Parallel job design, Parallel datasets, BuildOps, Wrappers, etc.

Moderators: chulett, rschirm, roy

Post Reply
pjsimon
Participant
Posts: 12
Joined: Mon Mar 28, 2005 4:18 pm

Looping in Buildop

Post by pjsimon »

Hello,
I'm trying to write a buildop for the following requirement........I have an input stream which has 2 columns

ProdID
ProdName

and I also have a rules reference table which has

ColumnNumber
Trigger
Value

suppose the rules reference table has values
colNum , Trigger , Value
1 , 2345 , 4567
2 , Marlboro , Marl Lights

For each and every record in the input stream......

The ProdID should take 4567 if its equal to 2345
and ProdName should take Marl Lights if it is equal to Marlboro....

I put together the following code for the buildop.......

Code: Select all

#include <string.h>
#include <stdio.h>

APT_String V_ProdID;
APT_String V_ProdName;


readRecord(0);
readRecord(1);


while (!inputDone(0))

{

V_ProdID = S1.ProdID;
V_ProdName = S1.ProdName;

while (!inputDone(1))
 {

  if (L1.ColumnNumber==1)
   { 
   if (L1.Trigger==S1.ProdID)
     V_ProdID = L1.Value;   
   }

else if  (L1.ColumnNumber==2)
   {  
   if (L1.Trigger==S1.ProdName)
     V_ProdName = L1.Value;
   }

readRecord(1);

 }

Output.ProdID = V_ProdID;
Output.ProdName = V_ProdName;

transferAndWriteRecord(0);
readRecord(0);
readRecord(1);

}
endLoop();
Problem:

The logic works only for the first record.......cos the second while loop in the code executes only once.......Is there a way to make the second loop run for each and every input record??????........

we are using DS 7.5.1A...........I welcome suggestions for doing outside of the buildop too......

Appreciate the help...

Thanks
PJSimon.
pneumalin
Premium Member
Premium Member
Posts: 125
Joined: Sat May 07, 2005 6:32 am

Try the lookup stage

Post by pneumalin »

pjsimon,
This is perfect case to use lookup stage. Try it and let me know how it goes!
pjsimon
Participant
Posts: 12
Joined: Mon Mar 28, 2005 4:18 pm

Post by pjsimon »

pneuma,
The key for the rules reference table is ColumnNumber and key for the input stream is virtual........which is the column number.......Can u plz give more info on how to go a'bt doing it???
Rajesh_kr82
Participant
Posts: 24
Joined: Sat Oct 15, 2005 1:09 pm

Post by Rajesh_kr82 »

Did you get any soultion for this issue. I am also in the same problem.
Regards,
Rajesh
pneumalin
Premium Member
Premium Member
Posts: 125
Joined: Sat May 07, 2005 6:32 am

Post by pneumalin »

pjsimon wrote:pneuma,
The key for the rules reference table is ColumnNumber and key for the input stream is virtual........which is the column number.......Can u plz give more info on how to go a'bt doing it???
pjsimon,
Did you get it resolved yet?
If I understand your requirement correctly, I would lookup the reference table Twice using the Key: Trigger instead of ColumnNumber for each single Input record. One for ProdID, and the other for ProdName...
You can then determine if the matches(ProdID<->Trigger, ProdName<->Trigger) found or not..

Hope this help!
Rajesh_kr82
Participant
Posts: 24
Joined: Sat Oct 15, 2005 1:09 pm

Post by Rajesh_kr82 »

Actually this is not about data or something. It is just that for each and every record in the primary source, i need to look up values in some other source. If you see in the code it is done in the secound while loop. But you cannot loop through the other dataset more then once. I am facing the same problem.

I tried to look at the code being generated and i found that the getRecord() method returns false each time. This is bacause cursor has reached the end of file. There should be some way to set this cursor back to record 1 and the parameter APT_Bop_inputDone[INPUT] to false. I got this stuff from the generated code.

rajesh
Regards,
Rajesh
benny.lbs
Participant
Posts: 125
Joined: Wed Feb 23, 2005 3:46 am

Re: Looping in Buildop

Post by benny.lbs »

Does the reference table large ?????

If it is not large, try to use vector to build up an internal table (in Pre-Loop), then loop with vector.
pjsimon wrote:Hello,
I'm trying to write a buildop for the following requirement........I have an input stream which has 2 columns

ProdID
ProdName

and I also have a rules reference table which has

ColumnNumber
Trigger
Value

suppose the rules reference table has values
colNum , Trigger , Value
1 , 2345 , 4567
2 , Marlboro , Marl Lights

For each and every record in the input stream......

The ProdID should take 4567 if its equal to 2345
and ProdName should take Marl Lights if it is equal to Marlboro....

I put together the following code for the buildop.......

Code: Select all

#include <string.h>
#include <stdio.h>

APT_String V_ProdID;
APT_String V_ProdName;


readRecord(0);
readRecord(1);


while (!inputDone(0))

{

V_ProdID = S1.ProdID;
V_ProdName = S1.ProdName;

while (!inputDone(1))
 {

  if (L1.ColumnNumber==1)
   { 
   if (L1.Trigger==S1.ProdID)
     V_ProdID = L1.Value;   
   }

else if  (L1.ColumnNumber==2)
   {  
   if (L1.Trigger==S1.ProdName)
     V_ProdName = L1.Value;
   }

readRecord(1);

 }

Output.ProdID = V_ProdID;
Output.ProdName = V_ProdName;

transferAndWriteRecord(0);
readRecord(0);
readRecord(1);

}
endLoop();
Problem:

The logic works only for the first record.......cos the second while loop in the code executes only once.......Is there a way to make the second loop run for each and every input record??????........

we are using DS 7.5.1A...........I welcome suggestions for doing outside of the buildop too......

Appreciate the help...

Thanks
PJSimon.
Rajesh_kr82
Participant
Posts: 24
Joined: Sat Oct 15, 2005 1:09 pm

Post by Rajesh_kr82 »

I talked to Ascential Support and was told that it is not possible to go through the secondry datasource again and again using the code. Hence this code will not work.
Regards,
Rajesh
Abid
Participant
Posts: 6
Joined: Mon Feb 12, 2007 1:02 am

Post by Abid »

I have similar code from buildop:

struct gui_rec {
int win_id;
string app_name;
string exe;
string win_title;
string rule1;
string rule2;
int type;
} gui_array[5000];

int rcnt=0;
readRecord(1);
while (!inputDone(1))
{
gui_array[rcnt].win_id=InLkp.WINDW_ID;
gui_array[rcnt].app_name=InLkp.APP_NAME;
gui_array[rcnt].exe=InLkp.EXE;
gui_array[rcnt].win_title=InLkp.WINDW_TITLE_TEXT;
gui_array[rcnt].rule1=InLkp.RULE1;
gui_array[rcnt].rule2=InLkp.RULE2;
gui_array[rcnt++].type=InLkp.TYPE;
readRecord(1);

}

Here as well,I am facing the issue as input has 2463 records but when checked "rcnt" comes to 1231 only.That's half of actual value.
Abid
Participant
Posts: 6
Joined: Mon Feb 12, 2007 1:02 am

Post by Abid »

Done...its been solved...

As pjsimon wrote,
The logic works only for the first record.......cos the second while loop in the code executes only once.......Is there a way to make the second loop run for each and every input record??????........


In DS job,in BuildOp stage,change execution mode to "Sequential".
and it takes all the records as needed.
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

You could have pre-read input port #1 into a static vector, as was suggested; you can then access this as often as you wish. For better performance, use a hash table rather than a vector - a bit more coding, but probably worth it.
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
Post Reply