MainframeMaster

IFTHEN Logic in INREC and OUTREC

IFTHEN in DFSORT lets you apply conditional reformatting to records: different BUILD, OVERLAY, or FINDREP actions depending on whether a record meets specified conditions. You can use IFTHEN in both INREC and OUTREC. Each IFTHEN clause has a WHEN type—WHEN=INIT (apply to all), WHEN=(logical expression) (apply when condition is true), WHEN=NONE (apply when no previous WHEN matched), WHEN=ANY (apply when any previous WHEN matched), or WHEN=GROUP (group-level operations)—and an action such as BUILD= or OVERLAY=. Using IFTHEN in INREC is important when the conditionally reformatted record must be used for sorting or INCLUDE/OMIT; using it in OUTREC is for conditional formatting in the final output only. This page explains the five WHEN types, BUILD vs OVERLAY, and how to combine multiple clauses.

INREC Processing
Progress0 of 0 lessons

Why Use IFTHEN?

Sometimes you need different output layouts for different records: for example, header records get one format, detail records another, or records with a certain field value get an overlay (e.g. mask a field or insert a constant). Without IFTHEN, you would need a single BUILD that applies to every record. With IFTHEN, you say: "when the first 3 bytes equal 'ABC', build the record this way; when they don't, build it that way." So IFTHEN gives you conditional reformatting—different BUILD or OVERLAY depending on a condition. The same logic is available in INREC (before the sort) and OUTREC (after the sort). Use INREC when the result drives the sort or INCLUDE/OMIT; use OUTREC when you only need the conditional format in the final dataset.

The Five WHEN Types

Each IFTHEN clause is classified by its WHEN type. The order of processing and which records each applies to are different.

IFTHEN WHEN types
WHEN typeMeaningTypical use
WHEN=INITApply BUILD/OVERLAY/FINDREP to all records; processed before other WHEN clausesBase layout or common reformat for every record
WHEN=(logexp)Apply only when the logical expression is true (e.g. field EQ value, PD GT 0)Conditional layout for specific record types or values
WHEN=NONEApply to records that did not match any preceding WHEN=(logexp)Else branch; default or fallback layout
WHEN=ANYApply to records that matched at least one preceding WHEN=(logexp)Additional formatting for any record that matched a condition
WHEN=GROUPGroup-level operations (multiply fields, sequence numbers within groups); processed earlyControl-break or group-based reformatting

WHEN=INIT and WHEN=GROUP are processed before any WHEN=(logexp), WHEN=NONE, or WHEN=ANY. So you often use WHEN=INIT to build a base record (e.g. copy 1–80), then one or more WHEN=(logexp) to overlay or rebuild for specific conditions, and WHEN=NONE to handle records that did not match any condition. WHEN=ANY applies to records that already matched at least one WHEN=(logexp)—useful for adding something extra to any record that matched.

WHEN=(logical expression)

The logical expression in WHEN=(logexp) uses the same style of conditions as INCLUDE/OMIT: field position, length, format (CH, PD, ZD, BI), comparison operator (EQ, NE, LT, LE, GT, GE), and value (constant or another field). For example: WHEN=(1,3,CH,EQ,C'ABC') is true when the first 3 bytes are the character constant 'ABC'. WHEN=(10,4,ZD,GT,1000) is true when the 4-byte zoned decimal at position 10 is greater than 1000. When the expression is true, the BUILD or OVERLAY for that clause is applied to the record.

BUILD vs OVERLAY

Inside an IFTHEN clause you specify what to do: BUILD= or OVERLAY= (or FINDREP when supported). BUILD= constructs a new record from the listed items (positions, constants, etc.)—it defines the full output record for that branch. OVERLAY= does not rebuild the whole record; it modifies specific positions. You give a position (and optionally length) and the new value (constant or field). So OVERLAY is useful when you want to change one or a few fields and leave the rest of the record unchanged. For example, replace an invalid date at position 72 with OVERLAY=(72:C'0001-01-01').

INREC Example: Conditional BUILD

We want to reformat records so that if the first 3 bytes are 'ABC', the output is the first 20 bytes plus the constant 'FOUND_ABC'; otherwise the first 20 bytes plus 'NO_MATCH'. Doing this in INREC means the sort sees the reformatted record.

text
1
2
3
SORT FIELDS=COPY INREC IFTHEN=(WHEN=(1,3,CH,EQ,C'ABC'),BUILD=(1,20,C'FOUND_ABC')), IFTHEN=(WHEN=NONE,BUILD=(1,20,C'NO_MATCH'))

The first IFTHEN applies when bytes 1–3 equal 'ABC'; the output is 20 bytes from input plus the 9-byte constant. The second IFTHEN with WHEN=NONE applies to all records that did not match the first—so they get 20 bytes plus 'NO_MATCH'. Every record is handled by exactly one of these two clauses.

