IF THEN ELSE ENDIF construct is used to conditionally execute job steps within a job. A job step execution can be controlled based on the return code of the previous step(s) using the COND parameter and IF-THEN-ELSE-ENDIF construct. The IF statement is always followed by a relational expression and a THEN clause. Optionally, an ELSE clause can follow the THEN clause. An ENDIF statement always follows the ELSE clause, if present, or the THEN clause. The system evaluates the relational expression at execution time.
- The ELSE clause specifies the job steps that the system processes when the evaluation of the relational-expression for the IF statement is a false condition.
- The ENDIF statement indicates the end of the IF THEN ELSE ENDIF statement construct, and must be coded for each construct.
Return code is set based on the status of execution of a job. The return code can be a number between 0 (successful execution) to 4095 (non-zero shows error condition).
- 0 = Normal – all OK
- 4 = Warning – minor errors or problems.
- 8 = Error – significant errors or problems.
- 12 = Severe error – major errors or problems, the results should not be trusted.
- 16 = Terminal error – very serious problems, do not use the results.
You can nest IF THEN ELSE ENDIF statement constructs up to a maximum of 15 levels. The steps that execute in a THEN clause and an ELSE clause can be another IF THEN ELSE ENDIF statement construct.
IF THEN ELSE ENDIF Syntax
//name IF condition THEN list of statements //*** action taken when condition is true *** //name ELSEÂ list of statements //*** action taken when condition is false *** //name ENDIF
Following is the description of the used terms in the above IF-THEN-ELSE-ENDIF Construct:
- Name : This is optional and a name can have 1 to 8 alphanumeric characters starting with alphabet, #,$ or @. The first character must be alphabetic or national ($, #, @).
- Condition : A condition will have a format: KEYWORD OPERATOR VALUE, where KEYWORDS can be RC (Return Code), ABENDCC (System or user completion code), ABEND, RUN (step started execution). An OPERATOR can be logical operator (AND (&), OR (|)) or relational operator (<, <=, >, >=, <>).
Continuing a relational expression: You can continue relational expressions on the next JCL statement. Break the relational expression where a blank is valid on the current statement, and continue the expression beginning in columns 4 through 16 of the next statement. Do not put comments on the statement that you are continuing. You can code comments after you have completed the statement. For example:
  //TESTCON IF (RC = 8 | RC = 10 | RC = 12 | //      RC = 14) THEN Â
