Reputation: 195
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
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
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