MainframeMaster

Nested IFTHEN Logic

Nested IFTHEN logic in DFSORT means using multiple IFTHEN clauses so that more than one conditional action can apply to the same record, or so that the order of evaluation creates a logical hierarchy. By default, only the first matching WHEN=(logexp) or WHEN=NONE is applied; to allow multiple clauses to apply to one record you use HIT=NEXT. That lets you overlay one field when condition A is true and another field when condition B is true—both can run on the same record. This page explains how multiple IFTHEN clauses are evaluated, what HIT=NEXT does, order of clauses, and patterns for layered or nested-style conditional reformatting.

Conditional Processing
Progress0 of 0 lessons

Default: First Match Only

When you list several IFTHEN clauses with WHEN=(logexp) or WHEN=NONE, DFSORT evaluates them in order. As soon as one clause matches and its BUILD or OVERLAY is applied, processing for that record typically stops—the next IFTHEN is not evaluated. So each record gets at most one of the conditional branches (plus whatever WHEN=INIT and WHEN=GROUP did, and possibly WHEN=ANY). That is the default "first match wins" behavior.

Example: you have WHEN=(1,1,CH,EQ,C'A') with OVERLAY=(80:C'1') and WHEN=(1,1,CH,EQ,C'B') with OVERLAY=(80:C'2'). A record with byte 1 = 'A' gets the first clause only; a record with byte 1 = 'B' gets the second only. No record gets both, and no record is re-evaluated for the next clause after a match.

HIT=NEXT: Allow Multiple Clauses to Apply

HIT=NEXT changes that. When you add HIT=NEXT to an IFTHEN clause, after that clause matches and its action is applied, DFSORT continues to the next IFTHEN clause instead of stopping. So the same record can receive a second (or third) overlay or build from a later clause. That is how you get "nested" or layered behavior: first overlay when condition A is true, then (if you used HIT=NEXT) second overlay when condition B is true.

Typical use: you have two date fields, at positions 72–81 and 82–91. You want to replace either with '0001-01-01' when it contains the invalid sentinel '9999-99-99'. You need two IFTHEN clauses—one for each field—and HIT=NEXT on the first so that the second is also evaluated. A record with both dates invalid gets both overlays.

text
1
2
3
4
5
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,100)), IFTHEN=(WHEN=(72,10,CH,EQ,C'9999-99-99'), OVERLAY=(72:C'0001-01-01')),HIT=NEXT, IFTHEN=(WHEN=(82,10,CH,EQ,C'9999-99-99'), OVERLAY=(82:C'0001-01-01'))

The first clause overlays position 72 when the first date is invalid; HIT=NEXT allows the second clause to run. The second overlays position 82 when the second date is invalid. A record with both invalid gets both overlays; a record with only the first invalid gets only the first overlay; a record with only the second invalid gets only the second (because the first does not match and evaluation continues anyway to the second).

Order of Evaluation

The order in which you list IFTHEN clauses matters:

  1. WHEN=INIT and WHEN=GROUP run first for every record. They establish the base record.
  2. WHEN=(logexp) and WHEN=NONE are then evaluated in the order you write them. The first matching clause is applied. If that clause has HIT=NEXT, the next clause is evaluated; if it matches, its action is applied, and so on.
  3. WHEN=ANY is evaluated after that; it applies to records that matched at least one WHEN=(logexp).

So if two WHEN=(logexp) clauses could both match the same record, the one that appears first wins (and optionally allows the next via HIT=NEXT). Put more specific conditions before broader ones if you want the specific overlay first; use HIT=NEXT when you want multiple overlays to stack.

Pattern: Multiple Independent Conditions

When conditions are independent (e.g. "if field A is bad, fix A; if field B is bad, fix B"), use one IFTHEN per condition and HIT=NEXT on each that should allow the next to run. Then a record can get zero, one, or several overlays depending on how many conditions are true.

Pattern: independent conditions
PatternEffect
One IFTHEN per condition, each with HIT=NEXT (except optionally the last)Each condition is evaluated; all matching clauses apply. Record can get multiple overlays.
Same but without HIT=NEXTOnly the first matching clause applies. Later clauses never run for that record.

