Using the COND parameter for conditional job step execution in JCL
The COND parameter is a powerful feature in JCL that allows for conditional execution of job steps based on the return codes from previous steps. It provides a way to control the flow of job execution without using the more complex IF/THEN/ELSE structures.
By using the COND parameter, you can skip steps that would be unnecessary or potentially harmful if previous steps didn't complete as expected. This tutorial explores how to use the COND parameter effectively for conditional processing in your JCL jobs.
The COND parameter is specified on the EXEC statement and can take several forms:
Basic Syntax:
12345//stepname EXEC PGM=program-name,COND=(code,operator) //stepname EXEC PGM=program-name,COND=(code,operator,stepname) //stepname EXEC PGM=program-name,COND=((code1,operator1),(code2,operator2),...) //stepname EXEC PGM=program-name,COND=EVEN //stepname EXEC PGM=program-name,COND=ONLY
The components of the COND parameter are:
The COND parameter specifies when to bypass (skip) a step, not when to execute it. If the condition is true, the step is skipped. This often confuses JCL programmers.
For example, COND=(4,LT)
means "bypass this step if any previous step's return code is less than 4" - this means the step only runs if all previous return codes are 4 or higher.
The COND parameter uses these comparison operators:
Bypass if return code is greater than the specified value
COND=(4,GT)
- Skip if RC > 4
Bypass if return code is greater than or equal to the specified value
COND=(8,GE)
- Skip if RC >= 8
Bypass if return code is equal to the specified value
COND=(0,EQ)
- Skip if RC = 0
Bypass if return code is not equal to the specified value
COND=(0,NE)
- Skip if RC ≠ 0
Bypass if return code is less than the specified value
COND=(8,LT)
- Skip if RC < 8
Bypass if return code is less than or equal to the specified value
COND=(4,LE)
- Skip if RC <= 4
If you don't specify a step name, the condition applies to all previous steps:
123//STEP1 EXEC PGM=PROGRAM1 //STEP2 EXEC PGM=PROGRAM2 //STEP3 EXEC PGM=PROGRAM3,COND=(4,LT)
STEP3 will be bypassed if STEP1 or STEP2 has a return code less than 4.
You can specify a particular step to check:
123//STEP1 EXEC PGM=PROGRAM1 //STEP2 EXEC PGM=PROGRAM2 //STEP3 EXEC PGM=PROGRAM3,COND=(0,NE,STEP1)
STEP3 will be bypassed if STEP1 has a return code not equal to 0.
You can specify multiple conditions in a single COND parameter:
123//STEP1 EXEC PGM=PROGRAM1 //STEP2 EXEC PGM=PROGRAM2 //STEP3 EXEC PGM=PROGRAM3,COND=((0,NE,STEP1),(4,GT,STEP2))
STEP3 will be bypassed if STEP1 has a return code not equal to 0 OR if STEP2 has a return code greater than 4.
To execute a step even if a previous step abended:
123//STEP1 EXEC PGM=PROGRAM1 //STEP2 EXEC PGM=PROGRAM2 //CLEANUP EXEC PGM=CLEANUP,COND=EVEN
The CLEANUP step will execute even if STEP1 or STEP2 abended. This is ideal for cleanup steps that should always run.
To execute a step only if a previous step abended:
123//STEP1 EXEC PGM=PROGRAM1 //STEP2 EXEC PGM=PROGRAM2 //RECOVERY EXEC PGM=RECOVERY,COND=ONLY
The RECOVERY step will only execute if STEP1 or STEP2 abended. This is useful for recovery procedures.
A common pattern in mainframe processing is conditional compile, link, and execute:
12345678910111213141516//JOBNAME JOB (ACCT),'DEVELOPER',CLASS=A //* //COMPILE EXEC PGM=IKFCBL00 //SYSIN DD DSN=SOURCE.COBOL(PROGRAM),DISP=SHR //SYSLIN DD DSN=&&OBJSET,DISP=(NEW,PASS), // UNIT=SYSDA,SPACE=(TRK,(5,5)) //SYSPRINT DD SYSOUT=* //* //LINK EXEC PGM=IEWL,COND=(4,LT,COMPILE) //SYSLIN DD DSN=&&OBJSET,DISP=(OLD,DELETE) //SYSLMOD DD DSN=LOAD.LIBRARY(PROGRAM),DISP=SHR //SYSPRINT DD SYSOUT=* //* //EXECUTE EXEC PGM=PROGRAM,COND=((4,LT,COMPILE),(0,NE,LINK)) //STEPLIB DD DSN=LOAD.LIBRARY,DISP=SHR //SYSOUT DD SYSOUT=*
This example shows a data processing job with cleanup that always runs:
1234567891011121314151617181920212223242526//JOBNAME JOB (ACCT),'DATA PROCESS',CLASS=A //* //EXTRACT EXEC PGM=EXTRACT //INPUT DD DSN=INPUT.DATA,DISP=SHR //OUTPUT DD DSN=&&TEMP1,DISP=(NEW,PASS), // UNIT=SYSDA,SPACE=(CYL,(10,5)) //SYSPRINT DD SYSOUT=* //* //SORT EXEC PGM=SORT,COND=(8,LT,EXTRACT) //SORTIN DD DSN=&&TEMP1,DISP=(OLD,PASS) //SORTOUT DD DSN=&&TEMP2,DISP=(NEW,PASS), // UNIT=SYSDA,SPACE=(CYL,(10,5)) //SYSIN DD * SORT FIELDS=(1,10,CH,A) /* //SYSOUT DD SYSOUT=* //* //REPORT EXEC PGM=REPORTER,COND=((8,LT,EXTRACT),(4,LT,SORT)) //INPUT DD DSN=&&TEMP2,DISP=(OLD,PASS) //OUTPUT DD DSN=FINAL.REPORT,DISP=(NEW,CATLG,DELETE), // UNIT=SYSDA,SPACE=(CYL,(5,1)) //SYSPRINT DD SYSOUT=* //* //CLEANUP EXEC PGM=IEFBR14,COND=EVEN //TEMP1 DD DSN=&&TEMP1,DISP=(OLD,DELETE) //TEMP2 DD DSN=&&TEMP2,DISP=(OLD,DELETE)
When using the COND parameter with cataloged procedures, you need a different syntax to reference steps within the procedure:
123456789//JOBNAME JOB (ACCT),'PROCEDURE EXAMPLE',CLASS=A //* //STEP1 EXEC PGM=PROGRAM1 //SYSOUT DD SYSOUT=* //* //PROCSTEP EXEC PROC=MYPROC //* //STEP2 EXEC PGM=PROGRAM2,COND=(0,NE,PROCSTEP.COMPILE) //SYSOUT DD SYSOUT=*
In this example, STEP2 will be bypassed if the COMPILE step in the MYPROC procedure did not complete with a return code of 0. The format for referencing a step in a procedure is procstepname.stepname
.
While the COND parameter is powerful, it has some limitations compared to IF/THEN/ELSE structures:
Choose the approach that best fits your needs. For simple conditional execution, COND is often sufficient. For more complex logic, IF/THEN/ELSE is usually more appropriate.
Always add comments to explain the COND logic, especially for complex conditions.
12//* Skip this step if previous step had RC > 8 (major error) //STEP2 EXEC PGM=PROGRAM2,COND=(8,GT,STEP1)
When possible, reference specific steps rather than all previous steps to make your logic more predictable.
Always include cleanup steps with COND=EVEN to ensure temporary resources are released even if the job fails.
Test your COND parameters with different return code scenarios to ensure they behave as expected.
If your conditional logic becomes difficult to express with COND parameters, consider switching to IF/THEN/ELSE statements.
Test your understanding of the COND parameter with these exercises:
Create a JCL job with two steps. In the second step, use the COND parameter to skip execution if the first step returns a code greater than 4.
123456//EXERJOB JOB (ACCT),'COND EXERCISE',CLASS=A //STEP1 EXEC PGM=MYPROG1 //SYSOUT DD SYSOUT=* //* //STEP2 EXEC PGM=MYPROG2,COND=(4,GT,STEP1) //SYSOUT DD SYSOUT=*
Create a JCL job with three steps. Add a fourth step that executes only if STEP1 had a return code of 0 or STEP3 had a return code less than or equal to 4.
123456789101112//EXERJOB JOB (ACCT),'COND EXERCISE',CLASS=A //STEP1 EXEC PGM=MYPROG1 //SYSOUT DD SYSOUT=* //* //STEP2 EXEC PGM=MYPROG2 //SYSOUT DD SYSOUT=* //* //STEP3 EXEC PGM=MYPROG3 //SYSOUT DD SYSOUT=* //* //STEP4 EXEC PGM=MYPROG4,COND=((0,NE,STEP1),(4,LT,STEP3)) //SYSOUT DD SYSOUT=*
Create a JCL job with four steps. Make one step execute only if a previous step abended (COND=ONLY) and another step execute regardless of whether previous steps abended (COND=EVEN).
123456789101112//EXERJOB JOB (ACCT),'COND EXERCISE',CLASS=A //STEP1 EXEC PGM=MYPROG1 //SYSOUT DD SYSOUT=* //* //STEP2 EXEC PGM=MYPROG2 //SYSOUT DD SYSOUT=* //* //STEP3 EXEC PGM=RECOVERY,COND=ONLY //SYSOUT DD SYSOUT=* //* //STEP4 EXEC PGM=CLEANUP,COND=EVEN //SYSOUT DD SYSOUT=*
1. What is the primary purpose of the COND parameter in JCL?
2. In COND=(4,LT), what does this condition mean?
3. What does COND=EVEN do in a JCL step?
4. Which of the following is NOT a valid operator in a COND parameter?
5. How would you specify a COND parameter to bypass a step if STEP1 had a return code of 8?
6. When multiple conditions are specified in a COND parameter, what is the logical relationship between them?