Adding sequence numbers in DFSORT means giving each record a sequential numeric value—1, 2, 3, … or a custom start and step (e.g. 1000, 1010, 1020). You use the SEQNUM keyword in INREC or OUTREC, with a length and format (ZD, PD, or BI). Optional START= and INCR= set the starting value and increment. The crucial choice is where to add the number: INREC assigns it in input order (before the sort), and OUTREC assigns it in output order (after the sort). This page explains how to add sequence numbers, where to put them in the record, which format to use, and when to use INREC vs OUTREC. For restarting the sequence at each group, see Resetting sequence numbers.
Sequence numbers give each record a unique position identifier. Common uses: report line numbers (1, 2, 3, … on each line of a report), preserving or restoring input order (add a number before the sort, then sort by it later to get back to original order), item numbers within a group (e.g. 1, 2, 3 within each order—see Resetting sequence numbers), and audit or tracking (each record has a unique sequence for reference). DFSORT generates these automatically with SEQNUM; you do not need a separate program.
INREC runs in the input phase, before the sort. So when you use SEQNUM in INREC, the first input record gets 1 (or START=), the second input record gets 2 (or START+INCR), and so on. After the sort, the records are in a different order—so the sequence numbers no longer increase in output order; they still reflect input order. Use INREC SEQNUM when you need to preserve original position or when the sequence number is part of a key used for sorting (e.g. to restore input order later).
OUTREC runs in the output phase, after the sort. So when you use SEQNUM in OUTREC, the first output record gets 1, the second gets 2, and so on. The numbers match the order records are written. Use OUTREC SEQNUM when you want line numbers or position numbers in the final output (e.g. report lines 1, 2, 3 in printed order).
| Phase | Order numbers follow | Typical use |
|---|---|---|
| INREC SEQNUM | Input order (order records were read) | Preserve original position; sort back by sequence later; sequence as part of sort key. |
| OUTREC SEQNUM | Output order (order records are written) | Report line numbers; position in final file; display order. |
In OUTREC, a common form is OVERLAY=(position:SEQNUM,length,format). The position is the starting byte in the output record where the sequence number is placed; length is the number of bytes (e.g. 5 for up to 5 digits in ZD); format is ZD, PD, or BI. Optional START= and INCR= follow the format.
12SORT FIELDS=(1,10,CH,A) OUTREC OVERLAY=(21:SEQNUM,5,ZD)
The sort runs first. Then OUTREC overlays positions 21–25 with a 5-byte zoned decimal sequence number (1, 2, 3, …). The rest of the record is unchanged. So the output has the sorted record with the sequence number at 21–25.
To place the sequence number in a specific place within a BUILD or FIELDS= layout, use position:SEQNUM,length,format as an item in the list. For example, to build an output with bytes 1–20 from input, then the sequence number, then bytes 21–80 from input:
1OUTREC FIELDS=(1,20,21:SEQNUM,5,ZD,21,80)
Here 1,20 copies input bytes 1–20 to output 1–20. Then 21:SEQNUM,5,ZD puts the 5-byte sequence number at output positions 21–25. Then 21,80 copies input bytes 21–80 to the output—the output position continues after the sequence number, so input 21–80 go to output 26–85. The total output length is 85 bytes. (Exact placement rules depend on DFSORT FIELDS= semantics; see your manual. The idea is that position:SEQNUM inserts the number at that output position.)
Length must be large enough to hold the maximum sequence value. For ZD, each byte holds one digit, so length 5 allows values 1 through 99999. For more records, use a larger length (e.g. 7 for 9999999). For PD and BI, the maximum value depends on the length and format; see the data types tutorials.
ZD (zoned decimal): One digit per byte in EBCDIC. When you print or display the record, the number appears as normal digits. Best for report line numbers or any human-readable sequence.
PD (packed decimal): Compact storage; good when the sequence number is used internally or as a sort key and you want to save space.
BI (binary): Fullword or halfword binary. Use when a downstream program expects a binary integer.
By default the sequence starts at 1 and increments by 1. START= sets the first value; INCR= sets the step. For example, SEQNUM,5,ZD,START=1000,INCR=10 produces 1000, 1010, 1020, … for each record. Use START when you need a specific starting value (e.g. to avoid overlapping with another numbering scheme). Use INCR when you need a step other than 1 (e.g. 10, 100) for spacing or alignment.
1OUTREC OVERLAY=(1:SEQNUM,7,ZD,START=1000000,INCR=1)
This places a 7-digit ZD sequence number at position 1, starting at 1000000 and incrementing by 1. So the first record gets 1000000, the second 1000001, and so on.
When you add SEQNUM in INREC, include it in the INREC FIELDS= or BUILD= so that the sequence number is part of the record that INCLUDE/OMIT and SORT see. For example, to keep the first 10 bytes, add a 5-byte ZD sequence number, then the rest of the record:
12INREC FIELDS=(1,10,SEQNUM,5,ZD,11,80) SORT FIELDS=(1,10,CH,A)
Each input record gets a number in read order (1, 2, 3, …). The sort then orders by the first 10 bytes. The sequence number remains in the record and still reflects input order. If you later need to restore input order, you could sort by the sequence number field (e.g. bytes 11–15 if that is where it landed in the layout).
Ask: do I need the number to reflect input order or output order? For report line numbers (1, 2, 3 in printed order), use OUTREC. For preserving or restoring original position, or for using the number as a sort key, use INREC. If you need both—e.g. an input-order sequence for audit and output-order line numbers for the report—you can use INREC to add one sequence number and OUTREC to overlay or add another at a different position (or use OUTFIL for a second output with its own sequence).
Imagine numbering a stack of cards. If you number them before you shuffle (INREC), then after you shuffle the numbers are mixed up—but you still know which card was first, second, third in the original stack. If you number them after you shuffle (OUTREC), then the first card in the new stack gets 1, the second gets 2—the numbers match the new order. So "before shuffle" = INREC (input order); "after shuffle" = OUTREC (output order).
1. You want line numbers 1, 2, 3, … in the order the report is printed. Where do you add SEQNUM?
2. You need to preserve the original input order and later sort back by it. Where do you add the sequence number?
3. What does START=1000,INCR=10 do with SEQNUM?
4. Which format (ZD, PD, BI) is best for a human-readable line number in a report?
5. In OUTREC FIELDS=(1,20,21:SEQNUM,5,ZD,26,80), where does the sequence number appear and how long is it?