MODULE 12 · JCL AND BATCH JOBS · 3/9

DD statements and DISP

18 min30 XPExercise

Most of the JCL you write is DD statements. The COBOL program only knows DD names; the DD statement decides which dataset each one is, and what happens to that dataset before and after the step.

The common DD forms

//ACCTIN   DD DSN=BANK.ACCOUNTS,DISP=SHR           existing dataset
//REPORT   DD DSN=BANK.REPORT,DISP=(NEW,CATLG,DELETE)  new dataset
//SYSOUT   DD SYSOUT=*                              to the spool
//CARDS    DD DUMMY                                 empty input, output discarded
//SYSIN    DD *                                     data inline in the JCL
20260924
/*

DSN (or DSNAME) is the dataset name: up to 44 characters in qualifiers of 1–8 characters separated by dots.

DISP=(status,normal,abnormal)

Status says what state the dataset is in when the step starts:

Status Meaning
NEW Create it. JCL error if it already exists
OLD It exists; I want it exclusively (to rewrite or delete it)
SHR It exists; others may read it at the same time
MOD Append to it. If it doesn't exist, create it

Normal disposition applies when the step ends, with any return code:

Disposition Meaning
KEEP Keep it
CATLG Keep it and record it in the catalog so later jobs find it by name
DELETE Delete it
PASS Keep it for a later step in this job (next lesson)

Abnormal disposition applies only if the step abends. If you leave it out, the normal disposition is used for both.

The three positions are positional, so DISP=(,CATLG) means "status defaulted to NEW, catalog it". DISP=SHR on its own means (SHR,KEEP).

Choosing dispositions

Think about the rerun. A job abends at 3 a.m.; someone fixes the problem and resubmits. Will it work?

  • Output: DISP=(NEW,CATLG,DELETE). After an abend the partial output is deleted, so the rerun's NEW doesn't fail with a duplicate name.
  • Input consumed by the step: DISP=(OLD,DELETE,KEEP). It is deleted only once processed successfully; after an abend it is still there to rerun.
  • Reference data: DISP=SHR, never OLD. OLD locks it and holds up every other job that reads it.
  • Logs and accumulating files: DISP=(MOD,CATLG).

IEFBR14: the program that does nothing

IEFBR14 is a two-instruction IBM program that just returns. So why run it? Because the system still allocates and disposes of every DD in the step. That makes it the standard tool for creating and deleting datasets:

//CLEANUP  EXEC PGM=IEFBR14
//OLDREJ   DD DSN=BANK.TRAN.REJECTS,DISP=(MOD,DELETE)
//NEWFILE  DD DSN=BANK.TRAN.EMPTY,DISP=(NEW,CATLG)

Here DISP=(OLD,DELETE) would be a trap: on a night with no rejects the job fails before anything runs:

  IEF212I DELJOB DELETE DATA SET NOT FOUND - OLDREJ DSN=BANK.TRAN.REJECTS

and NEW on a dataset that already exists fails with DUPLICATE NAME ON DIRECT ACCESS VOLUME.

What real NEW datasets also need

On z/OS a new dataset needs space and a record format, for example SPACE=(TRK,(10,5),RLSE), DCB=(RECFM=FB,LRECL=80,BLKSIZE=0) and UNIT=SYSDA, or a site default (SMS) that supplies them. The simulator doesn't need them, but you'll see them on almost every output DD at work. Also note that a real DD with no DISP at all defaults to (NEW,DELETE): the dataset vanishes at the end of the step. Always code DISP.

On the job

A frequent cause of a night-shift call is a rerun failing with "duplicate name" because the first run used (NEW,CATLG,CATLG) and left a half-written output behind. Many shops add an IEFBR14 cleanup step with DISP=(MOD,DELETE) at the start of the job so it can always be rerun from the top.

Your task

Finish the daily transaction job. Every night it must:

  1. CLEANUP: run IEFBR14 to delete yesterday's BANK.TRAN.REJECTS. On some nights there are no rejects and the dataset doesn't exist; the step must work either way. Use the DD name OLDREJ.
  2. POST: run POSTLOG, which reads the day's transactions, appends the valid ones to the history log and writes the invalid ones to a new rejects dataset:
DD Dataset What should happen to it
TRANIN BANK.TRAN.DAILY Must exist. Deleted once posted; kept if the step abends so it can be rerun
TRANLOG BANK.TRAN.HISTORY Appended to. On the very first night it doesn't exist yet and must be created. Always cataloged
REJECTS BANK.TRAN.REJECTS Created new and cataloged; deleted if the step abends
SYSOUT the spool SYSOUT=*

Every record is 18 characters: account X(8), type X (D or C), amount 9(7)V99. POSTLOG displays POSTLOG: nnnnn POSTED, nnnnn REJECTED.

Check your understanding

1. Two jobs read BANK.RATES at the same time. Which DISP lets them both run?
2. What does DISP=(NEW,CATLG,DELETE) do if the step abends?
3. Why do cleanup steps use DISP=(MOD,DELETE) rather than DISP=(OLD,DELETE)?
JCL
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.