Resolved Odd Outcome With "find"

JoseKreif

Member
The Find statement in my program does not seem to be working. The "if not avail" block will always execute thus creating a duplicate record.

However, the statement will work if I run it on it's own in the code editor.

Here is the code example

Code:
find [table] where [table].[field] = [variable] and [table].[field]  begins [variable] no-error.

    if not avail [table] then do:

      create [table].
  
      assign
        /* Assignments
            Here */
 
    end.

I'm sure it's something simple I am not seeing
 

Stefan

Well-Known Member
You've searched the knowledgebase for 'find begins'?
Which type of lock is being used? If the record is already locked (elsewhere) and the lock time out exceeds then the record will also not be available.
 

JoseKreif

Member
You've searched the knowledgebase for 'find begins'?
Which type of lock is being used? If the record is already locked (elsewhere) and the lock time out exceeds then the record will also not be available.

It should not be locked elsewhere. I don't normally use "begins", so this is a first for me experiencing the outcome of mixing it with a find.

I'm just a little confused, based on what I am seeing in the knowledgebase, Progress is suppose to return a record when a "find begins" is used, however, my program was never returning the record even when I know for a fact it's there, due to the program creating 2+ of the same record, since it kept hitting the "not avail" block.

At least things are working with my workaround
 
Last edited:

Fabio

New Member
There is a mistake in your logic.

Remove the "NO-ERROR" and post here the message that will appear.
 

JoseKreif

Member
There is a mistake in your logic.

Remove the "NO-ERROR" and post here the message that will appear.

That's not a mistake. I need that to prevent the program from crashing.

Removing it will only display the message "No Record Available".

Like I've said in the OP, however, that the statement works on it's own in the editor window.

This seems to be an issue with the "Find Begins".
 

LarryD

Active Member
It looks like it is possible that you have more than one record that satisfies the "begins". It would return "not available"

If you want to verify this condition, after your find with the begins statement:

Code:
if ambiguous [table] then do:
     message "There is more than one record that meets this criteria" view-as alert-box.
     ... do something ...
end.
else
if not avail [table] then do
 

JoseKreif

Member
It looks like it is possible that you have more than one record that satisfies the "begins". It would return "not available"

If you want to verify this condition, after your find with the begins statement:

Code:
if ambiguous [table] then do:
     message "There is more than one record that meets this criteria" view-as alert-box.
     ... do something ...
end.
else
if not avail [table] then do

I think I've tried "find First", that also lead it into the else block everytime. It's strange. Getting rid of the field begins "FooBar" and replacing with field = "FooBar" , seemed to have caused the logical error to go away.

What is your OpenEdge/Progress version?

Ancient, 10.2B on RHEL
 

Fabio

New Member
The below code was based on your logic. Run it to see what happens...

Code:
DEF TEMP-TABLE ttFruits NO-UNDO
  FIELD fruit-name AS CHAR FORMAT 'X(30)'.

DEF VAR ceFruits    AS CHAR NO-UNDO EXTENT 3 INITIAL ['Apple', 'Orange', 'Banana'].
DEF VAR yourSearch  AS CHAR NO-UNDO INITIAL 'Apple'.
DEF VAR i           AS INT  NO-UNDO.

DO i = 1 TO EXTENT(ceFruits):
  CREATE ttFruits.
  ASSIGN ttFruits.fruit-name = ceFruits[i].
END.

FIND ttFruits WHERE ttFruits.fruit-name = yourSearch
                AND ttFruits.fruit-name BEGINS yourSearch NO-ERROR.

IF NOT AVAIL ttFruits THEN DO:
  CREATE ttFruits.
  ASSIGN ttFruits.fruit-name = yourSearch.
END.

FOR EACH ttFruits NO-LOCK:
  DISPLAY ttFruits.
END.


Now, change this line:

Code:
DEF VAR yourSearch AS CHAR NO-UNDO INITIAL 'Apple'.


to:

Code:
DEF VAR yourSearch AS CHAR NO-UNDO INITIAL 'Apple '. /* Put a space after "Apple" word */


Run it again, and see what happens.
 

TheMadDBA

Active Member
Fabio wasn't suggesting that you permanently remove the NO-ERROR... just for the purpose of testing so you could see the error.

Like they have said... the difference is a FIND FIRST will only try and find the first record that satisfies the WHERE and will only throw an error if nothing matches it. Without a FIRST the query tries to make sure that only one record matches the WHERE clause. If there are 0 matches or more than 1 match it will throw an error.
 

JoseKreif

Member
Fabio wasn't suggesting that you permanently remove the NO-ERROR... just for the purpose of testing so you could see the error.

Like they have said... the difference is a FIND FIRST will only try and find the first record that satisfies the WHERE and will only throw an error if nothing matches it. Without a FIRST the query tries to make sure that only one record matches the WHERE clause. If there are 0 matches or more than 1 match it will throw an error.

Oh yes, I understand the difference. However, the Find with the begins failed reguardless.

Plus, there should never be more than 1 record with the same field, in which I'm looking for. Therefore, the "FIND" should work.

To be clear. "FIND FIRST", "FIND LAST", and "FIND" all failed with the "BEGINS"

Sorry if I didn't make it clear
 

TomBascom

Curmudgeon
There is nothing magical about FIND BEGINS.

There are only a couple of reasons for the code that you describe to fail:

1) The code that you describe is not what you are really doing. You have not posted the actual code -- I'm a cynic and a curmudgeon. I'll bet that you are doing at least one thing in your undisclosed code that makes a difference to our understanding of why your purported code is failing. 999 times out of 100 when someone posts pseudo code they leave out stuff that matters.

2) There are multiple records meeting the criteria and your FIND is ambiguous because several records meet the criteria. Yes, you claim that there "should" only be one. Use the AMBIGUOUS() function to test for that or test it with FOR EACH:

for each tableName no-lock where tableName.fieldName begins "whatever":
display tableName.
end.

if you get more than one result then the FIND is ambiguous and your "should only be one" assumption is incorrect.

3) The record is locked. Use the LOCKED() function to verify this.
 
Top