Rational Developer for System z
Enterprise PL/I for z/OS, Version 3.8, Programming Guide

Accessing and updating a data set with record I/O

Once you create a consecutive data set, you can open the file that accesses it for sequential input, for sequential output, or, for data sets on direct access devices, for updating. See Figure 30 for an example of a program that accesses and updates a consecutive data set. If you open the file for output, and extend the data set by adding records at the end, you must specify DISP=MOD in the DD statement. If you do not, the data set will be overwritten. If you open a file for updating, you can update only records in their existing sequence, and if you want to insert records, you must create a new data set. Table 16 shows the statements and options for accessing and updating a consecutive data set.

When you access a consecutive data set by a SEQUENTIAL UPDATE file, you must retrieve a record with a READ statement before you can update it with a REWRITE statement; however, every record that is retrieved need not be rewritten. A REWRITE statement will always update the last record read.

Consider the following:

READ FILE(F) INTO(A);
     .
     .
     .
READ FILE(F) INTO(B);
     .
     .
     .
REWRITE FILE(F) FROM(A);

The REWRITE statement updates the record that was read by the second READ statement. The record that was read by the first statement cannot be rewritten after the second READ statement has been executed.

To access a data set, you must identify it to the operating system in a DD statement. Table 20 summarizes the DD statement parameters needed to access a consecutive data set.

Table 20. Accessing a consecutive data set with record I/O: essential parameters of the DD statement
Parameters What you must state When required
DSNAME=
 
DISP=
Name of data set
 
