It is possible that I have already adequately covered the material I am presenting below on a couple of other pages on this site, specifically at VSAM File Access for COBOL, which was the original presentation of my VSAMIO assembler subroutines that allows MVT COBOL to manipulate VSAM clusters; and at COBOL Programs with ISAM and VSAM Datasets, which covers migration of native ISAM file handling in MVT COBOL over to VSAM clusters using my VSAMIO assembler routines. I wrote the material for the former in 2000, when I first wrote the VSAMIO routines, and the latter in 2021, to show how to migrate ISAM datasets over to VSAM.
As with the latter page above, the material presented here, and also the COBOL programs to demonstrate the material, are new material and not just a restating of previously presented material, even if there is some repetition and overlap.
For each example presented below, I will include a direct, side-by-side comparison of a program coded for compilation via the VS COBOL compiler, using native VSAM COBOL statements, against a program to achieve the same results, but coded for compilation via the MVT COBOL compiler utilizing the VSAMIO subroutines to access the VSAM clusters. The translation from native VS COBOL VSAM access to MVT COBOL with the VSAMIO subroutine calls is fairly straight forward. It is necessary to replace file definitions (SELECT statement and clauses, and FD group), and I/O statements (OPEN, CLOSE, READ, START, WRITE, and REWRITE) with definitions in WORKING STORAGE for holding file control information and I/O areas, and CALLs in the PROCEDURE DIVISION for all the equivalent COBOL I/O statements. But all of the logic outside of the file access remains the same, although, looking back over the COBOL code to write this text, I see that in some cases I made the occasional minor change to some of the data names.
It was necessary in a few specific instances to make small coding changes to accommodate the MVT COBOL compiler syntax conventions that are slightly different from VS COBOL. For example, using PERFORM to execute a paragraph in MVT COBOL will generate a warning if the syntax is not altered to PERFORM paragraph-name THRU paragraph-name, rather than just PERFORM paragraph-name. I will include a list of these changes for each program below.
The material presented below is:
Sequential access
Reading and printing records, via both Primary and Alternate key
Reading records and copying to sequential (tape) file (unloading records)
Random access
Sequential access
Random access
Key sequenced VSAM clusters provide a similar function to ISAM (Indexed Sequential Access Method) datasets. A KSDS cluster is composed of, at a minimum, an INDEX component and a DATA component. The INDEX contains the data values for the Primary Key, which is the order in which the records are loaded and maintained. The Primary Key for each record is unique within the collection of records; that is, each key value occurs in only a single record stored in the DATA component.
In addition to the Primary Key, additional Alternate Keys may be defined for a cluster, using data contained in other fields in the record. The Alternate Keys may be defined as Non-Unique; that is, there may be multiple key values in the set which occur in different data records. The first, or only, Alternate Key, must be created with the IDCAMS utility after the cluster is loaded. After the Alternate Key(s) are created with IDCAMS, the Alternate Key sets are maintained across additions and deletions of data records, and changes in the fields included in the Alternate Key in correlation with the data, just as the Primary Keys are maintained. You may also elect that the Alternate Key set is not to be updated automatically when the underlying data component is changed; see UPGRADE/NOUPGRADE in the IDCAMS Alternate Key definition syntax. This might be desirable in a group of records that had massive updates in batch, where the overhead of allowing VSAM to upgrade the Alternate Key set(s) is more costly than rebuilding the Alternate Key(s) after a massive update to the data records is completed.
In order to access the cluster via the Alternate Key(s), for each Alternate Key defined it is necessary to define a PATH object. The PATH object for a particular sequence set relates the Alternate Key object to the base cluster.
KSDS clusters are most frequently used for data where it is necessary to retrieve data records randomly using a key value.
Data used for all of the KSDS clusters below utilize a hypothetical student information data record:
Field Starting Column Ending Column Length Contains Picture 1 9 9 Student Identification Number 9(09) Primary key (length: 9, offset: 0) 10 21 11 Student Name, First X(11) 22 22 1 Student Name, Middle Initial X(01) 23 32 10 Student Name, Last X(10) 33 67 35 Address, Street X(35) 68 87 20 Address, City X(20) 88 89 2 Address, State Abbreviation X(02) 90 94 5 Address, Postal Code X(05) 95 102 8 Student Birth Date, YYYYMMDD X(08) 103 110 8 Enrollment Start Date, YYYYMMDD X(08) 111 118 8 Last Contact Date, YYYYMMDD X(08) 119 148 30 Student Sort Name X(30) Alternate key (length:30, offset: 118) 149 150 2 Unused X(02)
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
The goal in this example is to create a KSDS cluster from a sequential dataset (read from tape) which contains essentially the complete record to be written to the KSDS cluster. The Primary Key is the Student Number, 9 digits located in position 1 through 9 of the input record, which must be specified when the cluster is defined with IDCAMS as offset 0. A secondary key will be created using the Student Name, in the format of Last Name, First Name, and Middle Initial, designated as Student Sort Name, and is 30 characters located in position 119 through 148, which must be specified when the Alternate Key is defined with IDCAMS as offset 118. This field will be created by the loading program before the record is written, and it is possible that duplicates may occur in the Alternate Key.
When records are initially written to a KSDS cluster, the Primary Key field must be unique and must be in ascending sequence; otherwise VSAM will return an error code for the WRITE and the record will be omitted. In order to control any duplicate or sequence error conditions, the loading program will test for these two conditions and exclude writing any records that would cause an error condition on the actual VSAM WRITE. As the dataset containing the input records is sorted on the Primary Key field before beginning the VSAM load logic, there is really no expectation of a sequence error, although it is possible for there to be duplicate records in the input dataset.
The VS COBOL program using native VSAM coding statements is LOAD01N and the MVT COBOL program using the VSAMIO subroutine is LOAD01V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at load01n - load01v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset, and
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for LOAD01N may be viewed at load01nc.pdf, and the compile listing for LOAD01V may be viewed at load01vc.pdf.
The output from executing LOAD01N may be viewed at load01nx.pdf, and the output from executing LOAD01V may be viewed at load01vx.pdf.
When loading a KSDS cluster, even if you intend to set up one or more Alternate Keys, during the initial load only the Primary Key is created (written to the Index component of the cluster). If you look at the jobstream for loading the KSDS cluster, you will see that the steps involved in creating/loading the KSDS are:
execute IDCAMS to:
delete existing cluster and related components (Data, Index, Alternate Index, Path), if they exist,
define empty cluster,
execute COBOL program to load records into the newly defined cluster:
execute IDCAMS to:
define the Alternate Index,
build the Alternate Index from the records loaded into the cluster,
define the Path to relate the Alternate Index to the cluster.
After the Alternate Index is defined, so long as UPGRADE is specified for the Alternate Index when it is defined, any updates to the cluster will be propagated to the Alternate Index.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
After you have loaded the KSDS cluster, you can access the records sequentially, using either the Primary Key or the Alternate Key. For any single program, either the Primary Key or the Alternate Key (or any of the Alternate Keys, if you have designed a cluster to be accessed by more than one Alternate Key) may be used to read the records from the cluster.
The goal in this example is to read the records from the cluster using either the Primary Key or the Alternate Key. For my example program, I have designed it to accept a parameter on the EXEC statement that will direct the program whether to use the Primary Key or the Alternate Key to read and process the records from the cluster. This program is not a complex design, but does illustrate how to accomplish sequential access via different keys.
The VS COBOL program using native VSAM coding statements is READ01N and the MVT COBOL program using the VSAMIO subroutine is READ01V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at read01n - read01v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the report dataset,
the label records clause of the FD for the sequential report dataset,
to establish the position in the KSDS cluster, ZERO is moved to the Primary Key, as MVT COBOL issues a Warning if Low-Values is moved to a numeric field, and
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for READ01N may be viewed at read01nc.pdf, and the compile listing for READ01V may be viewed at read01vc.pdf.
The output from executing READ01N (both number and name sequence) may be viewed at read01nx.pdf, and the output from executing READ01V may be viewed at read01vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
The necessity of this sort of program is greatly reduced with KSDS clusters; it is what would have normally been regarded as a 'reorganization program' for an ISAM dataset. With ISAM, it was not possible to physically delete records from the indexed dataset, so it was necessary for there to be an indicator field maintained in ISAM records to indicate that a record was 'logically' deleted. Programs accessing the ISAM dataset would bypass or ignore any record so flagged, but periodically the dataset would need to be read sequentially, the flagged records bypassed, and the non-flagged records written to a sequential dataset, which was then used to reload the ISAM dataset with only the non-deleted records present.
Even though the Index component(s) of KSDS clusters do not require reorganization as frequently as ISAM dataset indexes did, it is still necessary to periodically backup and restore the contents of KSDS clusters to eliminate CI/CA splits. The frequency with which KSDS reorganization must be done is influenced by the volatility of the updating of the KSDS Index components.
The goal in this example is to simply read the records via Primary Key and write them to a sequential dataset (in this case written to tape). There is no real need for a program of this type with KSDS clusters, since IDCAMS REPRO may be used, both to copy the records to tape. Likewise, once the records from the cluster are copied to a sequential backup dataset, the cluster may be deleted, redefined, and IDCAMS may be used to REPRO the records from the backup dataset into the newly defined, empty cluster.
The VS COBOL program using native VSAM coding statements is UNLD01N and the MVT COBOL program using the VSAMIO subroutine is UNLD01V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at unld01n - unld01v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset,
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for UNLD01N may be viewed at unld01nc.pdf, and the compile listing for UNLD01V may be viewed at unld01vc.pdf.
The output from executing UNLD01N may be viewed at unld01nx.pdf, and the output from executing UNLD01V may be viewed at unld01vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
For maintenance of the records in the cluster, the easiest design is to randomly retrieve a record using the Primary Key, after which you may alter the contents of fields in the record or delete the record from the cluster. You may add new records to the cluster, without regard for the sequence of the Primary Key of the record you are adding. When a record is added to or deleted from the cluster, or values changed in fields that comprise the Alternate Key(s), if the Alternate Key is defined as UPGRADE (which is the case in this test suite), the Alternate Key index is also upgraded.
The method of creating and processing the update dataset has been kept at the very simplest for my example. I have created a dataset of update records (on tape) that are essentially a record in the format of the Student Information record stored in the cluster, with a code appended at the front of the record containing the update action:
A for addition of a new record,
B for changing fields in an existing record, or
D for deleting an existing record.
In the case of 'A', the record fields following the update action code are complete. In the case of 'C', only the fields to be changed have values supplied, the remainder of the fields contain low-values. In the case of 'D', only the Student Number field contains a value, all other fields contain low-values.
In a 'real life' environment, it is far more likely that maintenance would be performed via a CICS or other similar program in real time environment. As we have both KICKS and INTERCOMM available for MVS 3.8j running under Hercules, those would be a likely candidate to investigate, if interested.
The VS COBOL program using native VSAM coding statements is UPDT01N and the MVT COBOL program using the VSAMIO subroutine is UPDT01V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at updt01n - updt01v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset,
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT,
INSPECT verb replaced by EXAMINE.
The compile listing for UPDT01N may be viewed at updt01nc.pdf, and the compile listing for UPDT01V may be viewed at updt01vc.pdf.
The output from executing UPDT01N may be viewed at updt01nx.pdf, and the output from executing UPDT01V may be viewed at updt01vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
Entry sequenced VSAM clusters provide a similar function to Physical Sequential datasets. An ESDS cluster is composed of only a DATA component. The records may only be added to the dataset sequentially, although the dataset may be EXTENDed by writing additional records at the end of the dataset after it has been initially created. Records may not be physically deleted from the dataset. It is possible to access the records randomly by using IDCAMs to create an Alternate Index for the ESDS DATA component. As with the KSDS Alternate Keys, it is also necessary to create a PATH component to RELATE the Alternate Index to the base cluster.
If you write an application program in Assembler, it is also possible to directly access records in an ESDS cluster by using the Relative Byte Address. Since I am writing this from the perspective of using a COBOL program to access the VSAM clusters, I will not cover that here.
Data used for all of the ESDS clusters below utilize a hypothetical sales history data record:
Field Starting Column Ending Column Length Contains Picture 1 8 8 Date of sale (YYYYMMDD) 9(8) 9 11 3 Type of item 9(3) 12 51 40 Description of item X(40) 52 55 4 Gross price of item sold S9(5)V99 COMP-3 56 57 2 Discount allowed V99 58 61 4 Net price of item sold S9(5)V99 COMP-3 62 96 35 Purchaser name X(35) Alternate key #1 97 99 3 Type of item 9(3) 100 103 4 Relative record number S(8) COMP 104 111 8 Date of sale (YYYYMMDD) 9(8) Alternate key #2 112 114 3 Type of item 9(3) 115 118 4 Relative record number S9(8) COMP
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
The goal is to create an ESDS cluster from multiple years of historical sales records (read from tape). The records on the input dataset are already in sequence by date and time of sale, and tracking number. To facilitate building Alternate Indexes to retrieve the records for reporting, during the load process I created the fields necessary to build the index data at the end of the record that is written to the ESDS cluster. Since I did not wish to deal with non-unique Alternate Keys, I used the Relative Record Number of the record as the final sub-field of each key group.
Coming up with a design to demonstrate ESDS use was difficult, because ESDS organization - sequential - is about as vanilla as it gets. However, when I was working at a fairly large municipal government, we used an ESDS cluster to hold a fairly large number of key fields. The content of the key fields originated in several other datasets. With Alternate Indexes built over the ESDS cluster, the design pulled together a large amount of data to make it accessible online via CICS transactions and utilized during night batch runs to produce historical reports.
As I was coding this program, I decided that I wanted to see the records as they were loaded. However, this is a fairly large dataset, so I coded the program to accept an EXEC parameter to 'turn on' this detail printing. Without the parameter specified, only records which encounter an error during the write will be printed. A summary page is always printed showing the number of records read, written to the ESDS cluster, and records encountered with errors.
The VS COBOL program using native VSAM coding statements is LOAD03N and the MVT COBOL program using the VSAMIO subroutine is LOAD03V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at load03n - load03v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset, and
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for LOAD03N may be viewed at load03nc.pdf, and the compile listing for LOAD03V may be viewed at load03vc.pdf.
The output from executing LOAD03N may be viewed at load03nx.pdf, and the output from executing LOAD03V may be viewed at load03vx.pdf.
If you look at the jobstream for loading the ESDS cluster, you will see that the steps involved in creating/loading the ESDS are:
execute IDCAMS to:
delete existing cluster and related components (Data, Alternate Indexes, Paths), if they exist,
define empty cluster,
execute COBOL program to load records into the newly defined cluster:
execute IDCAMS to:
define the Alternate Indexes,
build the Alternate Indexes from the records loaded into the cluster,
define the Paths to relate the Alternate Indexes to the cluster.
After the Alternate Indexes are defined, so long as UPGRADE is specified for the Alternate Index when it is defined, any updates to the cluster will be propagated to the Alternate Indexes.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
When I loaded the records to the ESDS Cluster, I created fields that were used to build two Alternate Indexes. The first Alternate Key provides the sequence: purchaser name, type of item purchased, date purchased.
After you have loaded the ESDS cluster and built the Alternate Key(s), you can access the records sequentially in the order retrieved by the Alternate Key value.
The goal in this example is to read the records from the cluster using the first Alternate Key.
The VS COBOL program using native VSAM coding statements is READ03N and the MVT COBOL program using the VSAMIO subroutine is READ03V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at read03n - read03v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the report dataset,
the label records clause of the FD for the sequential report dataset,
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for READ03N may be viewed at read03nc.pdf, and the compile listing for READ03V may be viewed at read03vc.pdf.
The output from executing READ03N may be viewed at read03nx.pdf, and the output from executing READ03V may be viewed at read03vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
When I loaded the records to the ESDS Cluster, I created fields that were used to build two Alternate Indexes. The second Alternate Key provides the sequence: date purchased and type of item purchased.
After you have loaded the ESDS cluster and built the Alternate Key(s), you can access the records sequentially in the order retrieved by the Alternate Key value.
The goal in this example is to read the records from the cluster using the second Alternate Key.
The VS COBOL program using native VSAM coding statements is READ04N and the MVT COBOL program using the VSAMIO subroutine is READ04V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at read04n - read04v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the report dataset,
the label records clause of the FD for the sequential report dataset,
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for READ04N may be viewed at read04nc.pdf, and the compile listing for READ04V may be viewed at read04vc.pdf.
The output from executing READ04N may be viewed at read04nx.pdf, and the output from executing READ04V may be viewed at read04vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
Relative Record, or NUMBERED, VSAM clusters provide a similar function to BDAM (Basic Direct Access Method) datasets. An RRDS cluster is composed of only a DATA component. The records are always fixed length and might be visualized as a table of records. Once loaded into the RRDS cluster, records may be read sequentially or randomly. If read sequentially, they are read in order from the beginning of the file to the end. If read randomly, they are read using a relative record number, which varies from 1 to the highest record previously written to the cluster.
If records are loaded into an RRDS cluster sequentially, the first write places the record into the first available position in the cluster and each subsequent record is written following the previous record written.
If records are loaded RANDOMLY, each record is written to the cluster in the relative position indicated by the record number provided at the time of the write. In this case, gaps may exist between the records written. Sequentially reading records from a randomly loaded RRDS will return only the records present (previously written to) the cluster. A random read for a record number that has not been previously written will result in an INVALID KEY condition. A randomly loaded RRDS may later have records added in the open record slots. A sequentially loaded RRDS may only have additional records added at the end of the cluster.
Regardless of whether the RRDS was loaded sequentially or randomly, existing records may be read from an RRDS cluster, the contents updated, and the revised record rewritten to the cluster. It is also possible to DELETE an existing record from an RRDS cluster, and the deletion is physical; ie, the record is no longer present in the cluster.
An attempt to read a record from an open slot will result in a INVALID KEY condition. An attempt to write a record to an occupied slot will also result in an INVALID KEY condition.
In my experience over a number of years, I have rarely used RRDS, as the applications I was working on were typically betters suited by KSDS or ESDS. Consequently I found it a bit difficult to come up with an illustration using RRDS clusters in a realistic scenario. There are additional permutations of accessing RRDS clusters in my other VSAMIO pages, but the examples below both use RANDOM access, both for loading and retrieving records from the RRDS cluster. If you have read through my RPG section, you can recognize that the tables, and reports generated from them, come from my RPG programming example #6.
Data used for all of the RRDS clusters below utilize a set of hypothetical course information tables:
Department Table Field Starting Column Ending Column Length Contains Picture 1 2 2 Department Number 9(02) 3 6 4 unused, must contain 0 9(04) 7 46 40 Department Name X(40)
Course Table Field Starting Column Ending Column Length Contains Picture 1 2 2 Department Number 9(02) 3 5 3 Course Number 9(03) 6 6 1 unused, must contain 0 9(01) 7 56 50 Course Name X(50) 57 57 1 Course Credit Hours 9(01)
Section Table Field Starting Column Ending Column Length Contains Picture 1 2 2 Department Number 9(02) 3 5 3 Course Number 9(03) 6 6 1 Section Number 9(01) 7 26 20 Section Description X(20)
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
The goal is to create an RRDS cluster from three sequential datasets (read from tape). Each of the tape datasets contains one of the tables used to provide Department, Course, and Section information for university courses. Rather than build three separate RRDS clusters, I opted to combine the three tables into a single table in one cluster. Logically this resulted in an RRDS with records clustered around the areas the table records occupied for the three tables of data, with many open slots left. However it simplifies accessing the table data. If this were an actual application, it might be preferable to create three separate RRDS clusters, since the length of the record varies from 26 to 57 characters. Since RRDS records must all be the same length, it was necessary to waste storage in the case of the Department and Section table records.
When records are initially written to an RRDS cluster, each record is placed on the cluster using a relative record number. I have padded the unused portion of the Department and Course records with zeros, so that the first six characters of each table record may be used as the relative record number when writing the record to the RRDS (and subsequently when retrieving the record).
The VS COBOL program using native VSAM coding statements is LOAD02N and the MVT COBOL program using the VSAMIO subroutine is LOAD02V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at load02n - load02v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset, and
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for LOAD02N may be viewed at load02nc.pdf, and the compile listing for LOAD02V may be viewed at load02vc.pdf.
The output from executing LOAD02N may be viewed at load02nx.pdf, and the output from executing LOAD02V may be viewed at load02vx.pdf.
If you look at the jobstream for loading the RRDS cluster, you will see that the steps involved in creating/loading the RRDS are:
IDCAMS
delete existing cluster and related DATA component, if they exist,
define empty cluster,
execute COBOL program to load records into the newly defined cluster,
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
The goal is to sort a set of records that utilize information from the Department, Course, and Section table records into ascending sequence - Department Number, Course Number, and Section Number, then by Student Name - retrieve the table records when a level change occurs in the sorted records, and produce a couple of reports: Class Rolls for each section and Enrollment by Department, Course, and Section.
The VS COBOL program using native VSAM coding statements is READ02N and the MVT COBOL program using the VSAMIO subroutine is READ02V. A side-by-side comparison of the COBOL code (columns 7 through 72 only), showing the differences highlighted may be viewed at read02n - read02v.pdf.
To accommodate MVT COBOL syntax differences, there are minor changes made:
the format of the ASSIGN statement for the sequential datasets,
the label records clause of the FD for the sequential report dataset, and
all PERFORM statements have been modified to use the format PERFORM paragraph-name THRU paragraph-name, with the addition of the THRU paragraph in each case to be a paragraph containing a single statement: EXIT.
The compile listing for READ02N may be viewed at read02nc.pdf, and the compile listing for READ02V may be viewed at read02vc.pdf.
The output from executing READ02N may be viewed at read02nx.pdf, and the output from executing READ02V may be viewed at read02vx.pdf.
Instructions for obtaining the COBOL source, jobstreams to run and execute the programs, and input data may be found below at Source Code, Jobstreams, and Data for Compiling and Executing Examples.
An archive is available to download from native_cobol_to_vsamio.tar.gz [508kb MD5: 9b171838eaf40658062af58e44936c9c]. The archive contains:
jcl restore.native.cobol.to.vsamio.jcl Executes DSSREST to restore datasets from tape and then executes PDSUPDTE to tailor restored jobstreams to match High Level Qualifier for restored datasets. tape native_to_vsamio.het DSSDUMP containing COBOL source library, COBOL COPY library, JCL to compile/execute COBOL programs, LOAD library containing compiled COBOL programs. student.data.het tape read by LOAD01V to load student records into KSDS cluster student.update.het tape read by UPDT01V to apply maintenance to KSDS cluster (loaded by LOAD01V) unload.student.het tape written by UNLD01V to unload records from KSDS cluster onto tape nookbooks.het tape read by LOAD03V to load store inventory into ESDS cluster rvuniv_tables.het tape read by LOAD02V to load Department/Course/Section tables into RRDS cluster rvuniv_roster.het tape read by READ02V to utilize tables in RRDS cluster (loaded by LOAD02V) to produce reports
The first six statements of the jobstream to restore the DSSDUMP tape are:
//DSSREST JOB (SYS),'DSSREST',CLASS=S,MSGCLASS=X //* //RESTORE PROC HLQ='JAY02', <- HIGH LEVEL FOR DATASETS RESTORED // VOL='PUB000' <- VOLUME TO WHICH THEY ARE RESTORED //* //DSSREST EXEC PGM=DSSREST,REGION=8000K,TIME=1440, // PARM='*'
Before submitting the job, edit with a text editor and modify the HLQ (in statement three) and the VOL (in statement four) to match your system.
If you are interested in writing COBOL programs that utilize VSAM datasets, I hope this documentation has provided you with the information you need to install my routine and get started writing programs on your own. If I can answer any questions about installing and/or using the routine, or if you find errors in these instructions, please don't hesitate to send them to me:
This page was last updated on August 07, 2025.