MODULE 12 · JCL AND BATCH JOBS · 6/9

Return codes and COND

18 min30 XPExercise

Every step leaves a return code. COND lets later steps look at those codes and decide whether to run. It is also the most misread parameter in JCL, because it works backwards.

COND=(code,operator)

//POST     EXEC PGM=PAYPOST,COND=(8,LE)

Read it as: skip this step if 8 LE the return code of any earlier step. That is, skip if 8 ≤ RC, so the step runs only while every earlier RC is below 8.

The code comes first and the RC comes last, so say it out loud as "code operator RC":

COND Step is skipped when a previous RC is So it runs when all RCs are
(0,NE) anything but 0 0
(4,LT) 5 or more 0–4
(8,LE) 8 or more 0–7
(8,GT) 0–7 8 or more
(4,EQ) exactly 4 anything but 4

Operators are GT, GE, EQ, NE, LT and LE. A step that is skipped is flushed. It has no return code, doesn't count in later tests, and the job log says so:

  IEF142I PAYJOB VALIDATE - STEP WAS EXECUTED - COND CODE 0008
  IEF202I PAYJOB POST - STEP WAS NOT RUN BECAUSE OF CONDITION CODES
  IEF142I PAYJOB ALERT - STEP WAS EXECUTED - COND CODE 0000

The test looks at every previous step that ran, not only the one just before. That's why ALERT above uses COND=(8,GT). Had POST run and ended with RC 0, the test 8 GT 0 would be true and ALERT would be skipped too, which is exactly right: if posting happened, there's nothing to alert about.

After an abend

When a step abends, the system flushes every following step, whatever its COND says, except:

  • COND=EVEN: run this step even if an earlier step abended.
  • COND=ONLY: run this step only if an earlier step abended.
//CLEANUP  EXEC PGM=IEFBR14,COND=EVEN
//BACKOUT  EXEC PGM=PAYBACK,COND=ONLY

A JCL error is different: it stops the job there and then. No later step runs, EVEN and ONLY included.

The job's MAXCC

The job log ends with the highest return code of any step:

  $HASP395 PAYJOB ENDED - MAXCC=0008

Schedulers use it to decide whether the job "worked". Many sites treat MAXCC 4 as success and 8 as a failure that stops the schedule.

More than the simulator does

Real COND can name a step, COND=(4,LT,VALIDATE), so only that step's RC is tested. It can hold up to eight tests, COND=((8,LE),(4,EQ,STEP1)), and the step is skipped if any is true. COND on the JOB statement applies to every step. Modern JCL also has IF/THEN/ELSE/ENDIF, which reads the right way round:

// IF (VALIDATE.RC < 8) THEN
//POST     EXEC PGM=PAYPOST
// ELSE
//ALERT    EXEC PGM=PAYALERT
// ENDIF

Many shops prefer IF for new jobs, but you'll maintain plenty of old jobs full of COND, so you must be able to read both.

On the job

When someone asks "why didn't step 5 run last night?", open the job log, find the IEF202I line, then list the RCs of every step before it and test each against the COND. Nine times out of ten, a warning RC 4 from a step nobody was watching tripped a (0,NE).

Your task

The payments job has three steps, but right now every step runs every night. Add COND parameters so that:

Step Program Runs when
VALIDATE PAYVAL always (it's first)
POST PAYPOST VALIDATE ended with RC below 8
ALERT PAYALERT VALIDATE ended with RC 8 or more

PAYVAL ends with RC 0 when every payment is valid, RC 4 when some are invalid (the valid ones still get posted), and RC 8 when there is nothing valid to post.

Don't change the DD statements or the step names. When POST is skipped, BANK.PAYMENTS.POSTED must not be created.

Check your understanding

1. STEP1 ended RC 4. STEP2 has COND=(4,LT). Does STEP2 run?
2. Which COND makes a step run only if every earlier step ended RC 0?
3. STEP2 abends. STEP3 has COND=(8,LT). What happens to STEP3?
4. In the job log you see IEF202I ... STEP WAS NOT RUN BECAUSE OF CONDITION CODES. What happened?
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.