Error issued in READ loop: NAT3021 An invalid CID value was detected (Subcode 1)

**Hello! I’m having an error that couldn’t understand much. Already searched about it and saw 1 topic here in the forum, but I didn’t understand it much either. I have the following natural program structure:

#SP-A-INI   (A26)
  #ANO-A    (A04)
  #FILLER
#SP-A-END   (A26)
  #ANO-A    (A04)
  #FILLER
*
FOR #ANO 2018 2023
  #SP-A-INI.ANO-A := #SP-A-INI.ANO-A := #ANO
*
  READ FILE-A BY SUPER FROM #SP-A-INI TO #SP-A-END
    READ MULTI-FETCH OF 400 FILE-B BY SUPER FROM #SP-B-INI TO #SP-B-END
      READ MULTI-FETCH OF 200 FILE-C BY SUPER = FILE-B.SUPER
        IF #COUNT-REGISTER < 20
          WRITE WORK FILE 01  FILE-C.FIELD FILE-C.FIELD FILE-C.FIELD
          ADD 1   TO #COUNT-REGISTER
        END-IF
      END-READ
    END-READ
  END-READ
END-FOR

In all READ loops I have ACCEPT or IFs to validate another conditions to find the registers I need. The point where the error NAT3021 is being issued with Subcode 1 is in the line of the second READ, where FILE-B is being read, and I have no idea why this is happening.

Could anybody please help me? Thanks in advance!

Where do you set #SP-B-INI and #SP-B-END? I’m guessing that’s between the READ FILE-A and READ-FILE-B statements.

Your READ FILE-C statement is problematic. It will read FILE-C starting from SUPER = FILE-B.SUPER to the end of FILE-C. It will also read 200 records at a time but only do anything with the first 20. You need an escape bottom when the count is = 20. You should also multi-fetch 20 instead of 200 if you only use 20 records.

You might be getting the CID error because you are reading past the end of FILE-C.

1 Like

Hi Jerome!

Each one of the 3 files has their own supers. Each super is filled just before its use. It is like:

  • Fill supers for file A
    READ FILE-A BY SUPER-A FROM #SP-A-INI TO #SP-A-FIM
  • Fill supers for file B
    READ MULTI-FETCH OF 400 FILE-B BY SUPER-B FROM #SP-B-INI TO #SP-B-FIM
  • Fill super for file C
    READ MULTI-FETCH OF 200 FILE-C BY SUPER-C = #SP-B-INI
    END-READ
    END-READ
    END-READ

RC 21 means your Adabas Transaction Timer on the read of FIle-B is exhausted. You are trying to do too much (process 400 File-B records and >=80,000 File-C records) between Adabas calls.

Set your Multi-fetch factors to reasonable values, such as 10 or 20, to make Adabas calls more frequently.

1 Like

Make sure you review the logic for each loop that you are not reading needlessly through a large set of records. The code snippet for FILE-C starts a read from FILE-B.SUPER’s value, but has no ending nor ESCAPE BOTTOM clauses. As shown, it reads through the FILE-C records, counts and writes the first 20, then reads through the entire remaining FILE-C by FILE-C’s SUPER doing nothing but Adabas I/O. Remember: the READ statement is doing a logical sequential read, not a search - the “READ file-c BY super-c = x” does a read STARTING FROM x, so it will return ALL records whose super-c value is equal to x or greater than x, not just those “equal to x”.

Ralph’s suggestion that you are doing so much processing in between Adabas calls that you are timing out is indeed likely to be the root of the problem. Reducing the MULTI-FETCH factor may help, but the non-database processing you are doing between the database calls (all the code you’ve omitted from your snippet) may be the cause of the timeout.

1 Like

Hi Jerome!
Actually, I have more conditions inside each READ loop to get the records I need. There’re IFs and ACEEPTs. That’s why I can’t just ajust the multi-fetch factor to 20.

Yes, thanks Douglas! Actually I exchanged the READ for FILE-C to a FIND loop, that brings me less results. My intention with READ BY SUPER = FILE-B.SUPER was to find only the records that were equal FILE-B.SUPER… but now I understand that is not this, but from this… Thank you to you all!

The multi-fetch factor has nothing to do with your program logic. It only determines what the number of records that will be returned on a given Adabas call. Natural handles the processing of those multi-fetched records so it is transparent to your application code whether you use muti-fetch of 1 or multi-fetch of 400…unless you exceed database limits (such as the NABS/LU areas that are used to pass data buffers between the application and the database).

Multi-fetch factors of around 10 to 20 generally provide read access programs with good performance improvements with impacting the shared memory access. The multi-fetch clause should not be used if you are expecting to retrieve just a few records (e.g. less than 10). It is not a limit to how many records will be read, but a read-ahead buffer. Once the read-ahead buffer has been read by the application (Natural), the next READ will fetch the next block of records into the multi-fetch buffers.

I also suggest that you just use IF or DECIDE statements to identify the records you want to select rather than mixing IF logic and ACCEPT logic. Please review the documentation for the ACCEPT statement carefully if you choose to use ACCEPT (and/or REJECT) statements (Multiple ACCEPT/REJECT statements)

1 Like