OUTREC Example: Numeric Condition and OVERLAY

Copy all records, but when the 4-byte zoned decimal at position 10 is greater than 1000, overlay position 1 with the constant 'OVER_1000'; when it is less than or equal to 1000, overlay with 'UNDER_1000'. Using OVERLAY we can keep the rest of the record and only change the first bytes.

text
1
2
3
4
SORT FIELDS=COPY OUTREC IFTHEN=(WHEN=INIT,BUILD=(1,80)), IFTHEN=(WHEN=(10,4,ZD,GT,1000),OVERLAY=(1:C'OVER_1000')), IFTHEN=(WHEN=(10,4,ZD,LE,1000),OVERLAY=(1:C'UNDER_1000'))

WHEN=INIT builds the base record (full 80 bytes from input). Then the two WHEN=(logexp) clauses overlay the first 9 bytes with the appropriate constant. So the output record is 80 bytes, with positions 1–9 replaced by the label. (If both conditions could apply, order matters; typically only one will apply per record.)

WHEN=INIT as Base Layout

A common pattern is WHEN=INIT to set the base record for every record, then conditional OVERLAY to change specific fields when conditions hold. Example: copy 1–80 for everyone, then if bytes 30–34 are 'dept1', overlay position 45 with '***'; otherwise leave the record as built by INIT.

text
1
2
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(30,5,CH,EQ,C'dept1'),OVERLAY=(45:C'***'))

Here 1:1,80 places the input record at output starting at 1. Then the second clause overlays bytes 45–47 with '***' only when the condition is true. So you get one base layout and selective overlay without rewriting the whole BUILD for each case.

HIT=NEXT: Multiple Clauses Applying

By default, often only the first matching WHEN=(logexp) (or WHEN=NONE) is applied. If you need multiple WHEN clauses to be evaluated and applied (e.g. overlay at one position when condition A holds, and at another position when condition B holds), you can use HIT=NEXT. This tells DFSORT to continue to the next IFTHEN after applying the current one, so more than one overlay can occur on the same record. For example, replace invalid date at 72 and also at 82 with '0001-01-01' when each field equals '9999-99-99'.

text
1
2
3
4
OUTREC 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 IFTHEN overlays position 72 when the date there is the sentinel value; HIT=NEXT allows the second IFTHEN to run, which overlays position 82 when that date is the sentinel. So one record can get both overlays if both conditions are true.

WHEN=GROUP (Brief)

WHEN=GROUP is used for group-level operations: for example, multiplying fields or generating sequence numbers within groups of records (e.g. by control field). It is processed early like WHEN=INIT. The exact syntax and use (e.g. with REFORMAT or group definitions) are in the IBM DFSORT manual. For most conditional reformatting by record type or field value, WHEN=INIT, WHEN=(logexp), and WHEN=NONE are sufficient.

Explain It Like I'm Five

Imagine you have a stack of cards: some have "ABC" at the top, some don't. IFTHEN is like a rule that says: "If the card says ABC, write 'FOUND_ABC' on it; if it doesn't say ABC, write 'NO_MATCH'." So the computer looks at each card, checks the condition, and then does the right action. WHEN=INIT is like doing something to every card first (e.g. copy it). Then the other rules only change some cards. That way different cards get different treatment without writing a separate program for each kind of card.

Exercises

  1. You need to overlay position 50 with 'HIGH' when a packed decimal at 60 (4 bytes) is greater than 1000. Write a single IFTHEN clause (WHEN= and OVERLAY=) for OUTREC.
  2. When would you use IFTHEN in INREC instead of OUTREC? Give a concrete example.
  3. What is the purpose of WHEN=NONE? Give an example where it is useful.
  4. What does HIT=NEXT allow that default processing does not?

Quiz

Test Your Knowledge

1. When is WHEN=INIT processed relative to other IFTHEN clauses?

  • Last
  • Only when no other WHEN matches
  • Before any other WHEN clause (runs first on all records)
  • Only for the first record

2. What does WHEN=NONE do?

  • Disables IFTHEN
  • Applies formatting to records that did not match any preceding WHEN=(logexp)
  • Means no BUILD
  • Runs only when BUILD is empty

3. Why use IFTHEN in INREC instead of OUTREC?

  • IFTHEN is only in OUTREC
  • When the conditional reformatting must be seen by the sort or INCLUDE/OMIT (INREC runs before sort)
  • INREC IFTHEN is faster
  • Only OUTREC supports OVERLAY

4. What is OVERLAY in an IFTHEN clause used for?

  • Sort overlay
  • Modifying specific positions in the record without rebuilding the whole record
  • Copying the whole file
  • Deleting fields

5. What does HIT=NEXT do when used with IFTHEN?

  • Skips the next record
  • Allows subsequent IFTHEN clauses to be evaluated after the first match (multiple WHEN can apply)
  • Moves to next file
  • Next sort key