Field reordering in DFSORT means changing the order in which fields (columns) appear in the output record. The sorted record has fields in a fixed layout; with OUTREC FIELDS= or BUILD= you list the fields in the order you want them in the output. You can also drop fields by not listing them, and insert spaces, constants, or padding between fields. The key rule: the order of items in FIELDS= or BUILD= is the order in the output. Each item is either a (position,length) copy from the record at output time, or a constant (nX, nZ, C'...', X'...'). This page explains how to reorder columns, drop fields, insert spaces and delimiters, and how to compute the output record length for SORTOUT LRECL.
The input (or INREC) record may have a layout that does not match what you need for a report, a downstream program, or an interface. For example the key might be at the end of the record but the next program expects it at the start; or you want a report with columns in a different order (e.g. name, then id, then amount). Reordering with OUTREC does not change the sort order or the number of records—it only changes the layout of each record as it is written. You can also shorten the record by listing only the fields you need (dropping the rest) and optionally insert spaces or delimiters for readability.
In OUTREC FIELDS=(item1,item2,item3,...) or BUILD=(...), the items are written to the output record in the order you list them. So the first item becomes the first bytes of the output, the second item follows, and so on. To reorder, list the (position,length) pairs in the order you want those fields to appear. For example: input has id at 1–10, name at 11–30, amount at 31–38. You want output: name, then id, then amount. Then:
1OUTREC FIELDS=(11,20,1,10,31,8)
Output: 20 bytes from 11–30 (name), then 10 bytes from 1–10 (id), then 8 bytes from 31–38 (amount). Total 38 bytes. So you have reordered without changing the data; only the column order changed.
Each item in the list can be:
| Item | Meaning | Example |
|---|---|---|
| (pos,len) | Copy len bytes from input at pos | (21,20) → 20 bytes from 21–40 |
| nX | n blank (space) characters | 5X → 5 spaces |
| nZ | n binary zeros | 4Z → 4 bytes X'00000000' |
| C'...' | Character constant | C'|' → one pipe |
| X'...' | Hexadecimal constant | X'40' → one EBCDIC space |
(position,length) always refers to the record as it exists at output time (the sorted record, or the INREC record if INREC was used). So if INREC produced a 50-byte record, positions in OUTREC are 1–50. The output record length is the sum of the lengths of all items: each (pos,len) contributes len, nX contributes n, nZ contributes n, and C'...' or X'...' contributes the byte length of the constant.
You drop a field by not including it in the FIELDS= or BUILD= list. Only the items you list are written. So if the input has 80 bytes and you need only three fields—say at 1–5, 20–29, and 70–80—you list only those:
1OUTREC FIELDS=(1,5,20,10,70,11)
Output is 5+10+11 = 26 bytes. All other bytes of the input are dropped. So reordering and dropping go together: you choose which fields to keep and in what order.
To separate columns with spaces, use nX between the field items. For example: id (1–10), 5 spaces, name (11–30), 5 spaces, amount (31–38):
1OUTREC FIELDS=(1,10,5X,11,20,5X,31,8)
Output length: 10+5+20+5+8 = 48 bytes. You can use a delimiter like a comma or pipe: C\',\' or C\' | \' instead of or in addition to spaces. So FIELDS=(1,10,C\',\',11,20,C\'|\',31,8) produces id, comma, name, pipe, amount. The output length includes the length of each constant.
Some products support output position syntax in BUILD=, e.g. out_pos:input_start,length, so you can place a field at an exact output position. With plain FIELDS=, the position is implicit (next available). For simple reordering, listing items in the desired order is enough; the first item goes at output 1, the second continues after the first, and so on. BUILD= with output positions is useful when you need fixed output positions (e.g. for a copybook layout). Check your manual for exact BUILD= syntax.
The SORTOUT dataset must have LRECL equal to the length of the record that OUTREC builds. To compute it, add: for each (position,length), add length; for nX or nZ, add n; for C'literal', add the number of characters; for X'hex', add half the number of hex digits (each pair is one byte). For edited or converted fields (e.g. edit mask), the length is determined by the edit pattern or LENGTH= parameter. Getting LRECL wrong can cause truncation, padding, or allocation errors.
Input: 1–8 id, 9–28 name, 29–36 amount (PD). You want a report line: name (20 bytes), 3 spaces, id (8 bytes), 3 spaces, then amount (8 bytes). No edit on amount for this example.
1OUTREC FIELDS=(9,20,3X,1,8,3X,29,8)
Output: 20+3+8+3+8 = 42 bytes. Name appears first, then spaces, id, spaces, amount. Sort order is unchanged; only the layout is different.
For variable-length (VB) output, the first 4 bytes are the RDW. Typically you include the RDW as the first item (e.g. 1,4) so the record descriptor is copied, then list the data fields in the order you want. Do not reorder or drop the RDW; the system needs it to interpret record length.
Imagine you have a row of boxes: first box has your name, second has your number, third has your score. Someone asks for the row in a different order: first score, then name, then number. You don’t change what’s inside each box—you just write them on a new row in that order. Field reordering is like that: we take the same pieces of the record (the fields) and write them in a new order. We can also leave out some boxes (drop fields) or add empty spaces between boxes (nX) so the new row is easy to read.
1. How do you reorder fields in DFSORT OUTREC?
2. What does OUTREC FIELDS=(50,10,1,20,30,15) produce?
3. How do you drop fields when reordering?
4. To insert 5 spaces between two fields in the output, what do you add to FIELDS=?
5. Do (position,length) in OUTREC refer to the input or the output record?