WHY is it coming in null filled??!! It’s defined as 2000 characters in both programs.
It is irrelevant how it’s defined in either program. How is it defined when it’s sitting on a *JOBQ and therefore not inside any program? That is, how is it defined when it’s in a state outside of your programs?
That’s what happens to every submitted job. It doesn’t matter how long it takes; there is a time when it exists as nothing more than a message — a *RQS (request) message.
What is the definition of your parameter during the time that it has no definition?
Well, for a numeric value, it’s *DEC (15 5). For non-numeric, it’s *CHAR (32) by default, but will be longer out to as many non-blank positions go out to the right.
This is because a variable cannot be passed to a submitted job; only a value can be passed. A submitted job might sit on a *JOBQ for a fraction of a second or for an hour or for a week. If the *JOBQ is held, there’s no telling how long it will take. You signed off and went home — what happened to the variable definition when your interactive job ended? What difference does the called program make since it hasn’t started yet?
Because your parm is only a value and not a variable when you submit a job, the definition conforms to default definition rules. These rules haven’t changed in the past quarter century and more. See Passing parameters for one of the descriptions of defaults.
There are a couple valid ways to get around this issue.
First, SBMJOB has two possible parameters that are available to you — CMD() and RQSDTA(). Technically, when the command that you submit is a CALL command, you shouldn’t use the CMD() parameter. That parameter is intended to be used with commands that have typed parms. CALL has undefined parms. It was added to SBMJOB to facilitate prompting of defined commands.
If you must submit a CALL command, then you should use the RQSDTA() parameter. With RQSDTA(), you build the actual “request data” string. You string values together to create a *RQS message text. The resulting string should be capable of running directly on a command line. (A command line is nothing more than an interface to the request processor of your job.)
When you run a command through a command line, you can’t use variables; you must use values. Character variables that have trailing blanks and are longer than 32 characters must be enclosed in quotes and must have trailing blanks included inside the quotes. That’s exactly how they must be specified in the RQSDTA() parameter.
If the parm is 32 characters or less, it doesn’t matter because character values always get a minimum 32-byte area of memory reserved.
The other method is to define a *CMD object. One main purpose of a *CMD is to define data typing for your parameters. A *CMD is to CL what a procedure prototype is to RPG. The *CMD carries the variable definition inside of the *CMD definition.
In short, if you have values longer than 32 bytes that can have trailing blanks, you must use RQSDTA() or create a *CMD in order to pass the values as parameters for a submitted job.
Let’s say that your value in your current programming is “Abcdefg” and your variable is defined as *CHAR (2000). The first 32 bytes will contain “Abcdefg” plus 25 blanks. The called program will run in batch and try to access the next 1968 bytes of memory. Whatever was in that memory will be picked up; it will essentially be random. The memory itself will be memory that was allocated for the *JOBQ, not for your interactive program. (You might even suffer a machine-check error if it happens to be memory that is outside of the *JOBQ allocation.)
But if you build a string that includes the CALL command along with your value of 2000 bytes enclosed in quotes, and you pass the string through RQSDTA(), then the exact string will be stored on the *JOBQ. The actual trailing blanks that you passed in will cause the full 2000 bytes to be both allocated and initialized.
However, you’re currently using CMD(). That means that you aren’t supplying any quotes to mark the end of your value; you’re supplying a bare variable. The command analyzer that is inside the command-processing program of SBMJOB doesn’t have access to the variable definitions in your program. It builds a *RQS message that is based on the significant characters of your value.
You risk garbage in trailing blank positions.
Rather than passing a parm, if you don’t want the trouble of building a RQSDTA() string and you don’t want to define a *CMD, then place the value in a named data area or use the *LDA (Local Data Area). Be aware that the *LDA might unpredictably have a value already in it that’s used by some other programs elsewhere in your job. And a named data area might be referenced by jobs from two different users.
Other methods can be used, but they can have the same problems as data areas.
RQSDTA() and *CMDs are the two “correct” methods.