MainframeMaster

Multiple Outputs

Multiple outputs in DFSORT means writing to more than one dataset or report from a single sort step. Instead of running the sort several times to produce several files, you use multiple OUTFIL statements. Each OUTFIL specifies FNAMES= (the DD name or names where that output is written) and can have its own INCLUDE or OMIT so only certain records go to that file, and its own BUILD= so the record layout can differ per output. You can also list multiple DD names in one FNAMES= (e.g. FNAMES=OUT1,OUT2) to write the same stream to two or more datasets—useful when you need identical copies. Your JCL must define a DD statement for every name used in FNAMES=. This page covers why to use multiple outputs, how to code multiple OUTFILs, FNAMES= with one or many names, order of processing, and how SAVE captures records not selected by earlier OUTFILs.

OUTFIL Advanced
Progress0 of 0 lessons

Why Use Multiple Outputs?

In batch jobs you often need the same sorted data in more than one place: for example, one file for department A, one for department B, and one for everyone else; or one dataset with full records and another with a short summary for a report; or the same sorted file written to two different DSNs (e.g. production and backup). If you ran a separate SORT step for each output, you would read and sort the input once per step—wasting CPU and time. With multiple OUTFIL statements, you sort once and then, in the output phase, each record is evaluated against each OUTFIL. Matching records are written to the corresponding dataset(s). So one read and one sort produce many outputs.

Common multiple-output scenarios
ScenarioApproachNote
Same data, multiple copiesOne OUTFIL with FNAMES=OUT1,OUT2,...Identical stream to each DD
Different subsets (e.g. by department)Multiple OUTFILs, each with INCLUDE= (or OMIT=) and different FNAMES=One file per department or category
Different formatsMultiple OUTFILs, same or different filters, different BUILD= per OUTFILE.g. full record to one file, summary to another
Catch-all plus specificOUTFILs with INCLUDE= for each category, last OUTFIL with SAVESAVE gets records not written by earlier OUTFILs

Multiple OUTFIL Statements

Each OUTFIL statement defines one output stream. You can have as many OUTFILs as you need (within product limits). Each must specify FNAMES= so DFSORT knows which DD name(s) to write to. Example with three outputs:

text
1
2
3
4
SORT FIELDS=(1,10,CH,A) OUTFIL FNAMES=DEPT1,INCLUDE=(30,5,CH,EQ,C'DEPT1'),BUILD=(1,50) OUTFIL FNAMES=DEPT2,INCLUDE=(30,5,CH,EQ,C'DEPT2'),BUILD=(1,50) OUTFIL FNAMES=OTHER,SAVE,BUILD=(1,50)

The first OUTFIL writes only records where bytes 30–34 equal 'DEPT1' to the dataset allocated to DD name DEPT1. The second does the same for 'DEPT2' to DEPT2. The third has SAVE: it receives every record that was not written by the first or second OUTFIL (all records whose bytes 30–34 are neither DEPT1 nor DEPT2). All three outputs get a 50-byte built record. Your JCL must include //DEPT1 DD ..., //DEPT2 DD ..., and //OTHER DD ....

FNAMES= with One DD Name

Most often each OUTFIL has a single DD name: FNAMES=OUT1. That OUTFIL's output goes only to the dataset allocated to OUT1. Use one FNAMES= per OUTFIL when each output is distinct (different filter or different BUILD).

FNAMES= with Multiple DD Names (Same Stream)

