MainframeMaster

Complex Conditional Workflows

A complex conditional workflow in DFSORT is a pipeline that uses several kinds of conditional logic in one step: INREC IFTHEN (reformat before filter and sort), INCLUDE or OMIT (filter by condition), SORT, OUTREC IFTHEN (conditional output layout), and optionally OUTFIL with build or IFTHEN for additional outputs. The key is understanding the order of execution: INREC runs first, so the record that INCLUDE and SORT see is the INREC result; OUTREC runs last when writing to SORTOUT. This page explains that order, when to use IFTHEN in INREC vs OUTREC, how to combine INCLUDE/OMIT with IFTHEN, and how to design a full conditional pipeline.

Conditional Processing
Progress0 of 0 lessons

Execution Order: Input → Filter → Sort → Output

DFSORT processes control statements in a fixed order. Knowing this order is essential for designing conditional workflows:

  1. Input phase: INREC runs first. Every input record is reformatted according to INREC FIELDS=, BUILD=, or IFTHEN. The result is the "current" record for the rest of the step.
  2. Filter phase: INCLUDE and OMIT are applied. They see the INREC record. Records that do not pass the condition are dropped and never sorted or written.
  3. Sort phase: SORT or MERGE runs on the remaining records. Sort keys are taken from the record at this point (the INREC result).
  4. Output phase: When writing to SORTOUT, OUTREC runs. It sees the sorted record and produces the final output record. OUTREC can use IFTHEN to format by record type.
  5. Additional outputs: OUTFIL can produce extra datasets; each can have its own build/overlay and IFTHEN.

So if you need a field to be normalized or built so that INCLUDE or SORT can use it, that must happen in INREC. If you only need different formatting in the written file, OUTREC (or OUTFIL) is enough.

When to Use INREC IFTHEN vs OUTREC IFTHEN

INREC vs OUTREC IFTHEN
PhaseUse whenExample
INREC IFTHENThe conditional layout must affect INCLUDE/OMIT or the sort key.Normalize date to YYYY-MM-DD so INCLUDE can filter invalid dates; build a composite key for SORT.
OUTREC IFTHENYou only need different output layout by record type; sort and filter do not depend on it.Header records get one report format, detail records another; add labels or edit masks for display.

You can use both. For example: INREC IFTHEN to overlay a default date when invalid (so INCLUDE can keep only valid dates and SORT sees a consistent key), then OUTREC IFTHEN to add a "type" label in the first 10 bytes for report display. INREC affects what gets filtered and sorted; OUTREC affects what gets written.

Combining INREC, INCLUDE, and SORT

A common pattern is to normalize or fix data in INREC so that filtering and sort behave correctly. For example, overlay an invalid date with a default in INREC, then use INCLUDE to keep only records where that date is in range, then SORT by that date. The INREC step ensures the date field is in a consistent format before INCLUDE and SORT see it.

text
1
2
3
4
5
INREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(72,10,CH,EQ,C'9999-99-99'), OVERLAY=(72:C'0001-01-01')), INCLUDE COND=(72,10,CH,GE,C'2000-01-01',AND,72,10,CH,LE,C'2099-12-31') SORT FIELDS=(72,10,CH,A)

INREC overlays position 72 with a default when the date is the sentinel. Then INCLUDE keeps only records where the date (now possibly defaulted) is in the 2000–2099 range. SORT orders by that date. Without INREC, the sentinel value would not pass the INCLUDE range check and might sort incorrectly.

Adding OUTREC IFTHEN for Output Formatting

After the sort, you may want different output layout by record type. Use OUTREC IFTHEN: e.g. WHEN=(1,2,CH,EQ,C'H1') with one BUILD for headers, WHEN=(1,2,CH,EQ,C'D1') for details, WHEN=NONE for unknown. The sort already used the keys it needed; OUTREC only changes how the record is written, not which records exist or their order.

text
1
2
3
4
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(1,2,CH,EQ,C'H1'),OVERLAY=(1:1,10,C'HEADER ')), IFTHEN=(WHEN=(1,2,CH,EQ,C'D1'),OVERLAY=(1:1,10,C'DETAIL ')), IFTHEN=(WHEN=NONE,OVERLAY=(1:1,10,C'UNKNOWN '))

