2

I am new to progress 4GL. I'm always willing to write a proper code and willing to know each end every keyword that we are using but following sample queries giving same results. I don't know when to use FIND FIRST, FOR FIRST and CAN-FIND? Please help me by re-writing with impeccable answer

FOR EACH Customer NO-LOCK:
    FOR FIRST Order OF Customer:
    /*somelogic*/
    END.
END.

FOR EACH Customer NO-LOCK:
    FIND FIRST Order OF Customer NO-LOCK NO-ERROR.
    IF AVAILABLE Order THEN
    /*somelogic*/
END.

FOR EACH Customer NO-LOCK:
  IF CAN-FIND(FIRST  Order OF Customer ) THEN
  DO:
        /*somelogic*/
  END.
END.
Bharat
  • 177
  • 7
  • 2
    If I may, here are some presentations about best practices that I found very informative : [4GL Coding Worst Practices](https://www.pugchallenge.eu/docs/default-source/presentations-2017/tom-bascom---toms-keyword-forget-list.pdf?sfvrsn=91765dc_2), [Proper & Fast Indexing](https://pugchallenge.org/downloads2014/374_Still_Dont_Know_About_Indices_PCA2014.pdf), [ABL Best Practice Programming](http://www.cintegrity.com/content/ABL-Best-Practice-Programming) (the last link seems down today) – Tom Jan 21 '22 at 10:00
  • 1
    You shouldn't use OF either. OF makes a nice demo but it is awful from a readability and code self-documentation perspective. – Tom Bascom Jan 21 '22 at 16:13

1 Answers1

5

FOR FIRST scopes the record you find to a block. It avoids having to check the availability of the record when you reference it in the block as the block won't execute if it's not available.

FIND FIRST should never really be used. You have no control over which record will be the first to be found if there are many, and if there is just one you should just use FIND without the FIRST. That way the code explains what is expected, and you can test for AMBIGUOUS to ensure someone hasn't done something silly.

CAN-FIND is used for checking if a record exists without actually pulling that record back to the client side. There will be no record available in the buffer so you can't use the data. It's an excellent way of checking if a record exists without the overhead of pulling the content back across the wire. Use it if you don't care about the data.

jdpjamesp
  • 762
  • 7
  • 19
  • 2
    FIND FIRST is occasionally useful when you really do just need to know something about the first record in an ordered set. Although that pretty much always means that someone didn't properly normalize the attribute that is making it an interesting thing to do. You are also depending on an unstated index to support your assumed ordering so FIND isn't really the best way to approach that. That's bad but the really obnoxious thing about FIND FIRST is the code bases that always glue a FIRST to every FIND. That's a horrible "worst practice" that needs to be snuffed out. – Tom Bascom Jan 21 '22 at 15:37
  • 1
    FOR scopes the record. FIRST limits the selection (it does NOT sort). You do not need FIRST to get the benefits James describes ("FOR customer NO-LOCK WHERE custNum = 1:" works just fine) and the use of FIRST is very misleading, especially if there is also a BY. – Tom Bascom Jan 21 '22 at 16:12