You can list several DD names in one FNAMES=: FNAMES=OUT1,OUT2,OUT3. In that case, the same record stream—every record selected by this OUTFIL (and after any INCLUDE/OMIT and BUILD for this OUTFIL)—is written to all of those datasets. So OUT1, OUT2, and OUT3 get identical data. Use this when you need duplicate copies (e.g. one for production and one for archive, or one for region A and one for region B with the same content). The JCL must define all three DDs (//OUT1, //OUT2, //OUT3) with the appropriate DSN and DISP.

text
1
OUTFIL FNAMES=MAIN,BACKUP,BUILD=(1,80)

Here, every record (no INCLUDE/OMIT) is built as 80 bytes and written to both MAIN and BACKUP. So you get two identical 80-byte files from one OUTFIL.

JCL Requirements

For every name you use in FNAMES=, you must have a corresponding DD statement in the same step. The DD specifies the dataset name (DSN=), disposition (DISP=), and optionally LRECL, RECFM, and SPACE. The record length written is determined by the OUTFIL (e.g. BUILD= length or full record length); the DD's LRECL should match. If you reference FNAMES=REPORT and do not have //REPORT DD ... in the JCL, the step will fail at allocation or when DFSORT tries to open the file.

Order of OUTFIL Processing

DFSORT evaluates each record against the OUTFIL statements in the order they appear in SYSIN. For each record, the first OUTFIL whose condition (INCLUDE/OMIT, or no condition) is satisfied can write that record. So if OUTFIL1 has INCLUDE=(1,2,CH,EQ,C'01') and OUTFIL2 has INCLUDE=(1,2,CH,EQ,C'02'), a record with bytes 1–2 = '01' goes to OUTFIL1; a record with '02' goes to OUTFIL2. A record with '03' goes to neither unless you have a later OUTFIL with SAVE. The OUTFIL with SAVE should usually be last so it receives "everything else."

SAVE: Catch-All Output

SAVE on an OUTFIL means: write to this OUTFIL any record that has not been written by any previous OUTFIL in this step. So you use one or more OUTFILs with INCLUDE (or OMIT) to send specific record types to specific files, and one final OUTFIL with SAVE to capture all remaining records. Without SAVE, records that do not match any OUTFIL's INCLUDE/OMIT are not written to any OUTFIL (they may still go to SORTOUT if you have one). With SAVE, you ensure no record is "dropped" from the OUTFIL side—every record goes to at least one OUTFIL (the first it matches, or the SAVE one).

Different BUILD per OUTFIL

Each OUTFIL can have a different BUILD= (or no BUILD, meaning full record). So one OUTFIL might write a 20-byte summary (BUILD=(1,10,30,10)) and another the full 80-byte record (BUILD=(1,80) or omit BUILD). That way you get a short extract in one file and the full detail in another from the same sort.

SORTOUT and OUTFIL Together

You can have both SORTOUT and multiple OUTFILs. By default, the main sorted stream goes to SORTOUT (after OUTREC if specified). OUTFILs add extra outputs. If you want the main output to also be filtered or reformatted by OUTFIL logic, you can use OUTFIL FNAMES=SORTOUT,... so that the primary output is controlled by that OUTFIL (e.g. INCLUDE= or BUILD=). Then the same record might go to SORTOUT and to other OUTFILs depending on your conditions.

Explain It Like I'm Five

Imagine one big pile of sorted cards and several boxes. Each box has a label (FNAMES=). The rule for Box 1 is "only cards that say DEPT1"; for Box 2 "only cards that say DEPT2"; for Box 3 "all the rest." You go through the pile once and put each card in the right box. You might also say "when you put a card in Box 1, only copy the first 50 letters onto a new card"—that's BUILD= for that box. So multiple outputs = one pass through the data, many boxes (files), each with its own rule and optional shorter copy.

Exercises

  1. Code three OUTFILs: FILEA (records with byte 1 = 'A'), FILEB (byte 1 = 'B'), and FILEREST (SAVE). What JCL DD names are required?
  2. You want the same 80-byte sorted output written to both PROD and BACKUP. Write one OUTFIL that does this.
  3. Why is it more efficient to use multiple OUTFILs than to run three separate SORT steps that each read the same input and produce one output?
  4. If you put the OUTFIL with SAVE first instead of last, what would happen to records that match a later OUTFIL's INCLUDE?

Quiz

Test Your Knowledge

1. How do you write to more than one output file from a single DFSORT step?

  • You cannot
  • Use multiple OUTFIL statements, each with its own FNAMES= (DD name) and optional INCLUDE/OMIT/BUILD
  • Use multiple SORTOUT
  • Use INREC twice

2. What does FNAMES=OUT1,OUT2 mean on a single OUTFIL?

  • Write to OUT1 or OUT2
  • Write the same record stream to both OUT1 and OUT2—both datasets get identical data
  • Only OUT1 is used
  • Split records between OUT1 and OUT2

3. What must you do in JCL when using OUTFIL FNAMES=REPORT1,REPORT2?

  • Nothing
  • Define //REPORT1 and //REPORT2 DD statements with the correct DSN and DISP so DFSORT can write to both datasets
  • Only REPORT1
  • Use SORTOUT only

4. When would you use multiple OUTFILs instead of one SORTOUT?

  • Never
  • When you need different files: e.g. one file per department, or one full-format file and one summary file, or a report plus a data file—all from one sort
  • Only for reports
  • Only when sorting

5. Does the order of OUTFIL statements matter?

  • No
  • Yes. Records are evaluated against OUTFILs in order; the first OUTFIL whose INCLUDE/OMIT is satisfied can receive the record. SAVE on a later OUTFIL catches records not written by earlier OUTFILs
  • Only for BUILD
  • Only for FNAMES