When I started programming on the iSeries (a while ago), I occasionally ran into one thing that really frustrated me! Every now and then, a program would blow up with a decimal data error during testing. The parameter passing didn't work right for some reason. After doing some research and asking my coworkers for help, I learned a valuable lesson in parameter passing.
If you pass two parameters to a program from a command line, as shown below, the program defines both parameters.
If the program is written in CL, it will look something like this:
DCL VAR(&TEXT) TYPE(*CHAR) LEN(3)
DCL VAR(&NBR) TYPE(*DEC) LEN(3 0)
This program, like the ones I had trouble with, will blow up and issue a decimal data error. It fails because of the way parameters are passed on the iSeries. CL and RPG III programs pass parameters by reference. This means that they do not pass the data in the parameters; they pass the address of the data.
When the call statement shown above was issued, the system allocated memory to hold the parameters. By default, the system allocates 32 bytes of data to hold the character field and 8 bytes of data to hold the number as a packed field with 15 digits and five decimals. The data looks something like this:
A | B | C | | | | | | | | | | | | | 30 | 31 | 32 |
0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 2 | 0 | 0 | F |
The character field works fine. The program is only expecting three characters, so it ignores the extra data and loads in the first 3 bytes of data allocated above:
A | B | C | | | | | | | | | | | | | 30 | 31 | 32 |
The numeric field, however, is a different story. The program is expecting three digits, which pack into 2 bytes of data, so it ignores the last 8 bytes and loads the first 2 bytes:
0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 2 | 0 | 0 | F |
When the data is loaded, starting at the first byte, the program doesn't find valid numeric data, and it issues a decimal data error. It's not valid because the last half-byte is not a valid sign. It should be either an F for positive values or a D for negative values.
Now that you know what the problem is, how do you fix it? If the program had defined &NBR as a 15,5 decimal field, it would have read the numeric parameter correctly. Or you could learn how to write in hex! Instead of changing the program, try passing the data like this:
The x'...' indicates that the numeric values within quotes should be written in a packed hex format.
A lot of iSeries programmers give up on passing numeric parameters because of this problem. But now you know the solution, and you can show all your coworkers how to do it right!
Kevin Forsythe has over 19 years of experience working with the iSeries platform and its predecessors. He has been a member of the DMC team for the past nine years. Kevin's primary responsibility is providing iSeries education, but he also provides customers with project management, system design, analysis, and technical construction. In addition to his technical skills (RPG IV, CL, OS/400, SQL, FTP, Query, VB, Net.Data), Kevin possesses the ability to communicate new and complex concepts to his students. He has been the primary instructor for DMC's iSeries-based AS/Credentials training courses since 1997 and has authored courses such as Advanced ILE, SQL, Embedded SQL, Operations Navigator, and Intro to WebSphere Studio. An award-winning speaker, he has spoken at every COMMON Conference since the spring of 2000.
LATEST COMMENTS
MC Press Online