
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.
