So there I was... working on this batch COBOL program. The program was responsible for calculating the next settlement day based on a day-of-week code. The code is stored in a Db2 table as a 2-character field.
MOVE SETTLEMENT-DAY-CD TO WS-DESIED-WDAY
COMPUTE WS-DELTA-DAYS = WS-DESIRED-WDAY - WS-CUR-WDAY
Ship it. Done. Let's grab a coffee.
But THEY had other plans. It was not, in fact, done.
The results were awkward. Instead of scheduling settlements for Friday (2 days away), the program wants to schedule them for 47 days from now.
Wait. What?
Down the rabbit hole
So, I'm staring at the code and I notice something weird.
The DCLGEN says
10 SETTLEMENT-DAY-CD PIC X(2).
I assumed this meant values like '05' for Friday: 2 digits and zero-padded.
But the actual value in the database was different. '5 ' (that's 5 followed by a space).
In Hex mode: F5 40 (EBCDIC for "5" and " ")
What COBOL did with that?
When I did:
MOVE '5 ' TO WS-DESIRED-WDAY (where WS-DESIRED-WDAY is defined with PIC 9(2))
COBOL was like, "Ok, two characters going into two numeric positions. The first character is '5' and the second character is a space. Since the destination field is a numeric, I'll rather put a zero than a space."
Result: 50
Not 5. Not 05. Fifty.
The fix
COBOL has this function called
NUMVAL that actually thinks about what you're trying to do.
COMPUTE WS-DESIRED-WDAY = FUNCTION NUMVAL(SETTLEMENT-DAY-CD)
Now, NUMVAL looks at '5 ' and goes, "Ah! You mean the number 5. Got it. Ignoring that trailing space for you."
The Before & After
Before (me being naive):
MOVE SETTLEMENT-DAY-CD TO WS-DESIRED-WDAY
* '5 ' becomes 50
After (me being slightly less naive)
COMPUTE WS-DESIRED-WDAY = FUNCTION NUMVAL(SETTLEMENT-DAY-CD)
* '5 ' becomes 5
Quick Reference
TL:DR
If you are moving character data to a numeric field and it might have spaces or inconsistent formatting,
Don't: MOVE CHAR-FIELD TO NUMERIC-FIELD
Do: COMPUTE NUMERIC-FIELD = FUNCTION NUMVAL(CHAR-FIELD)
Got your own COBOL horror stories? Drop them in the comments section below. Misery loves company.
No comments:
Post a Comment