Locate Statement not Searching Whole Array in a Routine

Post questions here relative to DataStage Server Edition for such areas as Server job design, DS Basic, Routines, Job Sequences, etc.

Moderators: chulett, rschirm, roy

Post Reply
kenstorm
Premium Member
Premium Member
Posts: 40
Joined: Mon Oct 16, 2006 2:33 pm

Locate Statement not Searching Whole Array in a Routine

Post by kenstorm »

Hello all,

It is my understanding that the Locate statement can search an array. In order for me to use it in a routine, I have to specify a position. Well that defeats the purpose. Shouldn't it search by field? Otherwise, I have to spin it thru a loop and read one position at at time looking for a certain value.

Here's what I would like to do:
Locate '172' IN ParentArray SETTING X
Else ParentArray(New_No) = '172'

Here's what I have to do now:
FOR 1 to Index_No
Locate '172' IN ParentArray(Index_No) SETTING X
Else ParentArray(New_No) = '172'
NEXT
Regards - Ken Breetz

Keep me in the circle of trust
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

LOCATE will search at the field OR value OR subvalue level.

The syntax required to search at each level is different - you must specify the higher-level element (for example you may wish to search through the values in field #5).

Further you may not always want to search from the first element. If you've just found what you're looking for in the 7th element, you may want to search again from there.

LOCATE does not search dimensioned arrays AT ALL (your code suggests that you believe that it does). LOCATE searches dynamic arrays. For dimensioned arrays you DO have to "spin it through a loop and read one position at a time". Or you could use MATPARSE and MATBUILD statements to convert between dimensioned and dynamic arrays.

What, precisely, do you wish to achieve? What is the dynamic array delimiter (field mark, value mark)?

If you are using a field-mark-delimited dynamic array your syntax should be

Code: Select all

LOCATE "172" IN ParentArray Setting WhereFound
ELSE
   ParentArray<-1> = "172"  ; * append new field
END
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
kenstorm
Premium Member
Premium Member
Posts: 40
Joined: Mon Oct 16, 2006 2:33 pm

Post by kenstorm »

At this point, I would just like to get the Locate statement to work with any array. The Datastage help does not seem to be helpful.

Locate '172' IN '172,200,201,200,202' SETTING Ans
Else Ans = 'Not Found'

This is what I would like to get to work.
Regards - Ken Breetz

Keep me in the circle of trust
ArndW
Participant
Posts: 16318
Joined: Tue Nov 16, 2004 9:08 am
Location: Germany
Contact:

Post by ArndW »

The LOCATE statement works with DataStage dynamic arrays. The elements of these are separated by certain characters, @FM, @VM, @SM and @TM for the 4 different levels. The comma you are using is not one of these, which is why the statement isn't working as you expect. Try

Code: Select all

   WorkString = "123,456,789,012,345,678"
   DynamicArray = CONVERT(",",@FM,WorkString)

** or you could use the following 2 lines instead:
** DynamicArray = WorkString
** CONVERT "," TO @FM IN DynamicArray

   LOCATE '789' IN DynamicArray SETTING Pos ELSE Pos = 0
kenstorm
Premium Member
Premium Member
Posts: 40
Joined: Mon Oct 16, 2006 2:33 pm

Post by kenstorm »

Ray/Arnold,

Thanks for your help. javascript:emoticon(':D')
Very Happy

I didn't realize I needed to use convert. It works great now!

Here's the code that I am using in the routine:

Equate SearchString To Arg1
Equate InputArray To Arg2

BubbleCount = Dcount(InputArray,'|')
Convert '|' to @FM in InputArray

FOR FieldPos = 1 To BubbleCount

Party_Pair = Field(InputArray, @FM, FieldPos)

IF FieldPos = 1 Then
AOW_Pty = Field(Party_Pair, ',', 1)
ParentArray = Field(Party_Pair, ',', 1)
END

IF FieldPos = 1 Then
ChildsArray = Field(Party_Pair, ',', 2)
END

IF FieldPos > 1 Then
ParentArray = ParentArray:',':Field(Party_Pair, ',', 1)
ChildsArray = ChildsArray:',':Field(Party_Pair, ',', 2)
END

Next FieldPos

Convert ',' to @FM in ParentArray
Locate SearchString IN ParentArray SETTING Ans
Else Ans = 'Not a Parent'
:D
Regards - Ken Breetz

Keep me in the circle of trust
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

So you have a delimited string of the form x1,y1|x2,y2|x3,y3|... and you want to determine whether x2 exists in it?

You can do this with a single FIND statement.

Code: Select all

FIND Arg1 IN Convert("|,",@FM:@VM,Arg2) SETTING FMC,VMC,SMC 
Then
   Ans = FMC
End
Else
   Ans = "Not found"
End
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
kenstorm
Premium Member
Premium Member
Posts: 40
Joined: Mon Oct 16, 2006 2:33 pm

Post by kenstorm »

Whaah? The FIND Statement? Is that in the Basic.pdf? I went lookin' for it and didn't 'find' it. Is that something Ascential hid from us? It looks very similar to the Locate statement.

Your example is exactly dead on. That is what I am trying to do. x2 would be the parent and y2 would be the child. Some parents can also be a child. I am doing a sort of pecking order. Think of it like a Great-Grandfather with a large family at a banquet. I need to decide who eats first then second and so on. The Great-Grandfather would eat first then his direct children then their children. The only trick is to keep the line in order by direct relation. Like the mother's side all in line together right down to the youngest. Then behind the youngest, would be the oldest of another chain of relatives. This is the most complex chunk of code I've ever written. Thanks for your help.
Regards - Ken Breetz

Keep me in the circle of trust
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

Yep, right there between FILEUNLOCK and FINDSTR (the latter is like FIND but can perform a partial match - VERY handy sometimes). Page 6-243 in my BASIC manual (version 7.5) but easily found through the index.

LOCATE searches at one level, FIND and FINDSTR at three. You have two, so FIND was more appropriate - you just ignore the third level.
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