Sometimes you need to do more than one kind of access on the same VSAM file in one program. You might look up a record by key, then read the next few records in key order. Or you might want to position at a certain key (or the start of a range) and then read all records from that point forward. That mix of random (by key) and sequential (READ NEXT) is called dynamic access. In COBOL you specify ACCESS IS DYNAMIC in the SELECT for the file; then you can use READ by key, START, and READ NEXT (and where supported, READ PREV) in any order. This page explains what dynamic access is, how it differs from pure sequential and pure random, when to use it, and how to code it (START, READ NEXT, key handling, and range processing).
Dynamic access is an access mode that allows both random and sequential operations on the same open file. "Random" here means direct access by key (for a KSDS), by relative record number (for an RRDS), or by RBA (for an ESDS, depending on implementation). "Sequential" means reading records in order: for a KSDS, in key order using READ NEXT (or READ PREV). So with dynamic access you can, in one program: open the file, do a random READ to get one record by key, then do READ NEXT several times to get the following records; or use START to position at a key (e.g. the first record for customer "CUST100") and then READ NEXT until you have processed all records in the range you care about. The key point is that you are not locked into one style of access for the whole run.
With ACCESS IS SEQUENTIAL you can only do sequential operations: typically READ NEXT (and optionally START to set the starting position). You cannot do a random READ by key in the middle of the file and then continue. With ACCESS IS RANDOM you can only do direct access: you set the key and READ to get that one record. You cannot do READ NEXT to walk forward. With ACCESS IS DYNAMIC you can do both. So if your program needs to look up one record by key and then read the next five, or position at a key and process all records from that key to another, dynamic access is the right choice. If you only ever read in key order from the start (or from a START), sequential is enough; if you only ever read by key with no sequential walk, random is enough.
| Access mode | Capability |
|---|---|
| SEQUENTIAL | READ NEXT (and READ PREV where supported), START; no random READ by key in the same open. |
| RANDOM | READ by key (or RBA/RRN); no READ NEXT or START for sequential walk. |
| DYNAMIC | Both: READ by key, START at key, READ NEXT, READ PREV (where supported). Can switch between random and sequential in the same program. |
The typical pattern for range processing with dynamic access is: set the key (or alternate key) to the starting value you want (e.g. the first key in the range), issue START to position the file at that key (or at the first record greater than or equal to that key, depending on the START option), then in a loop issue READ NEXT until you have passed the end of the range or reached end of file. START does not read a record; it only sets the "current position" so that the next READ NEXT returns the record at that position (or the next one, depending on the exact semantics). So START key followed by READ NEXT gives you the record at that key; the next READ NEXT gives the following record, and so on. You can also use START with a key that is not in the file; then READ NEXT returns the first record with a key greater than (or equal to) the start key, which is useful for "first record at or after this key" processing.
In the FILE-CONTROL paragraph you specify ORGANIZATION IS INDEXED (for KSDS), ACCESS MODE IS DYNAMIC, and RECORD KEY (and optionally ALTERNATE RECORD KEY). In the procedure division you can use READ file-name for random read (with the key field set) and READ file-name NEXT for sequential read. For START you set the key and issue START file-name with the desired relational operator (e.g. KEY >= key-value to position at the first record with that key or greater). Example: to process all records with keys from LOW-KEY to HIGH-KEY, you might move LOW-KEY to the record key, START the file with KEY >= LOW-KEY, then in a loop READ NEXT until the key is greater than HIGH-KEY or you get end-of-file. Each READ NEXT returns the next record in key order; you process it and repeat.
123456789101112131415161718192021222324252627FILE-CONTROL. SELECT CUSTFILE ASSIGN TO CUSTFILE ORGANIZATION IS INDEXED ACCESS MODE IS DYNAMIC RECORD KEY IS CUST-ID FILE STATUS IS WS-STATUS. PROCEDURE DIVISION. OPEN INPUT CUSTFILE MOVE 'CUST100' TO CUST-ID START CUSTFILE KEY >= CUST-ID INVALID KEY PERFORM BAD-START END-START PERFORM UNTIL EOF READ CUSTFILE NEXT AT END SET EOF TO TRUE NOT AT END IF CUST-ID > 'CUST199' SET EOF TO TRUE ELSE PERFORM PROCESS-RECORD END-IF END-READ END-PERFORM CLOSE CUSTFILE STOP RUN.
This pattern (START at a key, then READ NEXT until a condition) is the standard way to process a key range with dynamic access. The exact syntax for START (KEY =, KEY >, KEY >=, etc.) and for READ NEXT may vary slightly by COBOL dialect; the idea is the same.
Another common use of dynamic access is to read one record by key and then read the next few in order. For example, you read the record for customer "CUST100" (random READ), then READ NEXT to get the next record (e.g. next order or next detail). After a random READ, the "current position" is set to that record, so the next READ NEXT returns the following record in key order. So you do not need an explicit START in that case; the random READ establishes the position. If you need to go back to a different key later, you can do another random READ or START to reposition.
Switching between random and sequential access can affect buffering. When you do a random READ, VSAM uses the index to find the right control interval and may read a different part of the file than where you were for sequential. So the "current position" for READ NEXT is the record you just read (or the position after START). If you alternate often between random and sequential to widely separated keys, the buffer pool may have to replace CIs, which can increase I/O. For range processing (START once, then many READ NEXTs), you tend to stay in the same part of the file and benefit from sequential I/O. So dynamic access is flexible but for very mixed patterns you may see more I/O than pure sequential or pure random to one area.
With sequential you can only turn the pages of the book one by one. With random you can jump to one page by its number. With dynamic you can do both: jump to a page (START or READ by key), then turn the pages from there (READ NEXT) until you are done with that section. So you get to choose each time whether to jump or to turn the page.
1. What does ACCESS IS DYNAMIC allow?
2. How do you process a range of keys with dynamic access?
3. Which VSAM type is typically used with dynamic access for key-based processing?