Showing posts with label JCL IF THEN ELSE. Show all posts
Showing posts with label JCL IF THEN ELSE. Show all posts

Saturday, 10 August 2013

JCL IF THEN ELSE ENDIF: RC, ABEND, and RUN Examples

A batch job should run LOADSTEP only when VALIDATE ends with RC 0 or 4. JCL IF THEN ELSE ENDIF expresses that rule directly: JES evaluates the condition after the earlier step finishes, runs the matching branch, and continues after the closing ENDIF.

JCL IF THEN ELSE ENDIF RC ABEND and RUN examples showing true and false job-step branches
JCL evaluates the IF expression at execution time and runs either the THEN branch or the ELSE branch.

JCL IF THEN ELSE ENDIF syntax

Code the construct after the JOB statement. The IF statement contains a relational expression followed by THEN. ELSE is optional, but every construct requires a matching ENDIF. The expression is evaluated at execution time from results produced before the IF statement.

//CHKRC    IF (VALIDATE.RC LE 4) THEN
//LOADSTEP EXEC PGM=PRODLOAD
//INFILE   DD DSN=APP.INPUT.VALID,DISP=SHR
//         ELSE
//ERRSTEP  EXEC PROC=ERRPROC
//         ENDIF

When VALIDATE.RC is 0 through 4, LOADSTEP runs. A higher return code selects ERRSTEP. Replace the program, procedure, and DD names with those used by the application.

Execution rule: THEN handles a true expression; ELSE handles a false expression. This is easier to read than a COND test whose true result bypasses the step.

Test a specific step return code

Use stepname.RC when the decision belongs to one earlier job step. Return codes are numeric values from 0 through 4095. Step names remove doubt when several prior programs have produced different return codes.

//RUNRPT   IF (SORTSTEP.RC EQ 0) THEN
//REPORT   EXEC PGM=RPTGEN
//SYSOUT   DD SYSOUT=*
//         ENDIF

This example runs REPORT only after SORTSTEP returns exactly zero. If SORTSTEP did not execute, an expression that references SORTSTEP.RC evaluates as false. That behavior matters when an earlier IF, COND parameter, restart, or error prevented the step from starting.

Understand unqualified RC

When no step name is present, RC means the highest return code produced by prior steps that executed. A step that did not start, was cancelled, or ended abnormally does not contribute a return code to that value. At the beginning of job execution, RC is initially zero.

//CONTINUE IF (RC LE 4) THEN
//NEXTSTEP EXEC PGM=APPLYUPD
//         ELSE
//STOPPATH EXEC PROC=ERRPROC
//         ENDIF
Scope check: use unqualified RC only when the rule genuinely depends on the highest earlier return code. If the rule belongs to one program, name that step explicitly.

Use comparison and logical operators

PurposeAlphabetic formSymbol formExample
EqualEQ=STEP1.RC EQ 0
Not equalNE¬=STEP1.RC NE 4
Greater / greater or equalGT / GE> / >=RC GT 8
Less / less or equalLT / LE< / <=STEP1.RC LE 4
Logical ANDAND&A.RC EQ 0 AND B.RC EQ 0
Logical OROR|RC EQ 8 OR RC EQ 12
NegationNOT¬NOT STEP1.ABEND

NOT is evaluated first, comparisons second, and logical operators third. Operators at the same priority are processed in coded order. Parentheses make mixed AND and OR expressions easier to review and protect the intended grouping.

Combine RC conditions safely

//GOODRUN  IF ((EXTRACT.RC LE 4) AND
//             (SORTSTEP.RC EQ 0)) THEN
//LOAD     EXEC PGM=LOADDB
//         ELSE
//REJECT   EXEC PROC=ERRPROC
//         ENDIF

The continued expression breaks where a blank is valid. Continue it in columns 4 through 16 of the next JCL statement, and do not place a comment on a statement being continued. Comments can follow after the expression is complete.

For multiple accepted return codes, an OR expression is clearer than a broad range when intermediate values have different meanings:

//ACCEPT   IF ((CHECK.RC EQ 0) OR
//             (CHECK.RC EQ 4)) THEN
//PROCESS  EXEC PGM=DAILYRUN
//         ENDIF

Test ABEND and ABENDCC

ABEND tests whether an earlier job step ended abnormally. Qualify it with a step name when recovery belongs to one step. ABENDCC can test a system completion code such as S0C7 or a user completion code such as U0100.

//BADPACK  IF (CALCSTEP.ABENDCC = S0C7) THEN
//C7PATH   EXEC PROC=ERRPROC
//         ENDIF

//ANYABND  IF (ABEND) THEN
//ABNDPATH EXEC PROC=ERRPROC
//         ENDIF

An IF test is not a universal recovery mechanism. IBM documents abnormal termination cases that prevent either branch from executing regardless of an ABEND test. Preserve the normal scheduler, restart, dump, and operations procedures for failures that stop job processing.

Use RUN when execution itself matters

The RUN keyword tests whether a named step started execution. It helps distinguish “the step did not run” from “the step ran and returned a value.” Its negative form tests that the step did not start.

//DIDRUN   IF (EXTRACT.RUN) THEN
//AUDIT    EXEC PGM=AUDITLOG
//         ENDIF

//SKIPPED  IF (NOT EXTRACT.RUN) THEN
//NOTICE   EXEC PROC=NOTIFY
//         ENDIF

