Tuesday, June 21, 2022

Extra parameters added to Call command to prevent decimal data error

new parameters added to call command

Anyone who has programmed on IBM i has experienced this frustration. I want to call a CL program from a command line. I type:

CALL CL_PGM ('A' 12)

And I am presented with the following error:

MCH1202 received by procedure CL_PGM. (C D I R)

For the beginner this is cryptic. When I drill down into the job log I can see what really happened:

> CALL CL_PGM('A' 12)
  Decimal data error.
  Function check. MCH1202 unmonitored by CL_PGM at statement 0000000700
    instruction X'0000'.
  MCH1202 received by procedure CL_PGM. (C D I R)
  MCH1202 received by procedure CL_PGM. (C D I R)

Why is what I passed to the program causing a decimal error?

When I pass a number like this to a CL program it has to be in hexadecimal, as a number is of a decimal data typed (packed). If I pass a hex value as the number:

CALL CL_PGM('A' x'00012F')

It does not error, but it is not an easy way to call a program. Over the years many developers have made up their minds to only passed character values between programs so that they did not have to deal with this issue.

In IBM i 7.5 there is a solution, which I cannot find in the documentation for IBM i 7.4 TR6. The Call command, CALL, has been changed.

Before I go into examples of this change let me show you the source for my CL program. This is the same program I used above:

01  PGM PARM(&FIRST &SECOND)

02  DCL VAR(&FIRST) TYPE(*CHAR) LEN(1)
03  DCL VAR(&SECOND) TYPE(*DEC) LEN(5 0)

04  CHGVAR VAR(&FIRST) VALUE(&FIRST)
05  CHGVAR VAR(&SECOND) VALUE(&SECOND)

06  ENDPGM

Line 1: Two parameters are passed to this program.

Lines 2: The first parameter is character.

Line 3: The second is decimal.

Lines 4 and 5: If you do not use the passed parameter it will not error, if it has an invalid data type.

When I am in a partition with an older release and I prompt the Call command I am presented with the following:

                              Call Program (CALL)

 Type choices, press Enter.

 Program  . . . . . . . . . . . . > SOMETHING    Name
   Library  . . . . . . . . . . .     *LIBL       Name, *LIBL, *CURLIB
 Parameters:                                                                  
   Parameter  . . . . . . . . . .                                        
      
                + for more values                                        
      

I am sure you are familiar with this screen. I can enter the values of the parameters I want to pass to my program.

With IBM i 7.5 there are extra parameters:

                              Call Program (CALL)

 Type choices, press Enter.

 Program  . . . . . . . . . . . . > SOMETHING    Name
   Library  . . . . . . . . . . . >   *LIBL       Name, *LIBL, *CURLIB
 Parameters:                                                                  
   Parameter  . . . . . . . . . .                                         
      
   Type and length of parameter:
   Type . . . . . . . . . . . . .   *DFT          *DFT, *DEC, *CHAR, *LGL...
   Length . . . . . . . . . . . .                 Number
   Decimal positions  . . . . . .                 Number
                + for more values  

These allow me to enter the (data) type of the value, its length, and if it is numeric the number of decimal positions.

The allowed (data) types are:

Type Description Maximum
length
*DFT Old rules apply. Character or decimal. Char = 32 bytes
Dec = 15,5
*CHAR Character 32,767 bytes
*DEC Decimal 24,8
*INT Signed binary integer 8 bytes
*UINT Unsigned binary integer 8 bytes
*LGL Logical, only '0' or '1' 1
*FLT Binary floating point 8 bytes

These parameters are optional. If I do not use them then *DFT is assumed.

How would I use these new parameters to call my program?

CALL PGM(CL_PGM) PARM(('A' (*CHAR 1)) (12 (*DEC 5 0)))

As the first parameter is a single character I could just:

CALL PGM(CL_PGM) PARM(('A' (12 (*DEC 5 0)))

If I increase the length of the character, first, parameter the program does not error:

CALL PGM(CL_PGM) PARM(('A' (*CHAR 2)) (12 (*DEC 5 0)))

If I increase the size of the decimal, second, parameter it does error.

CALL PGM(CL_PGM) PARM(('A' (12 (*DEC 6 0)))

If I add a decimal position to the decimal position:

CALL PGM(CL_PGM) PARM(('A' (12 (*DEC 5 1)))

And I check the result in debug I get an expected result:

&SECOND = 00120.

I can also use this within one CL program to call another program:

01  PGM

02  CALL PGM(CL_PGM) PARM(('B' (*CHAR 1)) (100 (*DEC 5 0)))

03  ENDPGM

I am very pleased with this as I can now call CL programs from the command line when testing without fear of it erroring due to a decimal error.

 

You can learn more about the changes to the Call command from the IBM website here.

 

This article was written for IBM i 7.5 only.

8 comments:

  1. Sachin AbeywardenaJune 21, 2022 at 5:11 AM

    This is fantastic news.. still recalled the error which is a real pain in those days. Finally IBM settled this. Thanks for sharing Simon..

    ReplyDelete
  2. Looks good. We will socialise this when we go to 7.5. Thanks big heaps

    ReplyDelete
  3. How about SBMJOB?

    It used to have problems when submitting numeric values. Did tih change improved it?

    ReplyDelete
    Replies
    1. Work with the SBMJOB command:

      SBMJOB CMD(CALL PGM(EGA007CLC) PARM(('A' (*CHAR 1))(123 (*DEC 5 0)))) JOB(TEST)

      Delete
  4. If I add a decimal position to the decimal position:

    CALL PGM(CL_PGM) PARM(('A' (12 (*DEC 5 1)))
    And I check the result in debug I get an expected result:

    &SECOND = 00120.

    Who, in this case, i don’t get
    &SECOND = 0012.0 ?

    ReplyDelete
    Replies
    1. The decimal place is assumed, therefore, in a 5,1 variable 00120 is 12 with 0 decimal value.

      Delete
  5. Reynaldo Dandreb MedillaJune 23, 2022 at 8:52 PM

    thanks Simon, a little late for me but it's good IBM guys did it this time

    ReplyDelete
  6. I found a great use for this that has nothing to do with decimals. We have struggled for years with the problems related to a long CHAR entry parameter on a CL. Testing yesterday, I looked at the failed job log and saw the email address was garbled hex. I remembered this article and Bingo! It worked fine. Many thanks.

    CALL PGM(MYLIB/CLPGMC)
    PARM((EMAILADDRESS@SERVER.COM (*CHAR 50)))

    ReplyDelete

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.