Temporary datasets and SYSOUT
Batch jobs are pipelines. One step extracts, the next sorts, the next reports. The data flowing between steps is often useless once the job ends, so there's no point giving it a permanent name and cataloging it.
Temporary datasets
A dataset name that starts with && is temporary. It exists only
while the job runs, and the system deletes it at the end of the job no
matter what disposition you code.
//EXTRACT EXEC PGM=ODEXTR
//ACCTIN DD DSN=BANK.ACCOUNTS,DISP=SHR
//ODOUT DD DSN=&&OVERDRN,DISP=(NEW,PASS)
//SUMMARY EXEC PGM=ODSUMM
//ODIN DD DSN=&&OVERDRN,DISP=(OLD,DELETE)
//ODRPT DD DSN=BANK.OVERDRAWN.REPORT,DISP=(NEW,CATLG,DELETE)
PASS means "keep this for a later step in this job". The second step
refers to the same &&OVERDRN name with status OLD (it exists now)
and deletes it once it's been read. If a third step also needed it, the
second would use DISP=(OLD,PASS) instead. The job log shows the
hand-off:
IEF285I &&OVERDRN PASSED
IEF142I ODRPTJOB EXTRACT - STEP WAS EXECUTED - COND CODE 0000
IEF237I ODIN ALLOCATED TO &&OVERDRN
IEF237I ODRPT ALLOCATED TO BANK.OVERDRAWN.REPORT
IEF285I &&OVERDRN DELETED
Notice that ODEXTR writes to DD ODOUT and ODSUMM reads DD ODIN.
The programs never agree on a DD name; the JCL connects them by pointing
both DDs at the same dataset.
On real z/OS, &&OVERDRN becomes a system-generated name such as
SYS26267.T020000.RA000.ODRPTJOB.OVERDRN, and you'll see that in the
job log. Real JCL also lets a later DD refer back to an earlier one
with DSN=*.EXTRACT.ODOUT (step name, DD name) instead of repeating the
name; the simulator only supports repeating the && name.
SYSOUT: output for people
Not every output is a dataset. Reports, messages and dumps are for people
to read, and they go to the spool with SYSOUT:
//SYSOUT DD SYSOUT=*
//REPORT DD SYSOUT=*
//AUDIT DD SYSOUT=A
* means "the same output class as the job's MSGCLASS". A letter picks
a specific class; each site decides which classes print, which are held
for viewing in SDSF and which are archived.
A COBOL DISPLAY goes to the SYSOUT DD in IBM Enterprise COBOL, so give
every COBOL step a //SYSOUT DD SYSOUT=*. Utilities have their own fixed
names: SYSPRINT for messages, SYSOUT for DFSORT. A COBOL output file
can also go straight to the spool: if SELECT RPT-FILE ASSIGN TO REPORT
and //REPORT DD SYSOUT=*, every WRITE becomes a line of printed
output.
DUMMY
DD DUMMY is a DD with no dataset behind it. A program that reads it
gets end-of-file immediately; anything written to it is thrown away. It's
handy for switching off an optional input or an unwanted report without
changing the program:
//EXCEPTS DD DUMMY
In the simulator
The simulator collects every DISPLAY into the step's SYSOUT
output, whether or not you code the DD. On z/OS a missing SYSOUT
DD makes the runtime allocate one dynamically at best, or lose the
messages at worst. Code it anyway.
On the job
Temporary datasets make a job easy to rerun: there's nothing left
over to clean up. The trade-off is that you can't inspect them after
the job ends. When you're debugging a pipeline, temporarily change
&&WORK to a real cataloged name such as YOURID.DEBUG.WORK so you
can browse what the first step produced.
Your task
The collections team's overdrawn report is built in two steps. Finish the job.
Step EXTRACT runs ODEXTR. It reads DD ACCTIN
(BANK.ACCOUNTS, shared) and writes every overdrawn account to DD
ODOUT. That output is only needed by the next step, so make it a
temporary dataset named &&OVERDRN, passed on to step 2.
Step SUMMARY runs ODSUMM. It reads the overdrawn accounts from
DD ODIN (the temporary dataset; delete it when the step is done)
and writes the report to DD ODRPT: a new dataset
BANK.OVERDRAWN.REPORT, cataloged, deleted if the step abends.
Both programs display a count, so both steps need a SYSOUT DD
(SYSOUT=*).