Execution Groups in JCL are logical collections of job steps that are treated as a unit for conditional processing. They provide a powerful way to organize complex job flows and implement sophisticated error handling strategies.
Unlike individual job steps, execution groups allow you to apply conditional logic to multiple steps at once, making it easier to control job flow and implement recovery procedures in complex batch applications.
Execution groups are defined using the IF/THEN/ELSE/ENDIF
construct or by enclosing a set of steps within CNTL/ENDCNTL
statements. Each approach offers different capabilities and is suited to different situations.
This approach allows you to conditionally execute multiple steps based on test conditions.
12345678910111213141516//MYJOB JOB (ACCT),'MY NAME',CLASS=A // IF (RC=0) THEN /* IF the return code from previous step is 0 */ //* ----- BEGINNING OF GROUP ----- //STEP1 EXEC PGM=PROGRAM1 //...DD statements... //STEP2 EXEC PGM=PROGRAM2 //...DD statements... // ENDIF /* END OF GROUP */ // IF (RC >= 4) THEN /* IF return code is 4 or greater */ //* ----- BEGINNING OF ERROR HANDLING GROUP ----- //ERRLOG EXEC PGM=ERRLOGPGM //...DD statements... //NOTIFY EXEC PGM=SENDMAIL //...DD statements... // ENDIF /* END OF GROUP */
The CNTL/ENDCNTL
approach is particularly useful when working with utility programs that support control groups, such as IDCAMS.
123456789101112131415161718192021//MYJOB JOB (ACCT),'MY NAME',CLASS=A //STEP1 EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * DELETE dataset.name SCRATCH PURGE SET MAXCC=0 /* //STEP2 EXEC PGM=IDCAMS //SYSPRINT DD SYSOUT=* //SYSIN DD * /* Beginning of control group */ IF LASTCC=0 THEN DO DEFINE CLUSTER(...) - DATA(...) - INDEX(...) END ELSE DO /* Error handling within control group */ SET MAXCC=8 END /*
Group error handling steps that should execute together when errors occur. This ensures that all required recovery actions take place.
12345678// IF (RC >= 8) THEN //BACKUP EXEC PGM=BAKUPPGM //... //RESTORE EXEC PGM=RESTPGM //... //NOTIFY EXEC PGM=MAILPGM //... // ENDIF
Execute different groups of steps based on the outcome of previous steps, creating branching logic in your job.
1234567891011// IF (RC = 0) THEN //NORMAL EXEC PGM=NORMPRC //... //UPDTMST EXEC PGM=UPDATE //... // ELSE //ERRPROC EXEC PGM=ERRORPRC //... //LOGFAIL EXEC PGM=LOGFAIL //... // ENDIF
Execute different groups of steps based on environmental variables, such as system ID or date.
1234567891011// SET SYSID=&SYSUID // IF (&SYSID = 'PROD') THEN //PRODSTEP EXEC PGM=PRODPGM //... // ELSE IF (&SYSID = 'TEST') THEN //TESTSTEP EXEC PGM=TESTPGM //... // ELSE //DEVSTEP EXEC PGM=DEVPGM //... // ENDIF
Execution groups can be nested within each other to create complex conditional logic. This allows for sophisticated job flows that can handle a variety of conditions and scenarios.
12345678910111213// IF (RC = 0) THEN //STEP1 EXEC PGM=PROGRAM1 //... // IF (DSN='PROD.MASTER') THEN //PRODPROC EXEC PGM=PRODPGM //... // ELSE //TESTPROC EXEC PGM=TESTPGM //... // ENDIF //STEP2 EXEC PGM=PROGRAM2 //... // ENDIF
You can nest up to 15 levels of IF statements in z/OS JCL, though keeping nesting to a reasonable depth improves readability and maintainability.
Feature | Execution Groups (IF/THEN/ELSE) | Individual COND Parameters |
---|---|---|
Scope | Multiple steps as a unit | Single step only |
Readability | More explicit, easier to follow | More compact but can be harder to follow |
Flexibility | Supports complex branching logic | Limited to pre-defined conditions |
Implementation | Added in later versions of z/OS | Traditional approach, available in all versions |
Write JCL that uses IF/THEN/ELSE to create an execution group that runs steps STEP1 and STEP2 only if a previous step ended with RC=0, otherwise runs ERRSTEP.
Create JCL with nested execution groups that implement the following logic: If STEP1 is successful (RC=0), run STEP2. If STEP2 is successful, run STEP3. If STEP2 fails (RC> 0), run ERROR1. If STEP1 fails, run ERROR2.
Write JCL that checks a symbolic parameter ENVIRONMENT and runs different execution groups based on whether it's set to PROD, TEST, or DEV.
12345678910111213141516171819202122232425262728293031323334353637383940414243//DATAJOB JOB (ACCT),'DATA PIPELINE',CLASS=A,MSGCLASS=X //* --------- EXTRACTION PHASE --------- //EXTRACT EXEC PGM=DATAXTRCT //SYSOUT DD SYSOUT=* //INPUT DD DSN=PROD.SOURCE.DATA,DISP=SHR //OUTPUT DD DSN=WORK.EXTRACT.DATA,DISP=(,PASS) //* --------- CONDITIONAL PROCESSING BASED ON EXTRACTION --------- // IF (EXTRACT.RC = 0) THEN //* ----- NORMAL PROCESSING PATH ----- //VALIDATE EXEC PGM=DATAVAL //SYSOUT DD SYSOUT=* //INPUT DD DSN=WORK.EXTRACT.DATA,DISP=(OLD,PASS) //OUTPUT DD DSN=WORK.VALID.DATA,DISP=(,PASS) //* // IF (VALIDATE.RC = 0) THEN //PROCESS EXEC PGM=DATAPROC //SYSOUT DD SYSOUT=* //INPUT DD DSN=WORK.VALID.DATA,DISP=(OLD,DELETE) //OUTPUT DD DSN=PROD.OUTPUT.DATA,DISP=(NEW,CATLG) // ELSE //VALIDERR EXEC PGM=ERRLOGGER //SYSOUT DD SYSOUT=* //INPUT DD DSN=WORK.VALID.DATA,DISP=(OLD,DELETE) //ERRFILE DD DSN=PROD.ERROR.LOG,DISP=MOD //MESSAGE DD * DATA VALIDATION FAILED - PROCESS TERMINATED /* // ENDIF //* // ELSE //* ----- ERROR HANDLING PATH ----- //EXTRERR EXEC PGM=ERRLOGGER //SYSOUT DD SYSOUT=* //ERRFILE DD DSN=PROD.ERROR.LOG,DISP=MOD //MESSAGE DD * DATA EXTRACTION FAILED - PROCESS TERMINATED /* // ENDIF //* //* --------- NOTIFICATION ALWAYS RUNS --------- //NOTIFY EXEC PGM=NOTIFYPGM //SYSOUT DD SYSOUT=* //MSGFILE DD DSN=PROD.MESSAGES,DISP=MOD
This example shows a data pipeline with nested execution groups that handle both normal processing and error conditions at different stages.
Understanding conditional execution flows in JCL
How return codes are used to control execution
Strategies for handling errors in JCL jobs
Mechanisms for controlling job execution flow
Options for restarting jobs after failures
1. What are JCL Execution Groups primarily used for?
2. Which construct can be used to create execution groups in JCL?
3. What is the maximum nesting level supported for IF statements in z/OS JCL?
4. What happens to steps inside an IF/THEN block when the condition evaluates to false?
5. Which of the following is NOT a recommended best practice for execution groups?