Disposition of data
set
Always
UNIT= or VOLUME=REF= Input device If data set not cataloged (all devices)
VOLUME=SER= Volume serial number If data set not cataloged (direct access)
DCB=(BLKSIZE= Block size1 If data set does not have standard labels
Notes:
1Or you could specify the block size in your PL/I program by using the ENVIRONMENT attribute.

The following paragraphs indicate the essential information you must include in the DD statement, and discuss some of the optional information you can supply. The discussions do not apply to data sets in the input stream.

Essential information

If the data set is cataloged, you need to supply only the following information in the DD statement:

If the data set is not cataloged, you must additionally specify the device that will read the data set and, direct access devices, give the serial number of the volume that contains the data set (UNIT and VOLUME parameters).

Example of consecutive data sets

Creating and accessing consecutive data sets are illustrated in the program in Figure 30. The program merges the contents of two data sets, in the input stream, and writes them onto a new data set, &&TEMP; each of the original data sets contains 15-byte fixed-length records arranged in EBCDIC collating sequence. The two input files, INPUT1 and INPUT2, have the default attribute BUFFERED, and locate mode is used to read records from the associated data sets into the respective buffers. Access of based variables in the buffers should not be attempted after the file has been closed.

Figure 30. Merge Sort—creating and accessing a consecutive data set
 //EXAMPLE  JOB
 //STEP1 EXEC IBMZCBG
 //PLI.SYSIN   DD *
 %PROCESS INT F(I) AG A(F) OP STG NEST X(F) SOURCE ;
 %PROCESS LIST;

  MERGE: PROC OPTIONS(MAIN);
    DCL (INPUT1,                             /* FIRST INPUT FILE     */
         INPUT2,                             /* SECOND INPUT FILE    */
         OUT )      FILE RECORD SEQUENTIAL;  /* RESULTING MERGED FILE*/
    DCL SYSPRINT    FILE PRINT;              /* NORMAL PRINT FILE    */

    DCL INPUT1_EOF  BIT(1) INIT('0'B);       /* EOF FLAG FOR INPUT1  */
    DCL INPUT2_EOF  BIT(1) INIT('0'B);       /* EOF FLAG FOR INPUT2  */
    DCL OUT_EOF     BIT(1) INIT('0'B);       /* EOF FLAG FOR OUT     */
    DCL TRUE        BIT(1) INIT('1'B);       /* CONSTANT TRUE        */
    DCL FALSE       BIT(1) INIT('0'B);       /* CONSTANT FALSE       */

    DCL ITEM1       CHAR(15) BASED(A);       /* ITEM FROM INPUT1     */
    DCL ITEM2       CHAR(15) BASED(B);       /* ITEM FROM INPUT2     */
    DCL INPUT_LINE  CHAR(15);                /* INPUT FOR READ INTO  */
    DCL A           POINTER;                 /* POINTER VAR          */
    DCL B           POINTER;                 /* POINTER VAR          */

    ON ENDFILE(INPUT1) INPUT1_EOF = TRUE;
    ON ENDFILE(INPUT2) INPUT2_EOF = TRUE;
    ON ENDFILE(OUT)    OUT_EOF    = TRUE;

    OPEN FILE(INPUT1) INPUT,
         FILE(INPUT2) INPUT,
         FILE(OUT)    OUTPUT;

    READ FILE(INPUT1) SET(A);                /* PRIMING READ         */
    READ FILE(INPUT2) SET(B);

    DO WHILE ((INPUT1_EOF = FALSE) & (INPUT2_EOF = FALSE));
      IF ITEM1 > ITEM2 THEN
        DO;
          WRITE FILE(OUT) FROM(ITEM2);
          PUT FILE(SYSPRINT) SKIP EDIT('1>2', ITEM1, ITEM2)
              (A(5),A,A);
          READ FILE(INPUT2) SET(B);
        END;
      ELSE
        DO;
          WRITE FILE(OUT) FROM(ITEM1);
          PUT FILE(SYSPRINT) SKIP EDIT('1<2', ITEM1, ITEM2)
              (A(5),A,A);
          READ FILE(INPUT1) SET(A);
        END;
    END;
    DO WHILE (INPUT1_EOF = FALSE);           /* INPUT2 IS EXHAUSTED  */
      WRITE FILE(OUT) FROM(ITEM1);
      PUT FILE(SYSPRINT) SKIP EDIT('1', ITEM1) (A(2),A);
      READ FILE(INPUT1) SET(A);
    END;

    DO WHILE (INPUT2_EOF = FALSE);           /* INPUT1 IS EXHAUSTED  */
      WRITE FILE(OUT) FROM(ITEM2);
      PUT FILE(SYSPRINT) SKIP EDIT('2', ITEM2) (A(2),A);
      READ FILE(INPUT2) SET(B);
    END;

    CLOSE FILE(INPUT1), FILE(INPUT2), FILE(OUT);
    PUT FILE(SYSPRINT) PAGE;
    OPEN FILE(OUT) SEQUENTIAL INPUT;

    READ FILE(OUT) INTO(INPUT_LINE);         /* DISPLAY OUT FILE     */
    DO WHILE (OUT_EOF = FALSE);
      PUT FILE(SYSPRINT) SKIP EDIT(INPUT_LINE) (A);
      READ FILE(OUT) INTO(INPUT_LINE);
    END;
    CLOSE FILE(OUT);

  END MERGE;
 /*
 //GO.INPUT1 DD *
 AAAAAA
 CCCCCC
 EEEEEE
 GGGGGG
 IIIIII
 /*
 //GO.INPUT2 DD *
 BBBBBB
 DDDDDD
 FFFFFF
 HHHHHH
 JJJJJJ
 KKKKKK
 /*
 //GO.OUT DD DSN=&&TEMP,DISP=(NEW,DELETE),UNIT=SYSDA,
 //          DCB=(RECFM=FB,BLKSIZE=150,LRECL=15),SPACE=(TRK,(1,1))

The program in Figure 31 uses record-oriented data transmission to print the table created by the program in Figure 27.

Figure 31. Printing record-oriented data transmission
%PROCESS INT F(I) AG A(F) OP STG NEST X(F) SOURCE ;
%PROCESS LIST;

 PRT: PROC OPTIONS(MAIN);
   DCL TABLE       FILE RECORD INPUT SEQUENTIAL;
   DCL PRINTER     FILE RECORD OUTPUT SEQL
                        ENV(V BLKSIZE(102) CTLASA);
   DCL LINE        CHAR(94) VAR;

   DCL TABLE_EOF   BIT(1) INIT('0'B);       /* EOF FLAG FOR TABLE   */
   DCL TRUE        BIT(1) INIT('1'B);       /* CONSTANT TRUE        */
   DCL FALSE       BIT(1) INIT('0'B);       /* CONSTANT FALSE       */


   ON ENDFILE(TABLE) TABLE_EOF = TRUE;

   OPEN FILE(TABLE),
        FILE(PRINTER);

   READ FILE(TABLE) INTO(LINE);             /* PRIMING READ         */

   DO WHILE (TABLE_EOF = FALSE);
     WRITE FILE(PRINTER) FROM(LINE);
     READ FILE(TABLE) INTO(LINE);
   END;

   CLOSE FILE(TABLE),
         FILE(PRINTER);
 END PRT;

Terms of use | Feedback

This information center is powered by Eclipse technology. (http://www.eclipse.org)