Showing posts with label z OS batch jobs. Show all posts
Showing posts with label z OS batch jobs. Show all posts

Wednesday, 10 April 2019

JCL System Affinity: Run a Job on a Specific System

//PAYROLL JOB (ACCT),'NIGHTLY',CLASS=A,MSGCLASS=X
/*JOBPARM SYSAFF=SYS2
//STEP1   EXEC PGM=PAYRUN

This JCL system affinity example makes SYS2 the eligible JES2 member for the job. Use /*JOBPARM SYSAFF=SYS2 when a batch step depends on a Db2 subsystem, locally installed product, private load library, device, or test configuration that is not available on every member of the JES2 multi-access spool complex.

JCL system affinity routing a batch job through SYSAFF to the eligible SYS2 member
SYSAFF limits a JES2 batch job to the named eligible member or members.

JES2 SYSAFF syntax and placement

Code the JES2 /*JOBPARM control statement directly after the JOB statement in a normal input stream. It begins with /*, not //. The member identifiers are installation-defined names, so copy them from a working job or confirm them with operations before submission.

//DB2LOAD JOB (ACCT),'LOAD',CLASS=A,MSGCLASS=X
/*JOBPARM SYSAFF=SYS2
//LOAD     EXEC PGM=DSNUTILB
//STEPLIB  DD  DSN=DB2.SYS2.SDSNLOAD,DISP=SHR

This request restricts both conversion and execution to SYS2. It does not make an inactive member active, bypass job-class rules, or prove that the named Db2 subsystem is available. The step still needs valid DD statements, libraries, security access, and an initiator or WLM-managed class that can select it.

Site-specific control: some installations restrict user-coded JOBPARM values or set affinity through a scheduler, exit, input device, or JOB statement. Keep the site-approved form when it differs from a portable example.

Choose one member, several members, or any member

JES2 valueEligible execution membersTypical use
SYSAFF=SYS2SYS2 onlyA subsystem or product exists only on SYS2.
SYSAFF=(SYS1,SYS2)Either SYS1 or SYS2The required service exists on two members.
SYSAFF=*The member that reads the jobKeep processing on the input member.
SYSAFF=ANYAny eligible memberRemove a narrower affinity when site rules permit.

A list is an eligibility set, not a sequence. SYSAFF=(SYS1,SYS2) does not tell JES2 to try SYS1 first. JES2 applies class, priority, member state, scheduling-environment, security-label, and other selection rules before a member starts the job.

Use SCHENV when the dependency is a resource

//CICSRPT JOB (ACCT),'REPORT',CLASS=A,MSGCLASS=X,
//             SCHENV=CICSREGN

SCHENV= names a WLM scheduling environment. That environment contains resource requirements and their required states. A job can execute on a system where those requirements are satisfied, so operations can change eligibility by changing resource states without editing the JCL.

Use SYSAFF for a static member restriction. Use SCHENV when the real requirement is an available resource, such as a subsystem or application region. They can be combined, but the intersection must contain at least one eligible active system or the job waits. IBM also distinguishes their timing: SYSAFF controls conversion and execution, while SCHENV controls execution after conversion.

Scheduler practice: if your enterprise scheduler already assigns affinity or a scheduling environment, change its job definition or variable rather than hard-coding a second restriction in production JCL.

JES3 SYSTEM syntax

In a JES3 environment, the equivalent JECL form is the //*MAIN SYSTEM= statement. Use it only when the target installation runs JES3 and its standards call for this form.

//RPTJOB  JOB (ACCT),'REPORT',CLASS=A,MSGCLASS=X
//*MAIN SYSTEM=(MVSA,MVSC)
//STEP1   EXEC PGM=RPTPGM

SYSTEM=ANY permits any qualifying global or local system, SYSTEM=JGLOBAL selects the global processor, and SYSTEM=JLOCAL selects a local processor. A list such as SYSTEM=(MVSA,MVSC) names eligible processors. The selected processor must support the job class and any specifically requested devices or JES3-controlled resources.

System affinity is not remote-node routing

JES2 SYSAFF selects a member of the local JES2 MAS. It does not route a job to an unrelated NJE node. Remote execution uses facilities such as XMIT or JES routing controls defined by the installation. The JCL JECL statements reference owns that broader statement and routing intent.

Intent boundary: use this page to choose a local eligible execution system. Use the JECL reference for ROUTE, XEQ, XMIT, output routing, and JES statement placement.

Diagnose a job waiting for the target system

A job restricted to SYS2 remains queued when no eligible SYS2 initiator or WLM-managed class can select it. For JES2, an operator or authorized user can display detailed status with:

$DJ'PAYROLL',LONG

If the display reports SYSAFF, check that the coded member name exists, the member is active, its independent-mode state matches the request, and the job class is selectable there. If it reports SCHENV, find the required environment in the long display and check its state by system:

D WLM,SCHENV=CICSREGN

A scheduling-environment delay can mask another reason that the job is ineligible. After the environment becomes available, review the job again for class limits, held execution, security-label affinity, duplicate job name, or other member-status restrictions.

Common system-affinity mistakes

SymptomWhat to check
JCL or JES syntax errorConfirm /*JOBPARM starts in column 1, uses no //, and contains a valid site-defined member name.
Job waits with SYSAFF statusCheck member activity, independent mode, class selection, and whether a scheduler replaced the affinity.
Job waits with SCHENV statusUse the WLM display to find which required resource state is unavailable on eligible systems.
Job runs on an unexpected memberInspect the submitted JCL, scheduler variables, JOB statement, input-device defaults, and exit changes rather than only the source member.
Program fails after correct routingAffinity only selects a system. Check STEPLIB, subsystem name, DD allocation, authorization, and product startup separately.
Remote node never receives the jobUse the site's NJE routing method; SYSAFF is not a substitute for XMIT or ROUTE XEQ.

Production checklist

  • Confirm whether the installation uses JES2, JES3, or scheduler-managed routing.
  • Verify the exact JES member name; do not assume the z/OS system name is identical.
  • Choose a named affinity only when the job has a real system-local dependency.
  • Prefer SCHENV when a resource state, rather than a permanent member name, defines eligibility.
  • Check that at least one eligible system can select the job class.
  • Confirm required subsystems, load libraries, devices, and security access on every eligible member.
  • Review the scheduler's generated JCL so that two restrictions do not produce an empty eligible set.
  • Use the long JES2 job display when the job waits.

For the JOB, EXEC, and DD relationship, see the JCL tutorial with examples. The JCL JOB statement guide covers job-level fields, and the JCL parameter-field guide explains positional and keyword coding.

Official IBM references

JCL system affinity FAQ

What does SYSAFF=* mean in JES2?

SYSAFF=* gives the job affinity to the JES2 member that reads the job. It is useful when the work must remain on that input member, but a named member is clearer when a scheduler or submission path can vary.

Can SYSAFF name more than one system?

Yes. A list such as SYSAFF=(SYS1,SYS2) makes either member eligible. JES2 selects an eligible member according to the rest of its job-selection rules; the list does not specify a preference order.

Why is a job delayed for SYSAFF?

The named JES2 members may be inactive, unable to select the job, or incompatible with the job's independent-mode requirement. Display the job with the JES2 long form and confirm the member name, state, class, scheduling environment, and security-label restrictions.

What is the difference between SYSAFF and SCHENV?

SYSAFF is a static list of eligible JES members and affects conversion and execution. SCHENV names a WLM scheduling environment whose resource states determine where the job may execute; it does not select the conversion system.

Code the narrowest eligible set that still has a live path to execution, then verify the submitted job rather than assuming the scheduler preserved the source JCL unchanged.

Monday, 8 April 2019

JCL TYPRUN Parameter: COPY, HOLD, JCLHOLD, and SCAN

A batch job has been changed, but you do not want it to allocate a data set or run a program until its JCL receives an initial syntax check. Add TYPRUN=SCAN to the JOB statement. JES sends the job through converter-level checking without executing its steps or allocating devices.

JCL TYPRUN COPY HOLD JCLHOLD and SCAN processing paths for a z/OS batch job
TYPRUN changes how JES handles a submitted job before normal step execution.

What the JCL TYPRUN parameter does

TYPRUN is an optional keyword parameter on the JOB statement. It requests special processing for the submitted job. Depending on the value and JES type, the system can print the submitted job stream, hold the job, stop JCL processing at an earlier point, or scan the JCL without running it.

ValueJES supportWhat happensDoes the job execute?
COPYJES2 onlyCopies the submitted input job stream to a SYSOUT data set controlled by the JOB statement's MSGCLASS.No
HOLDJES2 and JES3Holds the job before execution until an operator releases it.Only after release
JCLHOLDJES2 onlyHolds the job before JCL processing is completed until an operator releases it.Only after release and successful JCL processing
SCANJES2 and JES3Checks JCL syntax through the converter without running the job or allocating devices.No
Started-task restriction: do not specify TYPRUN for a started task. IBM states that a started task containing this parameter fails.

TYPRUN syntax on the JOB statement

Code one value on the JOB statement. The exact account information, programmer name, class, notification setting, and message options depend on local standards.

//CHKJCL   JOB (ACCT),'JCL CHECK',CLASS=A,MSGCLASS=X,
//             NOTIFY=&SYSUID,TYPRUN=SCAN
//STEP01   EXEC PGM=IEFBR14

The continued JOB statement ends its first line with a comma. Remove TYPRUN=SCAN before submitting the job for normal execution.

Use TYPRUN=SCAN to check JCL without execution

TYPRUN=SCAN is the value most developers use while checking a new or changed job. JES does not run any EXEC statement and does not allocate the DD statement devices. The converter can report issues such as invalid parameter-keyword spelling, invalid characters, unbalanced parentheses, misplaced positional parameters, and bad syntax in cataloged procedures invoked by scanned EXEC statements.

//PAYSCAN  JOB (ACCT),'PAY TEST',CLASS=A,MSGCLASS=X,
//             NOTIFY=&SYSUID,TYPRUN=SCAN
//SORT01   EXEC PGM=SORT
//SORTIN   DD DSN=PAY.INPUT,DISP=SHR
//SORTOUT  DD DSN=PAY.OUTPUT,
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(5,2)),UNIT=SYSDA
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
  SORT FIELDS=(1,10,CH,A)
/*

Review the job's JES messages after submission. Converter messages commonly begin with IEFC. A clean scan means the converter accepted the statements it checked; it does not prove that every data set exists, every program is available, or every runtime path will succeed.

What TYPRUN=SCAN can miss

IBM documents that SCAN checks only through the converter, not the interpreter. It does not catch every invalid subparameter, misplaced statement, or incompatible parameter combination. For example, a data-set qualifier longer than eight characters can pass the scan and fail later during interpreter processing.

Release check: never treat a successful scan as permission to run production work without the normal peer review, scheduler controls, data-set checks, and change process.

Use TYPRUN=HOLD to delay execution

TYPRUN=HOLD places the job on hold before execution. An operator must release it before JES can select it to run. This can be useful when a job must wait for a controlled event outside the scheduler, but a production scheduler should normally own production dependencies.

//PAYHOLD  JOB (ACCT),'PAYROLL',CLASS=A,MSGCLASS=X,
//             NOTIFY=&SYSUID,TYPRUN=HOLD
//STEP01   EXEC PGM=PAYRUN
//SYSOUT   DD SYSOUT=*

HOLD is supported with JES2 and JES3. Release commands and authority rules differ by installation. Follow the site's operations procedure rather than assuming that a developer ID can release the job.

Use TYPRUN=JCLHOLD to hold before completed JCL processing

TYPRUN=JCLHOLD is a JES2-only value. JES2 holds the job before completing JCL processing. After the operator releases the job, JCL processing continues. If pending errors surface while JCL processing is completed, JES2 does not keep the job held; it completes JCL processing and places the job in the output queue.

//JCLWAIT  JOB (ACCT),'WAIT FOR JCL',CLASS=A,MSGCLASS=X,
//             NOTIFY=&SYSUID,TYPRUN=JCLHOLD
//STEP01   EXEC PGM=MYPROG
//SYSOUT   DD SYSOUT=*

This behavior differs from the old explanation that JCL errors are simply checked when the operator releases the job. The timing of JCL processing and the treatment of pending error messages are the points that matter.

Use TYPRUN=COPY to print the submitted job stream

TYPRUN=COPY is also JES2 only. JES2 copies the submitted input stream directly to a SYSOUT data set and schedules that output for processing. The job is not selected for execution. The output class is the JOB statement's MSGCLASS.

//COPYJCL  JOB (ACCT),'COPY JCL',CLASS=A,MSGCLASS=X,
//             TYPRUN=COPY
//STEP01   EXEC PGM=IEFBR14

Use COPY when the submitted JCL itself must be routed to output. It is not a substitute for SCAN because its purpose is copying the input stream, not validating execution readiness.

TYPRUN=HOLD versus TYPRUN=JCLHOLD

QuestionHOLDJCLHOLD
Supported JES typesJES2 and JES3JES2 only
Hold pointBefore executionBefore completed JCL processing
Release requiredYesYes
Normal useDelay a converted job before executionDelay completion of JCL processing
What an error can doAn input-service error can prevent the holdPending JCL errors can cause completion into the output queue instead of a continued hold

TYPRUN and workload schedulers

Do not leave TYPRUN=SCAN, HOLD, or JCLHOLD in production scheduler JCL unless the scheduler and operations procedures require it. A scheduled job that never executes can remain outside the expected tracking path. IBM specifically warns against storing TYPRUN=SCAN jobs in IBM Z Workload Scheduler's EQQJBLIB because the scheduler does not track those test submissions.

A safer change flow is to copy the JCL to a developer-controlled library, add TYPRUN=SCAN, submit and review the JES messages, remove the parameter, then return the approved member through the site's normal change process.

Common TYPRUN mistakes

  • Expecting SCAN to find every error: it performs converter-level checking and can miss interpreter-time faults.
  • Leaving SCAN in the production member: the job is submitted but none of its steps execute.
  • Using COPY or JCLHOLD under JES3: both values are JES2 only.
  • Using TYPRUN on a started task: IBM states that the started task fails.
  • Assuming HOLD manages job dependencies: an enterprise scheduler is usually the correct owner of recurring production dependencies.
  • Expecting SCAN to verify resources: it does not prove that a program, data set, catalog entry, security profile, tape volume, or temporary-space request will work at execution time.
  • Using an installation-specific held class without checking: held job classes are defined locally and should not be copied blindly from another system.

TYPRUN testing checklist

  1. Work from the approved test copy of the JCL.
  2. Add TYPRUN=SCAN to the JOB statement.
  3. Submit the job and confirm that no program step executed.
  4. Review JES converter messages and correct reported JCL errors.
  5. Check data-set names, DISP values, program names, procedures, symbolic parameters, security access, and scheduler variables separately.
  6. Remove TYPRUN=SCAN.
  7. Submit through the normal test or production-control process.

Related JCL guides

Official IBM references

JCL TYPRUN questions

Does TYPRUN=SCAN execute any job steps?

No. JES scans the JCL through the converter without executing the job or allocating devices.

Does TYPRUN=SCAN find every JCL error?

No. It can find many syntax faults, but it does not perform every interpreter-time check and does not verify runtime resources.

What is the difference between HOLD and JCLHOLD?

HOLD delays the job before execution and works with JES2 or JES3. JCLHOLD is JES2 only and stops the job before JCL processing is completed.

Can TYPRUN be used for a started task?

No. IBM states that a started task fails when TYPRUN is specified.

Working rule: use SCAN for an initial converter check, remove it before execution, and still review the resources and controls that SCAN cannot validate.

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