MODULE 12 · JCL AND BATCH JOBS · 5/9

Feeding a program with SYSIN and PARM

15 min30 XPExercise

You met ACCEPT in the first module. Now you can see where its input comes from on a mainframe: the step's SYSIN DD. There's a second, smaller channel too: the PARM on the EXEC statement.

Instream data: DD *

//STATS    EXEC PGM=BRSTATS,PARM='DUB1'
//ACCTIN   DD DSN=BANK.ACCOUNTS,DISP=SHR
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
20260924
/*

DD * means "the data follows in the JCL". Every line up to the /* delimiter (or the next // statement) is an 80-byte record. Each ACCEPT reads the next one:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. RUNDATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-RUN-DATE      PIC X(8).
       01  WS-MODE          PIC X(4).
       PROCEDURE DIVISION.
           ACCEPT WS-RUN-DATE
           ACCEPT WS-MODE
           DISPLAY "RUN DATE " WS-RUN-DATE " MODE " WS-MODE
           STOP RUN.

With 20260924 and FULL as the two instream lines, it displays RUN DATE 20260924 MODE FULL. Put instream data in column 1: an ACCEPT into PIC X(8) takes the first eight positions of the record, so a leading blank shifts everything.

SYSIN is used for small control data: the business date, a "full or incremental" switch, a list of branches to process. The same program runs every night; only the cards change. Utilities read their instructions from SYSIN too, as you'll see with DFSORT.

PARM: a short string on the EXEC

//STATS    EXEC PGM=BRSTATS,PARM='DUB1'

PARM passes up to 100 characters to the program. Quote it if it contains commas or special characters: PARM='DUB1,FULL'. In GnuCOBOL, you read it with ACCEPT ... FROM COMMAND-LINE:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SHOWPARM.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-PARM          PIC X(20).
       PROCEDURE DIVISION.
           ACCEPT WS-PARM FROM COMMAND-LINE
           DISPLAY "PARM IS " WS-PARM
           STOP RUN.

PARM in IBM Enterprise COBOL

On z/OS the main program receives PARM through its LINKAGE SECTION: a halfword binary length followed by the text, named on PROCEDURE DIVISION USING:

       LINKAGE SECTION.
       01  LS-PARM.
           05  LS-PARM-LEN   PIC S9(4) COMP.
           05  LS-PARM-TEXT  PIC X(100).
       PROCEDURE DIVISION USING LS-PARM.

Only the first LS-PARM-LEN characters are valid. The idea is the same: a short value from the JCL, read once at the start.

Talking back: RETURN-CODE

Input flows into the program through SYSIN and PARM. The program talks back to the job through its return code. Move a number to the special register RETURN-CODE before STOP RUN, and it becomes the step's condition code in the job log:

           IF WS-COUNT = 0
               MOVE 4 TO RETURN-CODE
           END-IF
           STOP RUN.
  IEF142I BRJOB STATS - STEP WAS EXECUTED - COND CODE 0004

The convention across IBM utilities and most shops:

RC Meaning
0 Everything worked
4 Warning: finished, but look at this (empty input, a few rejects)
8 Error: output is incomplete or wrong
12, 16 Severe: couldn't run at all (bad control cards, missing input)

The next lesson uses these codes to decide which later steps run.

On the job

The business date usually arrives through SYSIN, often from a one-record control dataset shared by the whole night's schedule rather than typed into each job. When a job has to be rerun for last Tuesday, operations change that one card, not your program.

Your task

Write BRSTATS, a branch statistics program that operations run with this JCL:

//STATS    EXEC PGM=BRSTATS,PARM='DUB1'
//ACCTIN   DD DSN=BANK.ACCOUNTS,DISP=SHR
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
20260924
/*
  • The branch code comes from PARM. Read it with ACCEPT WS-BRANCH FROM COMMAND-LINE.
  • The run date is the first SYSIN line. Read it with a plain ACCEPT WS-RUN-DATE.
  • DD ACCTIN is the account file (already declared in the starter):
Field Picture Positions
ACCT-NO X(8) 1–8
ACCT-BRANCH X(4) 9–12
ACCT-NAME X(20) 13–32
ACCT-BALANCE S9(7)V99 SIGN IS LEADING SEPARATE 33–42

Count the accounts of that branch and total their balances, then display:

BRSTATS 20260924 BRANCH DUB1
ACCOUNTS: 00003
BALANCE:      14950.75

If the branch has no accounts, still display the three lines, but end with return code 4 so the job log flags it.

Check your understanding

1. A step has //SYSIN DD * followed by two lines and /*. What does the program's second ACCEPT receive?
2. How long can the PARM text on an EXEC statement be?
3. Why do programs set RETURN-CODE to 4 for 'nothing to do' rather than abending?
fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.