Midrange News for the IBM i Community


Posted by: Chris Proctor
Programmer Analyst
Columbia Sports Company
Portland, OR
READE reading other than expected?
has no ratings.
Published: 18 Dec 2012
Revised: 23 Jan 2013 - 2429 days ago
Last viewed on: 16 Sep 2019 (4379 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

READE reading other than expected? Published by: Chris Proctor on 18 Dec 2012 view comments(18)

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: clbirk
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 9 months 11 hours 14 minutes ago

does the file have duplicate keys?  I saw this over at publib on the READE so it really is "read"

 

For duplicate keyed files, the ILE RPG language performs a READ NEXT operation and compares the key of the returned record to determine if the record qualifies. If so, the record is returned to the program; if not, an end-of-file indication is returned. 

Posted by: clbirk
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 9 months 11 hours 13 minutes ago

one note that comment was made on DDM files, not sure if it applies to native non-ddm.

Posted by: chrisp
Premium member *
Portland, OR
Comment on: READE reading other than expected?
Posted: 6 years 9 months 10 hours 45 minutes ago

Well, the physical file isn't defined as "unique" if that's what you're referring to, but I'm not sure I'm following you. Smile

It's just supposed to be reading brand "Columbia", but it appears that it may also be reading "Sorel" which isn't a value that I'm using for the SETLL or the READE.

Posted by: Ringer
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 9 months 10 hours 3 minutes ago

> does a READ(E) for the brand

Is that just a typo? Is it really READE(E) instead? Or is that your bug? And when a record lock wait times out, usually after 60 seconds, the file cursor is still on that locked record. So you keep trying to read that locked record over and over.Yeah, the 60 second wait is BAD enough for performance but to do that in a loop is really BAD.

If you wanted to skip over it and %ERROR is *ON and %STATUS = 1218 (locked error), you'd do a READE(n) to not lock it, get past it. But this is not really want you want, the record should not be locked by the other jobs.

Chris Ringer

Posted by: chrisp
Premium member *
Portland, OR
Comment on: READE reading other than expected?
Posted: 6 years 9 months 9 hours 53 minutes ago
Edited: Tue, 18 Dec, 2012 at 15:26:26 (2465 days ago)

Hi Chris. Lol, yes it was a typo. I don't think I've explained the situation clearly enough. It just appears that even though the program should only be reading "Columbia" orders, because that's the key that's used in the READE(E), the joblog looks like it's trying to read a "Sorel", "MountainHardware", or "Montrail" record.

Each of the 4 NEPs should each be reading only one of these brands (specified in the *entry parm).

Also, I don't know that it makes a difference, but all 4 of these jobs are prestart jobs within the subsystem.

Posted by: Ringer
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 9 months 9 hours 34 minutes ago

Sounds like a bug. What is the key structure of the file? What values are the SETLL and the READE using for the keys? How are those values retrieved, via parms?

Chris Ringer

Posted by: chrisp
Premium member *
Portland, OR
Comment on: READE reading other than expected?
Posted: 6 years 9 months 9 hours 20 minutes ago

That's kinda' what I was thinking too, but one of the 4 jobs is running just fine. The key to the file is site_id and order_no (site_id is the brand). The SETLL and READE are pretty straight forward:

 

c       proc_siteid   setll(e)    I78000

c                          doueq     %eof(f78000)

c       proc_siteid   reade(e)  I78000

c                          if            %eof(F78000)

c                          leave

c                          end

c       proc_siteid    reade(e) I78000

c                           end

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: READE reading other than expected?
Posted: 6 years 9 months 9 hours 19 minutes ago

SETLL will position the file to the next highest value in the file equal to or greater than the key value.

If you are doing what some people do and replacing a CHAIN with a SETLL/READ pair, then I suspect you are seeing the following:

 

 

 /free
     myKeys SETLL theFIle;
            READ(E)   theFile;
     DOW NOT %EOF();
       // process the record
       READE(E) theFile;
     enddo;

 This would cause the situation you're seeing.

The SETLL positions the file.

The first READ (not READE) reads that first record and thus populates fields with data--wrong data, but data nonetheless.

The DOW NOT %EOF() is started, and since you did a READ instead of READE, %EOF is NOT on.

You process the first wrong record.

Read do a READE on the next record whose key is equal to that of the one returned by the READ opcode outside the DO loop.

Rinse and repeat.

Posted by: chrisp
Premium member *
Portland, OR
Comment on: READE reading other than expected?
Posted: 6 years 9 months 9 hours 4 minutes ago

Hi Bob. Thanks for the input. No, I'm not replacing a CHAIN with a SETLL/READ. This program has been around for a while, processing our ecom orders and I just think that no one has ever looked closely at how it's processing.

Basically, the read loop is only supposed to read the orders for the brand that has been passed as a parm to the process. Normally, I would have coded it like your example above, except the first read being a READE. I don't like to use DOU in most cases.

This just has me stumped because both the SETLL and READE are based on the brand parameter and there is no where in the logic where the parameter is being changed or anything like that. Too weird....

Posted by: Paulster
Premium member *
Sweden and The Netherlands
Comment on: READE reading other than expected?
Posted: 6 years 9 months 15 minutes ago

Hi Chris,

You probably already thought of this but I'll mention it anyway: If you'd bake in a bit of error handling after the READE (....if not already there...) you'd be able to debug the process and find out what's going on when the error occurs.


Seasonal greetings to y'all!

 

Regards,

Paulster

Posted by: arsenal
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 23 hours 46 minutes ago

In your example you READE file I78000, but you test the read result of file f78000. Perhaps bad copy/paste or an error in your programme.

 

How are those NEPs started and ended (think they should end sometime for back up reasons)? 

 

Regards,

Carel Teijgeler

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 21 hours 33 minutes ago

You do realize that SETLL returns %Found or %Equal and not %Eof so if Setll fails your Reade won't return %Eof, but might return %Error.

Posted by: Ringer
Premium member *
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 17 hours 1 minutes ago

I've never seen an (E) on a SETLL. It just looks odd to me. What's the purpose?

Chris Ringer

Posted by: chrisp
Premium member *
Portland, OR
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 14 hours 50 minutes ago

Thanks to everyone for the input. The way this program is written is just screwy to me. I always immediately follow my setll with a reade, but this one doesn't. I may just have to rewrite this chunk of code. The problem is, being that this is the main driving program for ecom orders, they don't want me to mess with it right now.

I'll just redo it in January. Chris, I have no idea why you'd put an (E) on SETLL either. I've never seen it. Lol.

Anyway, thanks everyone for the input, I really appreciate it. Have a Merry Christmas!

Chris

Posted by: neilrh
Premium member *
Jackson, MI
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 14 hours 20 minutes ago

The way that loop is written you're processing a record, then skipping the next. With a read at the top of the loop, followed by an if %eof-leave, you do not need the read at the bottom of the loop. You would process rcd-1, read rcd-2 (bottom of loop), then read rcd-3 and process it (top of loop).

Also worth a mention, you do have K(eyed) in the F-spec file definition. I saw one guy forget that when the file key was a numeric field and had all sorts of weird results, which we eventually traced to unkeyed reads.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: READE reading other than expected?
Posted: 6 years 8 months 29 days 13 hours 14 minutes ago

Good eye Neil.  Chris, why are you reading at the top and bottom of the DO loop?

Posted by: DaleB
Premium member *
Reading, PA
Comment on: READE reading other than expected?
Posted: 6 years 8 months 28 days 18 hours 4 minutes ago

The 2nd read at the bottom of the loop would cause you to skip every other record, but it wouldn't cause you to read the wrong records unless something in between is changing proc_siteid.

But I think everyone has missed that if you're coding the (E) extender, you should also be doing some error handling. If there was an exception, the (E) says ignore normal error handling and just return control to the program so I can handle it. You need an IF %ERROR() after the ReadE(E), and test either %STATUS() or a *STATUS subfield of the INFDS.

[On a side note, I agree SetLL(E) is not common, but it is valid. When you look at the list of Exception/Error codes, the only one that seems applicable is 01211, I/O operation to a closed file.]

Posted by: DaleB
Premium member *
Reading, PA
Comment on: READE reading other than expected?
Posted: 6 years 8 months 28 days 17 hours 54 minutes ago

And, personally, I don't like testing the loop end condition in the loop; one of the tests will always be redundant. A small restructuring of your loop avoids that:

 

c     proc_siteid   setll(e)  I78000
c     proc_siteid   reade(e)  I78000
c                   downe     %eof(f78000)
c     proc_siteid   reade(e)  I78000
c                   end

 

Unless the double read was intentional?