2

I have an own application where you can simulate a library (customer can lend and return books).

I have a LOAN file where I store the book-id, customer-id, loan-date and return-date for each loan.

This is my file select:

           SELECT LOAN-FILE
               ASSIGN TO "LOANS"
               ORGANIZATION IS INDEXED
               RECORD KEY IS LOAN-ID 
               ALTERNATE KEY IS LOAN-CUSTOMER WITH DUPLICATES
               ALTERNATE KEY IS LOAN-BOOK
               ACCESS MODE IS DYNAMIC.

This is the structure of my loan file:

       FD LOAN-FILE
       LABEL RECORDS ARE STANDARD.
       01 LOAN-RECORD.
           05 LOAN-ID PIC 9(5).
           05 LOAN-CUSTOMER PIC 9(5).
           05 LOAN-BOOK PIC 9(5).
           05 LOAN-DATE PIC 9(8).
           05 LOAN-RETURN-DATE PIC 9(8).

I am trying to read the file using the alternate key LOAN-CUSTOMER:

       READ-LOAN-DATA.
           MOVE "N" TO LOAN-FILE-AT-END.

           START LOAN-FILE
               KEY NOT < LOAN-CUSTOMER
               INVALID KEY 
                   MOVE "Y" TO LOAN-FILE-AT-END.
           
           IF LOAN-FILE-AT-END NOT = "Y"
              PERFORM READ-NEXT-LOAN-DATA.

       READ-NEXT-LOAN-DATA.
           READ LOAN-FILE NEXT RECORD 
               AT END 
                   MOVE "Y" TO LOAN-FILE-AT-END.

I am using that procedures in this procedure:

       FIND-LENT-BOOKS-OF-CUSTOMER.
           PERFORM READ-CUSTOMER-DATA.
           PERFORM DISPLAY-CUSTOMER-DATA.
           PERFORM INIT-DATA. 
           MOVE CUSTOMER-ID TO LOAN-CUSTOMER.
           DISPLAY "Loan customer before calling READ-LOAN-DATA " 
               LOAN-CUSTOMER.
           PERFORM READ-LOAN-DATA
               UNTIL LOAN-FILE-AT-END  = "Y".
           PERFORM DISPLAY-LOAN-DATA.

The problem is that I can not read my LOAN file. If I comment out the INVALID-KEY of my START statement then I am getting the error: record key does not exist for the file LOAN-FILE.

In another COBOL program I can read my LOAN file using the primary key LOAN-ID. It also displays the LOAN-ID and LOAN-CUSTOMER. But here I want to use LOAN-CUSTOMER as alternate key with duplicates and it is not found when I have entries in my loan file.

I am using COBOL on a Linux Mint virtual machine. I have installed Visual Studio Code as text editor and as cobol compiler I am using GNU Cobol 3.1.2.0.

So my cobol setup is simple. I am new to COBOL and I don't have any experience with JCL or VSAM files.

What is wrong with my code ? I tried an example from a tutorial "Teach yourself Cobol in 21 days" http://testa.roberta.free.fr/My%20Books/Mainframe/Cobol/Teach%20Yourself%20Cobol%20In%2021%20Days%20(2nd%20Ed).pdf (page 445 - 450) and it worked without any problems (this code is different). I also tried an implementation similiar to the one of the tutorial and the error also occurs in that implementation.

So why does it not read my alternate key from my LOANS file and how can I get this to work with my data file (in my own implementation) ?

eisem
  • 185
  • 1
  • 10

2 Answers2

2

I think you have a logic error here:

           PERFORM READ-LOAN-DATA
               UNTIL LOAN-FILE-AT-END  = "Y".

So just from that: you will always read the file until its end. I guess you want to do something along DISPLAY-CUST-LOAN and within that have a loop of READ NEXT and PERFORM DISPLAY-LOAN-DATA.

Then, from your note:

           START LOAN-FILE
               KEY NOT < LOAN-CUSTOMER

Is possibly not what you want, but instead

           START LOAN-FILE
               KEY >= LOAN-CUSTOMER

with an additional check in your read loop of

           IF LOAN-CUSTOMER NOT = DATA-CUSTOMER
              MOVE "Y" TO LOAN-FILE-AT-END

Side note: Style issue: instead of having many paragraphs and setting/query an additional file attribute you could use an inline perform:

      HANDLE-CUSTOMER-ENTRIES SECTION.
           START LOAN-FILE
               KEY >= LOAN-CUSTOMER
               INVALID KEY
                   DISPLAY 'NO DATA FOR CUSTOMER'
                   EXIT SECTION
           END-START
           READ LOAN-FILE NEXT RECORD
      *>   Note: would work without check if not the last entry of the complete file and the one seen with START was deleted in the microseconds between START+READ
           PERFORM FOREVER
              IF LOAN-CUSTOMER NOT = DATA-CUSTOMER
                 EXIT PERFORM
              END-IF
              PERFORM DISPLAY-LOAN-DATA
              READ LOAN-FILE NEXT RECORD
                 AT END EXIT PERFORM
              END-READ
           END-PERFORM
      *>
           CONTINUE.
Simon Sobisch
  • 6,263
  • 1
  • 18
  • 38
  • Using KEY >= LOAN-CUSTOMER still does not help. I also tried your suggestion of inline perform. It is still throwing the error "Record key does not exist for file LOAN-FILE". – eisem Sep 16 '21 at 08:58
  • Just to double check: you get the error message at the `START`, this `START` is exactly done only once and `LOAN-CUSTOMER` contains a value that is definitive stored in the file as seen when you just iterate with a plain `READ NEXT` through the file? – Simon Sobisch Sep 16 '21 at 09:02
  • The error message occurs at START and LOAN-CUSTOMER has a value directly before START. The value also is stored in the LOAN-FILE as alternate key. I have another program where I read my LOAN file using my primary key. And there I see the same value. But my alternate key still is not found at START. – eisem Sep 16 '21 at 09:09
  • 1
    Hm, do you mind creating a sample program that first creates some test data `OPEN OUTPUT` + `WRITE`s + `CLOSE`, then reads the data and sharing it, for example via https://www.tutorialspoint.com/compile_cobol_online.php ? This way one could inspect the code run easily and also try adjustments easily. [or: possibly allows you to find the issue when trimming down your program to the question, at least that happens for me from time to time...] – Simon Sobisch Sep 16 '21 at 09:22
  • Yes, I can do it. – eisem Sep 16 '21 at 09:24
  • I have written a cobol code which creates a new file and writes data into it. The file is exactly like my LOAN file. Here I could read the file using an alternate key but the result is shown twice. Link: – eisem Sep 16 '21 at 10:12
  • In my original file I also doing other things before reading the loans: ask for a customer id , checking if customer exists and then trying to get the loaned books of the customer (here my problem is occuring). – eisem Sep 16 '21 at 10:20
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/237178/discussion-between-simon-sobisch-and-eisem). – Simon Sobisch Sep 16 '21 at 12:13
0

In the COBOL program where a loan is created the invalid key has to be caught when the loan file is accessed.

It was missing and this lead to the issue.

eisem
  • 185
  • 1
  • 10