What it means
The mainframe does decimal arithmetic directly on packed decimal (COMP-3) and zoned decimal fields. Before it adds, compares or moves one of those fields as a number, the hardware checks that every byte holds a valid digit and that the last half-byte holds a valid sign. If the check fails, the processor raises a data exception, program interrupt code 7, and z/OS ends the step with system completion code 0C7.
So the instruction that failed isn't wrong in itself. The data reaching it is. The fix is almost always to find which field held bad data, and where that data came from.
Common causes
- A numeric field in WORKING-STORAGE was never given a starting value, so it still holds whatever was in storage (often low-values).
- An input record has spaces, letters or low-values where a number should be, for example a blank amount on a file from another system.
- The record layout (copybook) doesn't match the file, so the program reads the wrong bytes as a number. This often happens after someone adds a field to the file but not to every program that reads it.
- A group (alphanumeric) MOVE copied text into a numeric field without converting it.
- A table subscript or index ran past the end of the table and the program read or overwrote storage that belongs to another field.
- A field defined as COMP-3 in one program is passed to another program that defines it as DISPLAY, or the other way round.
How to find the problem
- Open the job log and look for
CEE3207S The system detected a data exception(Language Environment) or theIEA995Isymptom dump. Note the program name and the offset, such as+000004A2. - Recompile the program with the LIST (or OFFSET) option, or open the listing you already have, and find that offset. It points to the statement that did the arithmetic.
- Look at every numeric field used in that statement. One of them holds the bad value. If you have a dump, a debugger or a tool such as Fault Analyzer or Abend-AID, display those fields in hex. In a valid packed field every half-byte is a digit from 0 to 9, except the last one, which is the sign. The sign is normally C, D or F, and the hardware also accepts A, B and E.
- Find the record being processed when the step failed (the dump or the last record count in your messages usually tells you), and check that field in the input data set.
How to fix it
- Fix the data at the source if a file arrived with bad values, then rerun from the failed step.
- Give every numeric WORKING-STORAGE field a starting value with VALUE ZERO or an INITIALIZE statement.
- Check input before using it:
IF WS-AMOUNT IS NUMERIClets the program reject or report a bad record instead of abending. - Make sure every program that reads the file uses the same, current copybook, and recompile them after a layout change.
- If a subscript is involved, add a range check, or compile with SSRANGE in test to catch it early.
What it looks like
IEA995I SYMPTOM DUMP OUTPUT
SYSTEM COMPLETION CODE=0C7 REASON CODE=00000007
CEE3207S The system detected a data exception (System Completion Code=0C7).
From compile unit PAYCALC at entry point PAYCALC at compile unit offset +000004A2
IEF450I PAYRUN01 STEP020 - ABEND=S0C7 U0000 REASON=00000007