Every record gets bytes 1–80 from the sorted record (WHEN=INIT). Then the first 10 bytes are overwritten with a label depending on record type. So the written file has a readable prefix without changing sort order or record count.

Full Workflow Example: Normalize, Filter, Sort, Format

Put it together: (1) INREC IFTHEN to normalize or fix fields; (2) INCLUDE to drop bad or unwanted records; (3) SORT to order; (4) OUTREC IFTHEN to format output by type. Optionally (5) OUTFIL to write a second file (e.g. report or subset) with its own build or IFTHEN.

  • INREC: Overlay invalid dates, build a sort key, or shorten the record for performance.
  • INCLUDE/OMIT: Keep only records that meet your business rules (using the INREC record).
  • SORT: Order by the desired key (from the INREC record).
  • OUTREC: Apply report-style formatting, labels, or different layouts by type (IFTHEN).
  • OUTFIL: If you need more than one output (e.g. main file + report file), use OUTFIL with FNAMES= and build/IFTHEN per file.

Design Tips for Complex Workflows

Keep each phase focused. Use INREC for "what the rest of the step sees"—normalization and keys. Use INCLUDE/OMIT for "which records stay." Use OUTREC for "what gets written." If a condition is only for display, put it in OUTREC or OUTFIL; if it affects filtering or sort, put it in INREC and/or INCLUDE. Document the intended flow (e.g. in comments in the JCL or SYSIN) so that future changes do not break the order of dependencies.

Explain It Like I'm Five

Think of a factory line. First you fix the toys so they all look the same where it matters (INREC). Then you throw away the ones that don't pass the check (INCLUDE/OMIT). Then you line them up by size (SORT). Then you put different stickers on them depending on their type when you pack them in the box (OUTREC). So fixing happens first, then filtering, then sorting, then the final sticker. The order never changes.

Exercises

  1. You want to keep only records where bytes 50–53 (packed amount) are greater than zero, then sort by bytes 1–10, then write a report with the amount edited with commas. Do you need INREC IFTHEN? Where do you put the edit mask?
  2. Why can't you filter on a field that you only build in OUTREC?
  3. You have two record types and want type A in one OUTFIL file and type B in another, each with a different layout. What phases do you need (INREC? INCLUDE? SORT? OUTREC? OUTFIL?) and where does IFTHEN go?

Quiz

Test Your Knowledge

1. In what order do INREC, INCLUDE/OMIT, SORT, and OUTREC run?

  • SORT first, then INREC, then INCLUDE, then OUTREC
  • INREC first (input phase), then INCLUDE/OMIT (filter), then SORT, then OUTREC (output phase)
  • INCLUDE first, then INREC, then SORT, then OUTREC
  • OUTREC and INREC run at the same time

2. If you need to normalize a field so INCLUDE can filter on it, where do you do it?

  • In OUTREC
  • In INREC—so the normalized value is present when INCLUDE/OMIT and SORT run
  • In OUTFIL only
  • In a separate step

3. When would you use IFTHEN in both INREC and OUTREC in the same job?

  • Never; only one is allowed
  • When you need conditional reformatting that affects the sort or filter (INREC) and different conditional formatting for the final output only (OUTREC)
  • Only for COPY
  • Only when INCLUDE is omitted

4. What is a typical “complex conditional workflow” pattern?

  • Sort only
  • INREC IFTHEN to normalize or build keys → INCLUDE/OMIT to filter → SORT → OUTREC IFTHEN to format output by type; optionally OUTFIL with IFTHEN for additional outputs
  • OUTREC before INREC
  • INCLUDE only with no sort

5. Can OUTFIL use IFTHEN for conditional formatting on a secondary output file?

  • No; IFTHEN is only in INREC and OUTREC
  • Yes; OUTFIL can have its own build/overlay with IFTHEN so that each FNAMES= file gets conditionally formatted output
  • Only when SORTOUT is empty
  • Only for headers