eisem
eisem

Reputation: 195

Cobol - alternate key not found

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) ?

Upvotes: 2

Views: 456

Answers (2)

eisem
eisem

Reputation: 195

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.

Upvotes: 0

Simon Sobisch
Simon Sobisch

Reputation: 7287

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.

Upvotes: 2

Related Questions