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.
| 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.
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).
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.
//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.
%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;