MainframeMaster

FNAMES Usage

FNAMES (file names) is the OUTFIL parameter that tells DFSORT which DD name(s) to use for that OUTFIL's output. Every OUTFIL that writes to a dataset must specify FNAMES= so the system knows where to send the records. You can give a single DD name (e.g. FNAMES=REPORT) for one output dataset, or a list of DD names (e.g. FNAMES=(OUT1,OUT2,OUT3)) to write the same record stream to multiple datasets—or to distribute records across them when combined with SPLITBY or SPLIT1R. Each name in FNAMES= must have a matching //ddname DD ... in your JCL; otherwise the step will fail with an allocation error. This page covers FNAMES syntax (single vs multiple names, parentheses), how it interacts with split options, JCL requirements, and common usage patterns.

OUTFIL Advanced
Progress0 of 0 lessons

What FNAMES Does

FNAMES= links an OUTFIL to one or more output datasets by DD name. In z/OS, every dataset used in a job step is allocated via a DD (Data Definition) statement. The DD name is the symbol you use in the JCL (e.g. //OUT1 DD DSN=MY.DATA.OUT1,...). When DFSORT executes an OUTFIL, it writes records to the dataset(s) allocated to the DD name(s) you specify in FNAMES=. So FNAMES=OUT1 means "write this OUTFIL's output to whatever dataset is allocated to DD name OUT1." If you specify FNAMES=(OUT1,OUT2), the same output stream is written to both datasets—you get two identical copies (unless you also use a split option, which changes how records are distributed).

Syntax: Single vs Multiple Names

For a single output, code FNAMES=ddname. Parentheses are optional: FNAMES=REPORT and FNAMES=(REPORT) are equivalent. For multiple outputs, you must list the names. You can use parentheses: FNAMES=(OUT1,OUT2,OUT3), or on some systems a comma-separated list without parentheses: FNAMES=OUT1,OUT2,OUT3. The parentheses form is standard and avoids ambiguity when you have many names or other parameters on the same line.

FNAMES forms
FormMeaningExample
FNAMES=ddnameSingle output; write to this one DDFNAMES=REPORT
FNAMES=(dd1,dd2,...)Multiple outputs; same stream to each DD (or split by SPLITBY/SPLIT1R)FNAMES=(OUT1,OUT2,OUT3)
FNAMES=dd1,dd2 (no parens)Same as list: dd1 and dd2 both receive the same streamFNAMES=OUT1,OUT2

JCL Requirements

For every name that appears in FNAMES=, your JCL must include a DD statement with that name. For example, if you code OUTFIL FNAMES=(FILE1,FILE2), you need:

text
1
2
//FILE1 DD DSN=MY.OUT.FILE1,DISP=(NEW,CATLG),SPACE=(TRK,(10,5)),LRECL=80,RECFM=FB //FILE2 DD DSN=MY.OUT.FILE2,DISP=(NEW,CATLG),SPACE=(TRK,(10,5)),LRECL=80,RECFM=FB

The LRECL and RECFM should match the record length and format that the OUTFIL produces (full record or as built by BUILD=). If you omit a DD, the step will fail when DFSORT tries to open that output. So always define each FNAMES= name in the same step.

Single Name: One Output Dataset

When you have one OUTFIL and one output file, use FNAMES=ddname. For example, to write a report to a dataset named via DD REPORT:

text
1
OUTFIL FNAMES=REPORT,BUILD=(1,80,81:80X)

Every record that this OUTFIL selects (subject to INCLUDE/OMIT if any) is written to the dataset allocated to REPORT. This is the most common case: one OUTFIL, one DD, one output file.

Multiple Names: Same Stream to Multiple Datasets

When you specify FNAMES=(DD1,DD2,...,DDk) without SPLIT, SPLITBY, or SPLIT1R, the same record stream is written to every listed DD. So you get k identical copies. Use this when you need the same output in more than one place—for example, one copy for production and one for archive, or one for region East and one for region West with the same data. Example:

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

Both PROD and BACKUP receive the same 80-byte records. You must define both //PROD and //BACKUP in JCL with appropriate DSN and space.

FNAMES with SPLITBY and SPLIT1R

When you combine FNAMES=(OUT1,OUT2,OUT3) with SPLITBY=n, records are distributed in blocks of n across the files (first n to OUT1, next n to OUT2, next n to OUT3, then next n to OUT1, and so on). So the three datasets no longer get identical copies; they get different subsets in rotating blocks. With SPLIT1R=n, the first n records go to OUT1, the next n to OUT2, the next n to OUT3, and any remainder to OUT3—contiguous blocks per file. So the meaning of multiple FNAMES= names depends on whether you use a split option: without one, same stream to all; with SPLITBY or SPLIT1R, records are split by count across the list.

Multiple OUTFILs vs One OUTFIL with Multiple FNAMES

Multiple OUTFILs, each with its own FNAMES= (usually one name per OUTFIL), let you write different content to different files: different INCLUDE/OMIT, different BUILD, or SAVE on the last to catch the rest. One OUTFIL with FNAMES=(A,B,C) without a split option writes the same content to A, B, and C. So: use multiple OUTFILs when you want different data or format per file; use one OUTFIL with multiple FNAMES when you want identical copies or when you are using SPLITBY/SPLIT1R to distribute by count.

Record Length and Format

The record length written to each FNAMES= dataset is determined by the OUTFIL: either the full record (after INREC/OUTREC if present) or the length defined by BUILD= on that OUTFIL. All datasets in the same FNAMES= list receive the same record format and length. So set LRECL and RECFM on each DD to match (e.g. LRECL=80, RECFM=FB for 80-byte fixed blocked).

Common Mistakes

  • Forgetting the DD in JCL: Every FNAMES= name must have a //ddname DD ... in the same step. Missing DD causes allocation failure.
  • Wrong LRECL: If OUTFIL builds 100-byte records (e.g. BUILD=(1,100)), the DD must have LRECL=100 (or the record length you build). Mismatch can cause truncation or abends.
  • Using FNAMES for different content: If you need different records in different files (e.g. by department), use multiple OUTFILs with different FNAMES= and INCLUDE=, not one OUTFIL with many FNAMES= (which duplicates the same stream).

Explain It Like I'm Five

FNAMES is like writing the same letter to three friends. You put three addresses (OUT1, OUT2, OUT3) on the envelope list—that's FNAMES=(OUT1,OUT2,OUT3). The post office (DFSORT) sends one copy to each address. So all three get the same letter. If you use a special rule like "send the first 500 letters to friend 1, the next 500 to friend 2," that's SPLITBY or SPLIT1R—then they get different bundles instead of the same copy. The addresses (DD names) must be real: you have to define them in JCL or the post office won't know where to send the mail.

Exercises

  1. Write an OUTFIL that writes the same 80-byte record stream to two datasets named COPYA and COPYB. What JCL do you need?
  2. You have OUTFIL FNAMES=(X,Y,Z),SPLIT1R=1000. How many records go to X, Y, and Z if the input has 2500 records?
  3. When would you use one OUTFIL with FNAMES=(A,B) instead of two OUTFILs with FNAMES=A and FNAMES=B?
  4. What happens if you code FNAMES=REPORT but your JCL has no //REPORT DD statement?

Quiz

Test Your Knowledge

1. What does FNAMES= on an OUTFIL statement specify?

  • The input file DD name
  • The DD name(s) of the dataset(s) where this OUTFIL output is written
  • The sort key field names
  • The record format

2. What is the effect of OUTFIL FNAMES=(COPY1,COPY2),BUILD=(1,80)?

  • Only COPY1 is written to
  • The same 80-byte record stream is written to both COPY1 and COPY2
  • COPY1 gets 40 bytes, COPY2 gets 40 bytes
  • BUILD is ignored when multiple names are used

3. When using FNAMES=(OUT1,OUT2,OUT3) with SPLITBY=500, how are records distributed?

  • All records to OUT1 only
  • First 500 to OUT1, next 500 to OUT2, next 500 to OUT3, then next 500 to OUT1 again (rotating)
  • 500 total across all three
  • OUT1 gets 500, OUT2 and OUT3 get the rest

4. You want one OUTFIL to write to a single report dataset. How do you code FNAMES?

  • FNAMES=(REPORT)
  • FNAMES=REPORT (single name, no parentheses required)
  • FNAMES=REPORT, only in MERGE
  • You must use SORTOUT only

5. What happens if you use FNAMES=OUT1 in OUTFIL but do not define //OUT1 in JCL?

  • DFSORT uses SORTOUT instead
  • The step fails with a JCL or allocation error because the DD name is missing
  • OUT1 is created automatically
  • Only a warning is issued