Use a site procedure or program that actually exists; the names above show the control structure. The JCL RESTART guide explains how restart selection changes which earlier steps execute.

Reference a step inside a procedure

For a step within a called procedure, qualify the test with both the job-step name and procedure-step name. The form is jobstep.procstep.RC. This prevents a procedure's internal step name from being confused with a top-level step.

//BLDAPP   EXEC PROC=BUILDPRC
//LINKOK   IF (BLDAPP.LINK.RC LE 4) THEN
//RUNTEST  EXEC PGM=APPTEST
//         ELSE
//FAILBLD  EXEC PROC=ERRPROC
//         ENDIF

Confirm the expanded procedure in the job listing before relying on the qualifier. See the JCL procedure guide for cataloged and in-stream procedure structure.

Know what can appear in a branch

Either the THEN clause or the ELSE clause must contain at least one EXEC statement; otherwise the construct has no executable branch. EXEC and its associated DD statements can be conditional, as can nested IF constructs and several step-level output or dump DD statements.

Do not place JOB, JCLLIB, JOBLIB, job-level SYSCHK, or XMIT statements inside a conditional branch. PROC, PEND, INCLUDE, comments, delimiter statements, null statements, and JES statements can appear there, but JES processes them regardless of the IF result.

Review the expanded JCL: an INCLUDE inside a false branch is still processed. The steps brought in by it can be conditional, but the inclusion operation itself is not controlled by the IF result.

Nest IF constructs with restraint

z/OS JCL permits up to 15 levels of IF/THEN/ELSE/ENDIF nesting. Each IF requires its own ENDIF. Give meaningful names to complex IF statements and indent examples consistently so an operator can match each ELSE and ENDIF during an incident.

//OKCOPY   IF (COPYSTEP.RC EQ 0) THEN
//HASDATA  IF (CHECK.RC EQ 0) THEN
//LOAD     EXEC PGM=LOADDB
//         ELSE
//EMPTY    EXEC PROC=NODATAP
//         ENDIF
//         ELSE
//COPYERR  EXEC PROC=ERRPROC
//         ENDIF

Shallow constructs are easier to restart and diagnose. If several branches repeat the same DD statements, consider a procedure with symbolic parameters rather than adding more nesting.

IF THEN ELSE versus COND

IF/THEN/ELSE/ENDIF executes the THEN branch when its expression is true. A COND parameter works as a bypass test: when its comparison is true, the associated step is skipped. That inverse reading is the source of many maintenance errors.

Use IF constructs for new multi-step branching where readability matters. Keep the separate JCL COND parameter guide for existing procedures and step-level bypass rules. The JCL EXEC guide covers where COND, PARM, REGION, and procedure calls belong, while the JCL tutorial provides the JOB, EXEC, and DD structure around these examples.

Common errors and checks

SymptomLikely causeCheck
THEN branch never runsReferenced step did not executeCheck the job log, preceding conditions, and stepname.RUN.
Unexpected branch runsUnqualified RC used the highest prior return codeReplace RC with the intended stepname.RC.
JCL conversion errorMissing THEN, ENDIF, parentheses, or valid continuationMatch each IF to one ENDIF and inspect statement columns.
Expression groups incorrectlyMixed AND and OR without clear parenthesesParenthesize each comparison and the intended Boolean groups.
ABEND recovery step does not runThe failure prevented continued job processingUse the job log and site recovery procedure; not every abend permits IF evaluation.
Procedure-step test is falseQualifier uses the wrong invocation or procedure step nameCheck the expanded JCL and code jobstep.procstep.RC.

Production checklist

  • Name the exact earlier step when the condition belongs to one result.
  • Use unqualified RC only for a deliberate highest-prior-return-code rule.
  • Use RUN when a skipped step must be distinguished from a completed step.
  • Use ABENDCC only for a specific documented recovery path.
  • Parenthesize combined conditions and verify operator order.
  • Match every IF with ENDIF and keep nesting far below the 15-level limit.
  • Ensure at least one of the THEN or ELSE clauses contains an EXEC statement.
  • Review expanded procedures, INCLUDE members, and restart behavior.
  • Test RC 0, RC 4, a failing RC, a skipped step, and an abend path.

Official IBM references

JCL IF THEN ELSE ENDIF FAQ

What does RC mean in a JCL IF statement?

RC is a return-code keyword. Without a step name, it represents the highest return code from prior steps that executed. With a qualifier such as STEP1.RC, it tests that specific step's return code.

What happens if a referenced JCL step did not run?

When an IF expression names a step that did not execute, the expression for that step evaluates as false. Use the RUN keyword when the distinction between not run and a completed return code matters.

Can JCL IF THEN ELSE statements be nested?

Yes. z/OS JCL supports up to 15 levels of IF/THEN/ELSE/ENDIF nesting. Keep nesting shallow so operators, step names, and matching ENDIF statements remain easy to verify.

Is JCL IF THEN ELSE better than the COND parameter?

IF/THEN/ELSE/ENDIF usually reads more directly because its true branch runs, while a true COND test bypasses a step. Existing procedures can still use COND, so choose one clear style and verify its exact execution rule.

When a conditional job takes the wrong path, check whether the named step actually ran before changing the comparison; a valid return-code test cannot succeed for a step that never started.

New In-feed ads