When you use SUM FIELDS= to add up a numeric field per group, the result is written back into the same byte range as the input field. If the total is larger than that field can hold, you get overflow. DFSORT gives you two behaviors: VLSHRT (variable-length short) and NOVLSHRT. With VLSHRT, the result is truncated to fit so the job continues—but you may lose high-order digits and the total can be wrong. With NOVLSHRT, overflow is not allowed: the step fails so you can increase the field size (e.g. via INREC) or fix the data. This page explains when overflow happens, how to specify VLSHRT and NOVLSHRT, how to avoid overflow by sizing the field correctly, and the trade-off between “keep running” and “guarantee correct totals.”
Overflow occurs when the sum of a numeric field across all records in a group is larger than the maximum value that can be stored in that field’s length and format. For example: a 5-byte zoned decimal (ZD) field holds 5 digits plus sign, so the maximum value is 99,999 (or -99,999). If you sum 100 records and each has a value of 10,000, the total is 1,000,000—6 digits. That does not fit in 5 digits, so you get overflow. Similarly, a 4-byte packed decimal (PD) holds 7 digits plus sign; if the sum exceeds 9,999,999 (or the negative equivalent), it overflows.
VLSHRT (variable-length short): when the sum does not fit in the output field, DFSORT truncates the value to fit. The job continues and writes the truncated result. You may lose the most significant digits—for example a total of 1,234,567 in a 5-digit field might become 34,567 or a product-specific truncation. So the output can be wrong and there is no built-in signal that overflow happened. Use VLSHRT when you prefer the job not to abend and can accept possible data loss (e.g. non-critical reporting).
NOVLSHRT: when the sum overflows, DFSORT does not truncate. Instead, the step terminates with an error (e.g. an ICE message or abend). You then fix the cause: increase the field length (e.g. with INREC so the summed field is longer) or correct the data. Use NOVLSHRT when you need to guarantee that no overflow is silently lost—for example in financial or audit-sensitive totals.
| Option | Behavior on overflow | When to use |
|---|---|---|
| VLSHRT | If sum overflows, truncate to fit in the field; job continues | Acceptable to lose digits; prefer no abend |
| NOVLSHRT | If sum overflows, do not truncate; step fails with error | Need to guarantee correct totals; detect bad data or layout |
You can specify VLSHRT or NOVLSHRT on the OPTION statement (e.g. OPTION NOVLSHRT) so it applies to the whole step, or in some products on the SUM statement (e.g. SUM FIELDS=(21,5,ZD),NOVLSHRT). If both are present, the SUM-level option may override for that SUM. The exact syntax and default (VLSHRT or NOVLSHRT) depend on your DFSORT version; see your installation’s documentation.
123OPTION NOVLSHRT SORT FIELDS=(1,8,CH,A) SUM FIELDS=(21,5,ZD),NOVLSHRT
If the sum of the 5-byte ZD at 21–25 overflows, the step will fail instead of truncating. You can then increase the field (e.g. INREC to put the value in a 7-byte or 8-byte field) and sum that instead.
The safest way to avoid overflow is to make the summed field large enough for the largest possible total. Estimate: maximum sum ≈ maximum value per record × maximum number of records per group. Then choose a field length and format that can hold that number. For example, if the max value per record is 99,999 and you have up to 10,000 records per group, the max sum is 999,990,000 (9 digits). A 4-byte PD holds 7 digits + sign; a 5-byte PD holds 9 digits + sign. So you need at least 5 bytes packed, or the equivalent in ZD. Use INREC to build a record where the value to be summed is in a longer field (e.g. copy the original 5-byte amount into a 6-byte or 8-byte position), then specify that longer position and length in SUM FIELDS=. The sum is then written into the longer field and will not overflow as long as the length is sufficient.
Input: amount at 21–25 (5-byte ZD). You expect up to 100,000 records per group and values up to 99,999, so the max sum is 9,999,900,000 (10 digits). Use INREC to copy the amount into a longer field (e.g. 6-byte PD at 26–31, which holds 11 digits + sign), then sort and sum that field.
123INREC OVERLAY=(26,6,PD,21,5,ZD) SORT FIELDS=(1,8,CH,A) SUM FIELDS=(26,6,PD)
The exact INREC syntax for copying or converting one field into another (e.g. ZD to PD in a longer field) is product-dependent. The idea is: the field that SUM writes to is now 6 bytes PD at 26–31, which can hold a much larger total. Non-summed positions (e.g. 1–25) still come from the first record of the group; position 26–31 holds the sum.
The names VLSHRT and NOVLSHRT also relate to how DFSORT handles variable-length (VB) records when record length is shorter than the maximum. In some products, VLSHRT improves performance or correctness for VB input; NOVLSHRT may be required when using SUM with variable-length data. If you use VB input and see unexpected truncation or abends with SUM, try NOVLSHRT or consult your manual for variable-length and SUM.
Imagine you have a small box that can only hold a number with 5 digits (like 99,999). You add up a lot of numbers and the total is 1,234,567. The box is too small. VLSHRT is like squeezing the number into the box by cutting off the front—you might get 34,567 in the box, but the real total was 1,234,567, so it’s wrong. NOVLSHRT is like the computer saying “I won’t put it in the box; I’ll stop and tell you to get a bigger box.” So you get a bigger box (a longer field) and try again. The “bigger box” in the computer is making the sum field longer with INREC.
1. What happens when the sum of a numeric field is too large to fit in the output field (overflow)?
2. How do you prevent overflow when summing many large values?
3. Where do you specify VLSHRT or NOVLSHRT?
4. Why would you choose NOVLSHRT over VLSHRT?
5. You sum a 5-byte ZD field; the maximum value per record is 99999 and you have up to 1000 records per group. What is a safe approach?