A relational expression consists of:
- Comparison operators
- Logical operators
- NOT (¬) operators
- Relational-expression keywords
- Numeric values
Order of Operator    Operation            Evaluation --------    ---------            ---------- NOT operator: NOT or ¬    NOT               first Comparison operators: GT or >    Greater than          second LT or <    Less than            second NG or ¬>   Not greater than        second NL or ¬<   Not less than          second EQ or =    Equal to            second NE or ¬=   Not equal to          second GE or >=   Greater than or equal to    second LE or <=   Less than or equal to      second Logical operators: AND or &    AND               third OR or |    OR               third Keyword          Use -------- -------- RC         indicates a return code ABEND(ABEND=TRUE)  indicates an abend condition occurred ¬ABEND(ABEND=FALSE) indicates no abend condition occurred ABENDC(Sxxx,Uxxxx  indicates a system or user completion code RUN(RUN=TRUE)    indicates that the specified step started           execution ¬RUN(RUN=FALSE)   indicates that the specified step did not           start execution
Examples
Following is a simple example showing the usage of IF-THEN-ELSE-ENDIF:
//USERIDX JOB CLASS=6,NOTIFY=&SYSUID //* //PRC1 Â PROC //PST1 Â EXEC PGM=SORT //PST2 Â EXEC PGM=IEBGENER // Â Â PEND //STP01Â EXEC PGM=SORTÂ //IF1Â Â IF STP01.RC = 0 THEN //STP02Â EXEC PGM=MYCOBB1,PARM=123 // Â Â Â ENDIF //IF2Â Â IF STP01.RUN THEN //STP03a EXEC PGM=IEBGENER //STP03b EXEC PGM=SORT // Â Â Â ENDIF //IF3Â Â IF STP03b.!ABEND THEN //STP04Â EXEC PGM=MYCOBB1,PARM=456 // Â Â Â ELSE // Â Â Â ENDIF //IF4Â Â IF (STP01.RC = 0 & STP02.RC <= 4) THEN //STP05Â EXEC PROC=PRC1 // Â Â Â ENDIF //IF5Â Â IF STP05.PRC1.PST1.ABEND THEN //STP06Â EXEC PGM=MYABD // Â Â Â ELSE //STP07Â EXEC PGM=SORT // Â Â Â ENDIF
Let’s try to look into the above program to understand it in little more detail:
- The return code of STP01 is tested in IF1. If it is 0, then STP02 is executed. Else, the processing goes to the next IF statement (IF2).
- In IF2, If STP01 has started execution, then STP03a and STP03b are executed.
- In IF3, If STP03b does not ABEND, then STP04 is executed. In ELSE, there are no statements. It is called a NULL ELSE statement.
- In IF4, if STP01.RC = 0 and STP02.RC <=4 are TRUE, then STP05 is executed.
- In IF5, if the proc-step PST1 in PROC PRC1 in jobstep STP05 ABEND, then STP06 is executed. Else STP07 is executed.
- If IF4 evaluates to false, then STP05 is not executed. In that case, IF5 are not tested and the steps STP06, STP07 are not executed.
The IF-THEN-ELSE-ENDIF will not be executed in the case of abnormal termination of the job such as user canceling the job, job time expiry or a dataset is backward referenced to a step that is bypassed.
Example-01: The following example shows the use of alphabetic characters rather than special characters for comparison operators.
//IFBAD Â Â IFÂ (ABEND | STEP1.RC > 8) THEN Â Â or //IFBAD Â Â IFÂ (ABEND OR STEP1.RC GT 8) THEN Â Â . Â Â . //IFTEST2 Â IFÂ (RC > 4 & RC < 8) THEN Â Â or //IFTEST2 Â IFÂ (RC GT 4 AND RC LT 8) THEN
Example-02: The following example shows a simple IF/THEN/ELSE/ENDIF statement construct without an ELSE statement.
//JOBAÂ Â Â JOB Â ... //STEP1 Â Â EXECÂ PGM=RTN Â Â Â Â Â Â Â . Â Â Â Â Â Â Â . //IFBAD Â Â IFÂ (ABEND | STEP1.RC > 8) THEN //TRUEÂ Â Â EXECÂ PROC=ERROR //IFBADENDÂ ENDIF //NEXTSTEPÂ EXECÂ PROC=CONTINUE
The IF statement named IFBAD invokes procedure ERROR if either an abend has occurred on a previous step of the job, or STEP1 has returned a return code that is greater than 8. Otherwise, step TRUE is bypassed and the system processes step NEXTSTEP.
Example-03: The following example shows a simple IF/THEN/ELSE/ENDIF statement construct with a null ELSE clause.
//JOBBÂ Â Â JOB Â ... //STEP1 Â Â EXECÂ PGM=RTN Â Â Â Â Â Â Â . Â Â Â Â Â Â Â . //IFBAD Â Â IFÂ (ABEND | STEP1.RC > 8) THEN //TRUEÂ Â Â EXECÂ PROC=ERROR //Â Â Â Â Â ELSE //IFBADENDÂ ENDIF //NEXTSTEPÂ EXECÂ PROC=CONTINUE
The IF statement named IFBAD invokes procedure ERROR if either an abend has occurred on a previous step of the job, or STEP1 has returned a return code that is greater than 8. Otherwise, the system bypasses step TRUE, and the null ELSE clause passes to NEXTSTEP.
Example-04: The following example shows a simple IF/THEN/ELSE/ENDIF statement construct with an ELSE clause.
//JOBCÂ Â Â JOBÂ Â ... //STEP0 Â Â EXEC Â PGM=RTN1 Â Â Â Â Â Â Â . Â Â Â Â Â Â Â . //IFTEST2 Â IFÂ (RC > 4 & RC < 8) THEN //* Â Â Â Â Â Â *** WARNING CONDITION REPORTING GROUP *** //STEP1 Â Â EXEC Â PGM=IEFBR14 //REPORTÂ Â EXEC Â PROC=REPTRTN //* Â Â Â Â Â Â *** WARNING CONDITION REPORTING GROUP END *** //Â Â Â Â Â ELSE //ERRORSTPÂ EXEC Â PROC=ERRORTN //ENDTEST2Â ENDIF //NEXTSTEPÂ EXEC Â PROC=CONTINUE
Processing for this IF/THEN/ELSE/ENDIF statement construct is:
- If the relational-expression for the IF/THEN statement construct named IFTEST2 is true (the highest step return code for the job is greater than 4 and less than 8 at the point when this statement is being processed), the system processes the THEN clause. The system executes program IEFBR14 and procedure REPTRTN on EXEC statements STEP1 and REPORT.
- Otherwise, the relational-expression for IFTEST2 is false and the system processes the ELSE clause (procedure ERRORTN on EXEC statement ERRORSTP).
- Processing then continues with procedure CONTINUE on step NEXTSTEP.
Example-05: The following example shows nested IF/THEN/ELSE/ENDIF statement constructs with ELSE clauses. The nested statements are indented so that they are easier to read.
//JOBD   JOB  ... //PROC1   PROC //PSTEPONE EXEC PGM=... //PSTEP11  EXEC PGM=... //PSTEP12  EXEC PGM=... //     PEND //PROC2   PROC //PSTEPTWO EXEC PGM=... //     PEND //EXP1   EXEC PROC=PROC1 //EXP2   EXEC PROC=PROC2 //IFTEST3  IF (RC > 12) THEN //STEP1BAD IF (EXP1.PSTEP11.RC > 12 OR EXP1.PSTEP12.RC > 12) THEN //STEP1ERR EXEC PGM=ERRTN,PARM=(EXP1) //     ELSE //STEP2ERR EXEC PGM=ERRTN,PARM=(EXP2) //END1BAD  ENDIF //     ELSE //NOPROB  EXEC PROC=RUNOK //ENDTEST3 ENDIF //NEXTSTEP EXEC …
Processing for the IF/THEN/ELSE/ENDIF construct named IFTEST3 is:
- If the relational-expression for IFTEST3 is true (the highest step return code for the job is greater than 12 at the point where this statement is being processed), the system processes the THEN clause of IFTEST3. It evaluates the relational-expression of the IF/THEN/ELSE/ENDIF construct named STEP1BAD.
- If the STEP1BAD relational-expression is true (the return code is greater than 12 for either of the two steps in procedure PROC1, which is invoked by step EXP1), the system processes the THEN clause of STEP1BAD. Step STEP1ERR invokes program ERRTN, passing EXP1 as a parameter.
- If the STEP1BAD relational-expression is not true, the system processes the ELSE clause for STEP1BAD. Step STEP2ERR invokes program ERRTN, passing EXP2 as a parameter.
- However, if the relational-expression for IFTEST3 is false, the system processes the ELSE clause. Step NOPROB invokes procedure RUNOK.
- Processing then continues with step NEXTSTEP.
Example-06: The following example shows two IF/THEN/ELSE/ENDIF statement constructs, one of which is nested in the ELSE clause of the other. The nested statements are indented so that they are easier to read.
//JOBE   JOB  ... //PROC1   PROC //PSTEPONE EXEC PGM=... //     PEND //PROC2   PROC //PSTEPTWO EXEC PGM=... //     PEND //EXP1   EXEC PROC=PROC1 //EXP2   EXEC PROC=PROC2 //IFTEST4  IF (EXP1.PSTEPONE.RC > 4) THEN //STEP1ERR EXEC PGM=PROG1 //     ELSE //IFTEST5  IF (EXP2.PSTEPTWO.ABENDCC=U0012) THEN //STEP2ERR EXEC PGM=PROG2 //     ELSE //NOERR   EXEC PGM=PROG3 //ENDTEST5 ENDIF //ENDTEST4 ENDIF //NEXTSTEP EXEC …
Processing for the IF/THEN/ELSE/ENDIF construct named IFTEST4 is:
- If the relational-expression for IFTEST4 is true (the return code is greater than 4 for PSTEPONE in procedure PROC1, which is invoked by step EXP1), the system processes the THEN clause of IFTEST4. EXEC statement STEP1ERR invokes program PROG1. The system then passes control to ENDIF statement ENDTEST4, and processing continues with step NEXTSTEP.
- However, if the relational-expression for IFTEST4 is false (the return code is 4 or less for PSTEPONE in procedure PROC1, which is invoked by step EXP1), the system processes the ELSE clause of IFTEST4. It evaluates the IF/THEN/ELSE/ENDIF statement construct IFTEST5. Processing for the IF/THEN/ELSE/ENDIF construct named IFTEST5 is:
- If the relational-expression for IFTEST5 is true (the user-defined abend completion code is 0012 from PSTEPTWO in procedure PROC2, which is invoked by step EXP2), the system processes the THEN clause of IFTEST5. EXEC statement STEP2ERR invokes program PROG2. The system then passes control to ENDIF statement ENDTEST5, and then ENDTEST4. Processing continues with EXEC statement NEXTSTEP.
- However, if the relational-expression for IFTEST5 is false (that is, the user-defined abend completion code is not 0012 from PSTEPTWO in procedure PROC2, which is invoked by step EXP2), the system processes the ELSE clause of IFTEST5. EXEC statement NOERR invokes program PROG3. Processing then continues with step NEXTSTEP.
Example-07: The following example shows an IF/THEN/ELSE/ENDIF statement construct with a deferred checkpoint restart.
//DEFER1 JOB RESTART=(STEP2,CHECK004) //STEP1 EXEC PGM=IEFBR14 //IF1  IF STEP1.RC=0 | ¬STEP1.RUN THEN //STEP2 EXEC PGM=DEBIT1 //STEP3 EXEC PGM=CREDIT1 //STEP4 EXEC PGM=SUMMARY1 //    ELSE //STEP5 EXEC PGM=DEBIT2 //STEP6 EXEC PGM=CREDIT2 //STEP7 EXEC PGM=SUMMARY2 //    ENDIF
Processing for the IF/THEN/ELSE/ENDIF construct named IF1 is as follows:
- The conditions on statement IF1 will be checked before executing STEP2.
- STEP1.RC=0 tests false because STEP1 did not execute and cannot be correctly evaluated.
- ¬STEP1.RUN tests true; therefore, STEP2, STEP3, and STEP4 will execute and STEP5, STEP6, and STEP7 will not execute.
Note: Without the ¬STEP.RUN condition, STEP2, STEP3, and STEP4 would not execute and STEP5, STEP6, and STEP7 would execute.
Example-08: The following example shows an IF/THEN/ELSE/ENDIF statement construct with a deferred step restart.
//DEFER2 JOB RESTART=(STEP3) //STEP1 EXEC PGM=IEFBR14 //IF1  IF STEP1.RC=0 | ¬STEP1.RUN THEN //STEP2 EXEC PGM=DEBIT1 //STEP3 EXEC PGM=CREDIT1 //STEP4 EXEC PGM=SUMMARY1 //    ELSE //STEP5 EXEC PGM=DEBIT2 //STEP6 EXEC PGM=CREDIT2 //STEP7 EXEC PGM=SUMMARY2 //    ENDIF
Processing for the IF/THEN/ELSE/ENDIF construct named IF1 is:
- The conditions on statement IF1 will be checked before executing STEP3.
- STEP1.RC=0 tests false because STEP1 did not execute and cannot be correctly evaluated.
- ¬STEP1.RUN tests true; therefore, STEP3 and STEP4 will execute and STEP5, STEP6, and STEP7 will not execute.
Note: Without the ¬STEP1.RUN condition, STEP3, and STEP4 would not run, and STEP5, STEP6, and STEP7 would run.
Example-09: The following example specifies that if STEP1 does not abend, the system is to run STEP2 and STEP3. Otherwise, it is to run STEP4.
//JOBF   JOB ... //STEP1  EXEC PGM=... //IFTEST6 IF  ¬ABEND THEN //STEP2  EXEC PGM=... //STEP3  EXEC PGM=... //     ELSE //STEP4  EXEC PGM=... //     ENDIF
The determination of which steps to run is made when the IF/THEN/ELSE/ENDIF statement construct is processed immediately after STEP1 executes. This determination is not subject to change based on the results of running steps after STEP1.
Thus, if STEP1 does not abend, even if STEP2 does, STEP3 (and not STEP4) still runs. If, however, STEP1 does abend, STEP4 is the next step to run, as prescribed by the ELSE clause.