ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

*start setll and %found()

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • *start setll and %found()

    Working on a V7R2 box, I'm getting strange results from the following code:

    Code:
    c     *start        setll     KEYEDFILE                      
    c                   eval      ResultInd    = %found(KEYEDFILE)
    File KEYEDFILE has one record in it. I would expect indicator variable ResultInd to get value '1' from the second line of code, but it gets '0'. Am I misunderstanding the function of the *start value, or am I misunderstanding the interaction of setll and %found()? Thanks!

  • #2
    FWIW, I replaced the *start with *loval, and ResultInd was set to '1' as I expected. So apparently I'm not getting what *start does.

    Comment


    • #3
      The code doesn't make a lot of sense... what is it meant to do? Check if the file has a start?

      Comment


      • #4
        *START positions to the beginning of the file, *LOVAL positions to the lowest value for the datatype of the key field. This would make a difference if you have null capable key fields for example.

        Comment


        • #5
          Originally posted by Scott Klement View Post
          The code doesn't make a lot of sense... what is it meant to do? Check if the file has a start?
          Simply to see if the file contains any records.

          Comment


          • #6
            Originally posted by UserName10 View Post
            *START positions to the beginning of the file, *LOVAL positions to the lowest value for the datatype of the key field. This would make a difference if you have null capable key fields for example.
            The file in question has a very simple record format - one field, non-null-capable, 5 digits packed, zero decimal places, keyed unique by that field. The one record in the file has a positive value for that field. Under the circumstances, I don't understand why *START and *LOVAL are behaving differently.

            Comment


            • #7
              The manual doesn't say explicitly that *START does not set the %Found (or %Equal) indicators - but it kinda says it by omission. It specifically states that:
              • Either an error indicator (positions 73-74) or the 'E' extender may be specified.
              I'd guess that when *START is used %Found is not usable.

              Given that it is a tiny file and SETLL will only take a miniscule time less than a READ why not just read the thing - or use *LOVAL of course.

              Comment


              • #8
                Originally posted by JonBoy View Post
                Given that it is a tiny file and SETLL will only take a miniscule time less than a READ why not just read the thing - or use *LOVAL of course.
                Since the show must go on, I already replaced the *START with *LOVAL, tested, and sent the code up to QA. Like many other programmers, however, I would like to know what the compiler actually does with the code I kludge together. That way I don't end up with with stupid bugs like the one I just fixed.

                Comment


                • #9
                  *START was introduced in V4R4 to deal with problems that could arise with the use of *LOVAL. If you want to understand what those are then Junlei does a better job of it than IBM right here. https://www.mcpressonline.com/progra...by-setll-loval

                  I cannot find any IBM docs that describe the full details but ... *LOVAL is a figurative constant i.e. it represents an actual physical key/rrn. *START on the other hand is a reserved word. The implication is that while *LOVAL causes a normal keyed operation to occur, *START modifies to operation of SETLL itself and uses no key. As a result it can never fail/succeed in terms of positioning for a record. The start of the file is the start of the file regardless of whether there are any records in it or not. Consequently when you use *START %Found is meaningless.

                  Now that I've thought it all through it makes perfect sense - but IBM could do a much better job of documenting the differences.

                  P.S. I hope this is maintenance and they are not forcing you to use that nasty old fixed column stuff.

                  Comment


                  • #10
                    Originally posted by BAndrewsRTC View Post
                    Simply to see if the file contains any records.
                    That's not what it does... SETLL just changes the position of the file where the next read will take place. SETLL *START positions to the start of the file, it does not check if there are records. SETLL *LOVAL positions to wherever *LOVAL equates to. (For character keys, I think it's x'00000', for numeric it'd be -999999... or whatever the lowest possible value for the key would be.) So if you had a file with a 4,0 numeric key, you could use SETLL *LOVAL to see if a record existed with the key -9999. But this won't tell you if there are _any_ records in the file.

                    Instead, I would suggest something like this:
                    Code:
                    setll *start KEYEDFILE;
                    read(n) KEYEDFILE;
                    if %EOF;
                       // there was nothing in the file
                    endif;
                    or to match your example (using fixed format):
                    Code:
                         c     *start        setll     KEYEDFILE                      
                         c                   read(n)   KEYEDFILE
                         c                   if        %EOF
                         c** ... file is empty ..
                         c                   endif

                    Comment


                    • #11
                      With all respect, Scott, setll followed by %found() will tell you if any records in the file exist with a key >= to the one you specified. So setll *loval followed by %found() will tell you if any non-null records are in the file. I've used it for 20 years, works perfectly.
                      My mistake was expecting setll *start to behave the same way.

                      Comment

                      Working...
                      X