Processing with VSAM Files Please use speaker notes for additional information! Organization is sequential Access is sequential SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS SEQUENTIAL ACCESS IS SEQUENTIAL. This code means that the file is organized without indexes and will be read sequentially one record at a time. Note that since sequential is the default for both organization and access, these clauses do not need to be specified. The organization of the tells how the data is organized. Organization sequential means that it is organized without indexes. Organization indexed means that it is an indexed file with a primary index and possible alternate indexes that can be used to access the records. Essentially that means that there will be a data file and an index file used to access the data. The third type of organization is relative which will be not be dealt with in this presentation. Once a file has been set up with indexes, other programs reading or updating this file must also specify the indexes. The indexes can then be used to access the records on the file. Today indexed files are VSAM (Virtual Storage Access Method). Access refers to how the records on the file will be accessed. The access method is directly related to the organization. For example if the organization is sequential, the records can only be accessed sequentially. Organization is indexed Access is sequential SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... This file is an indexed VSAM file. That means that the records are stored on a disk using a methodology that includes indexes. This means that there will be two files: one containing the data and one containing the indexes. The index can be either numeric or alphanumeric. The index must be unique so frequently a field like social security number or some other identification number is used as the index. In this example, the file is organized so that it has indexes. The field that is the index is specified in the record key clause. The access on this select is sequential which means that the file will be read sequentially one record at a time. Note that the indexed field that is the record key must then be defined in the FILESECTION. Organization is indexed Access is random SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... With random access, the indexed structure can be used to access a specific record based on the record key. The structure of the program usually involves reading a transaction that contains a particular identification number and then randomly finding a match to that identification number in the indexed file. (Note I used identification number because that is the record key in the example). Organization is indexed Access is dynamic SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS DYNAMIC RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... With indexed organization, you can also specify that ACCESS IS DYNAMIC. This means that the indexed file can be read both sequentially and dynamically in this program. For example, you might randomly access a particular record and then process the records after it in the file sequentially until a particular condition is met. As we will see, with dynamic access the programmer must write code to specify whether the read is random or sequential. Alternate key SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO ALTERNATE RECORD KEY IS EMPNAME WITH DUPLICATES. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 EMPNAME PIC X(20). SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS IDNO ALTERNATE RECORD KEY IS EMPNAME WITH DUPLICAT3S. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 EMPNAME PIC X(20). SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS DYNAMIC RECORD KEY IS IDNO ALTERNATE RECORD KEY IS EMPNAME WITH DUPLICATES. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 EMPNAME PIC X(20). Creating a VSAM file SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... WRITE INDEXED-REC INVALID KEY PERFORM B-300-ERROR-WRITE. In this example, I am going to be creating a indexed sequential file with IDNO as the key. When dealing with indexes there is the possibility that I will encounter a situation where the write is invalid. In these cases, the invalid key clause on the write will be triggered. If the write is invalid, the write will not be executed. Instead processing will go to B-300ERROR-WRITE. Write an indexed file SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO. FD 01 WRITE INDEXED-REC INVALID KEY PERFORM B-300-ERROR-WRITE NOT INVALID KEY PERFORM B-310-PAPER-TRAIL END-WRITE INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... There is also a NOT INVALID KEY clause that allows the programmer to specify activity that is to take place if the WRITE was successful. For example, the programmer could have a routine that writes a report containing all of the records successfully written tot he file. Note that the END-WRITE clause can be used with the WRITE as well. Creating an indexed file SELECT SEQ-PAY-FILE ASSIGN TO “A:\PAYORIG.DAT” ORGANIZATION IS SEQUENTIAL ACCESS IS SEQUENTIAL. SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO. DATA DIVISION. FILE SECTION. FD PAYORIG DATA RECORD IS PAYIN-REC. 01 PAYIN-REC. 05 ID-IN PIC 9(5). 05 REST-IN PIX X(100). FD INDEXED-FILE DATA RECORD IS INDEXED-REC. 01 INDEXED-REC. 05 IDNO PIC 9(5). 05 REST-DATA PIC X(100). B-200-LOOP. MOVE ID-IN TO IDNO. MOVE REST-IN TO REST-DATA. WRITE INDEXED-REC INVALID KEY PERFORM B-300-WRITE-ERR. READ PAYORIG AT END MOVE “NO “ TO MORE-RECS. Reading an indexed file sequentially SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... READ INDEXED-FILE AT END MOVE “NO “ TO MORE-RECS. When an indexed file is being read sequentially the usual sequential read is used. Essentially, you can read the indexed file sequentially from record one until end of file has been reached. The processing will be the same as if the organization was sequential. EQUAL TO = GREATER THAN START filename KEY IS > NOT LESS THAN NOT < GREATER THAN OR EQUAL TO >= In this example, I have the user INVALID KEY… enter an identification number NOT INVALID KEY… which is accepted to an area in END-START working storage. The entered DISPLAY “ENTER START IDNO”. number is then moved to IDNO ACCEPT IDNO-ENTERED. which is the RECORD KEY. I MOVE IDNO-ENTERED TO IDNO then look for a starting point START INDEXED-FILE based on the KEY >= to IDNO. KEY >= IDNO If the user entered 45678 then INVALID KEY processing would start with DISPLAY “INVALID START POINT” either 45678 or the first record MOVE “NO “ TO FOUND-IND larger than 45678. If no record NOT INVALID KEY was equal or greater than other MOVE “YES” TO FOUND-IND processing needs to be coded. END-START NOTE: The START positions, a IF FOUND-IND = “YES” READ is needed to actually read READ INDEXED-FILE the record. AT END MOVE “NO “ TO MORE-RECS. START verb Sequentially reading using alternate key When you want to read sequentially along the alternate key path, you use the START verb to establish both the alternate key path and the starting point. In this example, I want to read the starting with the first record along the alternate key path. To do this, I move LOW-VALUES to the field defined as the ALTERNATE RECORD KEY and then in the KEY clause of the START, I again use the name of the ALTERNATE RECORD KEY. This not only locates the record but also establishes the path to be followed with the sequential READ. SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS SEQUENTIAL RECORD KEY IS IDNO ALTERNATE RECORD KEY IS EMPNAME WITH DUPLICATES. FD INDEXED-FILE DATA RECORD IS INDEXED-REC. 01 INDEXED-REC. 05 IDNO PIC 9(5). 05 EMPNAME PIC X(20). MOVE LOW-VALUES TO EMPNAME. START INDEXED-FILE KEY GREATER THAN EMPNAME INVALID KEY ... READ INDEXED-FILE AT END MOVE “NO “ TO MORE-RECS. Random read - record/prime key MOVE TRAN-ID TO IDNO. READ INDEXED-FILE INVALID KEY PERFORM B-310-PROBLEM NOT INVALID KEY PERFORM B-300-PROCESS END-READ OR MOVE TRAN-ID TO IDNO. READ INDEXED-FILE INVALID KEY PERFORM B-310-PROBLEM. SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS IDNO. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 ... MOVE TRAN-ID TO IDNO establishes the key. The READ that randomly reads the file looking for a record with that IDNO. If the read is not successful in finding a record with that IDNO, the INVALID KEY clause is executed. Random read - alternate key MOVE EMP-NAME-TRAN TO EMPNAME. READ INDEXED-FILE KEY IS EMPNAME INVALID KEY PERFORM B-310-PROBLEM NOT INVALID KEY PERFORM B-300-PROCESS END-READ OR MOVE EMP-NAME-TRAN TO EMPNAME. READ INDEXED FILE KEY IS EMPNAME INVALID KEY PERFORM B-310-PROBLEM. SELECT INDEXED-FILE ASSIGN TO “A:\PAYROLL.DAT” ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS IDNO ALTERNATE RECORD KEY IS EMPNAME WITH DUPLICAT3S. FD 01 INDEXED-FILE DATA RECORD IS INDEXED-REC. INDEXED-REC. 05 IDNO PIC 9(5). 05 EMPNAME PIC X(20). The employee name from the transaction is move to the EMPNAME to establish the key. Since this READ is going to be using the ALTERNATE RECORD KEY the KEY clause has to be used in the READ to establish the fact that we are searching for a match in the alternate index, not the prime index. Read sequentially &/or randomly SELECT MASTER-FILE ASSIGN TO "C:\PCOBWIN\VSAM\VSAMALT.DAT" ORGANIZATION IS INDEXED ACCESS IS DYNAMIC RECORD KEY IS MID ALTERNATE RECORD KEY IS MITEM-NAME WITH DUPLICATES. This file is organized with indexes and the ACCESS IS DYNAMIC clause allows the programmer to access the file either sequentially or randomly using either the record key MID or the alternate record key MITEM-NAME. Sequential read using primary key: (Assumes starting point has been established). READ MASTER-FILE NEXT AT END MOVE "YES" TO EOF-IND END-READ. When reading a ACCESS IS DYNAMIC file sequentially, the NEXT is required to differentiate between the two types of READs. Random read using primary key: MOVE RETR-ID TO MID. READ MASTER-FILE INVALID KEY PERFORM B-310-INVALID NOT INVALID KEY PERFORM B-300-PROCESS END-READ. Random and sequential reads MOVE START-PT TO MID. MOVE "YES" TO MSTR-FOUND. READ MASTER-FILE INVALID KEY MOVE "NO " TO MSTR-FOUND. IF MSTR-FOUND = "YES" PERFORM B-300-DETAIL EOF-MSTR = "YES”. B-300-DETAIL. ...processing... READ MASTER-FILE NEXT AT END MOVE "YES" TO EOF-MSTR. This code shows the START-PT being moved to the MID (the record key) and then a random read being done to locate the record that is requested. When the record is found, control will pass to the B-300-DETAIL. In this routine, the file will be read sequentially from the record located by the random read. Note that the sequential read uses the NEXT. When EOF is reached, processing will end. Start and sequential read Random and sequential read In this code a random read locates the starting record. If the locate is successful, then the NEXT record is read and processed. MOVE START-PT TO MID. MOVE "YES" TO MSTR-FOUND. READ MASTER-FILE INVALID KEY MOVE "NO " TO MSTR-FOUND NOT INVALID KEY MOVE “YES” TO MSTR-FOUND END-READ. IF MSTR-FOUND = "YES” READ MASTER-FILE NEXT AT END MOVE "YES" TO EOF-MSTR. To mix random and sequential read statements, dynamic access must be specified. In this code the start verb locates the starting record but does not read it. The first time the READ is executed the record that was located is read and processed. MOVE START-PT TO MID. MOVE “YES” TO MSTR-FOUND. START MASTER-FILE KEY >= MID INVALID KEY MOVE “NO “ TO MSTR-FOUND NOT INVALID KEY MOVE “YES” TO MSTR-FOUND END-START IF MSTR-FOUND = “YES” READ MASTER-FILE AT END MOVE “YES’ TO EOF-MSTR. Alternate key SELECT MASTER-FILE ASSIGN TO "C:\PCOBWIN\VSAM\VSAMALT.DAT" ORGANIZATION IS INDEXED ACCESS IS DYNAMIC RECORD KEY IS MID ALTERNATE RECORD KEY IS MITEM-NAME WITH DUPLICATES. Sequential read using alternate key: Random read using alternate key: (Assumes that the start point and alternate key path has been established). MOVE RETR-NAME TO MITEM-NAME. READ MASTER-FILE KEY IS MITEM-NAME INVALID KEY PERFORM B-410-INVALID NOT INVALID KEY PERFORM B-400-PROCESS. READ MASTER-FILE NEXT AT END MOVE "YES" TO EOF-IND. The sequential read is assuming that the path has been established by a previous random read. SELECT MASTER-FILE ASSIGN TO "C:\PCOBWIN\VSAM\VSAM1.DAT" ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS MID FILE STATUS IS WS-FILE-STATUS. File status 01 WS-FILE-STATUS PIC XX VALUE SPACES. MOVE RETR-ID TO MID. READ MASTER-FILE INVALID KEY PERFORM B-310-INVALID. IF WS-FILE-STATUS = "00" PERFORM B-300-PROCESS. Because of the file status clause in the select, the file status is retrieved every time this record is used. A file status of 00 means that the processing was successful. Charts that give meaning to the specific numbers are available in COBOL manuals. B-310-INVALID. MOVE RETR-ID TO PID. IF WS-FILE-STATUS = "23" MOVE "RECORD MISSING" TO PMSG ELSE MOVE "OTHER PROBLEM" TO PMSG. File status 01 WS-FILE-STATUS PIC XX VALUE SPACES. SELECT MASTER-FILE ASSIGN TO "C:\PCOBWIN\VSAM\VSAM1.DAT" ORGANIZATION IS INDEXED ACCESS IS RANDOM RECORD KEY IS MID FILE STATUS IS WS-FILE-STATUS. PROCEDURE DIVISION. DECLARATIVES. ERROR-HANDLING SECTION. USE AFTER ERROR PROCEDURE ON MASTER-FILE. ERROR-CHECK. IF WS-FILE-STATUS = "23" MOVE RETR-ID TO PID MOVE "RECORD MISSING " TO PMSG WRITE PRINTZ AFTER ADVANCING 1 LINES END-IF. END DECLARATIVES. MAIN-PROGRAM SECTION. MAINLINE. PERFORM A-100-INITIALIZE. PERFORM B-100-PROCESS. PERFORM C-100-TERMINATE. STOP RUN. B-200-LOOP. MOVE SPACES TO PRINTZ. MOVE RETR-ID TO MID. READ MASTER-FILE. IF WS-FILE-STATUS = "00" PERFORM B-300-PROCESS END-IF. The declaratives part of the program is where you can set up error handling procedures that can be applied to a file. Note that the read has no clause associated with it. If the read is unsuccessful control switches to the the error-handling section and appropriate processing is done.