Pattern: Priority Order (First Match Wins)

When you want one of several actions and the order defines priority (e.g. "if type A do X, else if type B do Y, else do Z"), list the conditions in priority order and do not use HIT=NEXT. Then the first match wins and the rest are skipped. WHEN=NONE at the end catches records that matched no condition.

text
1
2
3
4
5
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(1,2,CH,EQ,C'H1'),OVERLAY=(79:2C'1')), IFTHEN=(WHEN=(1,2,CH,EQ,C'D1'),OVERLAY=(79:2C'2')), IFTHEN=(WHEN=(1,2,CH,EQ,C'T1'),OVERLAY=(79:2C'3')), IFTHEN=(WHEN=NONE,OVERLAY=(79:2C'0'))

No HIT=NEXT: each record gets at most one of the OVERLAYs. Record type H1 gets '1' at 79–80, D1 gets '2', T1 gets '3', and anything else gets '0' from WHEN=NONE.

Logical Nesting vs Clause Order

"Nested" can mean two things. Logical nesting is when the condition itself contains nested logic (e.g. (A AND B) OR (C AND D)) using parentheses and AND/OR in WHEN=(logexp)—see the Complex conditional expressions tutorial. Clause nesting or stacking is what we do here: multiple IFTHEN clauses in sequence, with HIT=NEXT allowing more than one to apply. Both are valid; this page focuses on clause order and HIT=NEXT. For complex conditions inside a single WHEN=, use the comparison operators and grouping described in the INCLUDE/OMIT and complex conditional expressions pages.

Explain It Like I'm Five

Imagine you have a checklist: "If the card has a smudge here, put a sticker here. If the card has a tear there, put a sticker there." Usually you might stop after the first sticker. But if the rule says "and then check the next rule," you keep going. So one card could get a sticker for the smudge and another for the tear. HIT=NEXT is like saying "and then check the next rule"—so one record can get several fixes or overlays from different rules.

Exercises

  1. You have three IFTHEN clauses: overlay 10 when (1,1,CH,EQ,C'A'), overlay 20 when (2,1,CH,EQ,C'X'), overlay 30 when (3,1,CH,EQ,C'Y'). No HIT=NEXT. What happens to a record with bytes 1='A', 2='X', 3='Y'? What if you add HIT=NEXT to the first and second clauses?
  2. When would you avoid using HIT=NEXT?
  3. Why does the order of WHEN=(logexp) clauses matter when a record could match more than one?

Quiz

Test Your Knowledge

1. What does HIT=NEXT do in an IFTHEN clause?

  • Skips the next record
  • Allows the next IFTHEN clause to be evaluated after the current one matches, so more than one clause can apply to the same record
  • Moves to the next file
  • Resets the sequence number

2. By default, how many WHEN=(logexp) or WHEN=NONE clauses apply to a single record?

  • All of them
  • Only the first one that matches
  • Only WHEN=NONE
  • Only WHEN=ANY

3. Why would you use multiple IFTHEN clauses with HIT=NEXT?

  • To filter records
  • To apply several different overlays to the same record when different conditions are true (e.g. fix date at 72 and also at 82 when each is invalid)
  • To sort twice
  • To merge files

4. Does the order of IFTHEN clauses matter?

  • No; DFSORT reorders them
  • Yes; WHEN=INIT and WHEN=GROUP run first, then WHEN=(logexp) and WHEN=NONE are evaluated in the order you write them, and the first match typically applies unless HIT=NEXT is used
  • Only WHEN=NONE order matters
  • Only in OUTFIL

5. Can you combine WHEN=INIT, multiple WHEN=(logexp), WHEN=NONE, and WHEN=ANY in one IFTHEN list?

  • No; only two clauses allowed
  • Yes; you can list all of them in one IFTHEN parameter; INIT and GROUP run first, then the rest in order
  • Only in INREC
  • Only WHEN=ANY and WHEN=NONE