|
rpg400-l-request@xxxxxxxxxxxx wrote:
3. Parameters Stepping on each other (Fleming, Greg (ED)) This is weird. We have a CL submitting an RPG. When we debug, the parameters look fine in the CL, but they seem to be stepping on each other when we look at them in the RPG. Here's some code snippets: DCL VAR(&PUSERID10) TYPE(*CHAR) LEN(10) DCL VAR(&PASSWRD10) TYPE(*CHAR) LEN(10) DCL VAR(&PIPADDRS) TYPE(*CHAR) LEN(48) DCL VAR(&PFMDIR) TYPE(*CHAR) LEN(256) DCL VAR(&PTODIR) TYPE(*CHAR) LEN(256) DCL VAR(&PFILENAME) TYPE(*CHAR) LEN(50) DCL VAR(&PPRODTYPE) TYPE(*CHAR) LEN(1) SBMJOB CMD(CALL PGM(FF407AR) PARM(&PUSERID10 + &PASSWRD10 &PIPADDRS &PFMDIR &PTODIR + &PFILENAME &PPRODTYPE)) JOB(FTP_PC2PC) + JOBQ(QBATCH2) HOLD(*NO)
Greg: You're using SBMJOB with the CMD() parm where you should be using the RQSDTA() parm. Here's a test replacement for your FF407AR program: --------- Begin pgm ( + &PUSERID10 + &PASSWRD10 + &PIPADDRS + &PFMDIR + &PTODIR + &PFILENAME + &PPRODTYPE + ) DCL VAR( &PUSERID10 ) TYPE(*CHAR) LEN(10) DCL VAR( &PASSWRD10 ) TYPE(*CHAR) LEN(10) DCL VAR( &PIPADDRS ) TYPE(*CHAR) LEN(48) DCL VAR( &PFMDIR ) TYPE(*CHAR) LEN(256) DCL VAR( &PTODIR ) TYPE(*CHAR) LEN(256) DCL VAR( &PFILENAME ) TYPE(*CHAR) LEN(50) DCL VAR( &PPRODTYPE ) TYPE(*CHAR) LEN(1) dmpclpgm return endpgm --------- End All it does is take the parms and dump them so you can examine the values. The change to your code snippet looks like this: --------- Begin pgm DCL &PUSERID10 *CHAR 10 value( 'TomL' ) DCL &PASSWRD10 *CHAR 10 value( 'TomL' ) DCL &PIPADDRS *CHAR 48 + value( '1.2.3.4' ) DCL &PFMDIR *CHAR 256 + value( 'my/very/long/directory/name/greater/than/32/chars/long' ) DCL &PTODIR *CHAR 256 + value( 'my/second/very/long/directory/name/greater/than/32/chars/long' ) DCL &PFILENAME *CHAR 50 + value( 'my_very_long_file_name_50_chars_long_approximate' ) DCL &PPRODTYPE *CHAR 1 value( 'x' ) dcl &Q *char 1 value( '''' ) dcl &Q_Q *char 3 value( ''' ''' ) /* SBMJOB CMD(CALL PGM(FF407AR) PARM(&PUSERID10 + &PASSWRD10 &PIPADDRS &PFMDIR &PTODIR + &PFILENAME &PPRODTYPE)) JOB(FTP_PC2PC) + JOBQ(QBATCH2) HOLD(*NO) */ SBMJOB JOB( FTP_PC2PC ) JOBQ( QPGMR ) + RQSDTA( + 'call ff407ar (' *cat &Q *cat + &PUSERID10 *cat &Q_Q *cat + &PASSWRD10 *cat &Q_Q *cat + &PIPADDRS *cat &Q_Q *cat + &PFMDIR *cat &Q_Q *cat + &PTODIR *cat &Q_Q *cat + &PFILENAME *cat &Q_Q *cat + &PPRODTYPE *cat &Q *cat ')' + ) HOLD( *NO ) return endpgm --------- End I used QPGMR instead of QBATCH because that's easier here. I stuck a bunch of VALUE() clauses in so that you could see what values were involved. The basic deal is the same as it's been ever since the CMD() parm was first added to SBMJOB back in Version 1 of OS/400. The CMD() parm isn't what gets sent as the *RQS (Request) message to the job queue; the RQSDTA() parameter value is what gets sent. If you prompt SBMJOB and look at the default for RQSDTA(), you'll probably see "*CMD". That means that the program behind SBMJOB will use what you put in the CMD() parm to _generate_ the *RQS message. But early in that process, the CMD() value gets _formatted_ according to basic rules. Run your version of SBMJOB and look at the *RQS message in the submitted joblog and compare it to the *RQS message from my example. The difference after yours gets _formatted_ should be obvious. IBM supplied the CMD() parm to assist with a couple difficulties with RQSDTA(), but CMD() introduced difficulties of its own. The difficulties involve embedded quotes and numeric parms. CMD() makes passing numeric parms easy, but you _must_ use a variable declaration of *DEC (15 5) in the called program. You can use any numeric definition for RQSDTA(), but you _must_ build RQSDTA() as a character string. That means you do some fancier coding in the calling program, often so that you express the numeric value as hex digits. Also, _you_ are responsible for properly escaping any embedded quotes in your RQSDTA() string. Other than the &Q and &Q_Q variables, none of the VALUE() clauses I have here have any embedded quotes; so it doesn't matter. But if embedded quotes are possible, it can get ugly real fast. I used &Q and &Q_Q in order to help simplify the quotes that were necessary around the parm values in the RQSDTA() string. If any of the parms for FF407AR had embedded quotes, each of those would need to be escaped (doubled) by the program before concatenating it all together. All of that gets to why it can be easiest just to create a command definition and submit that in place of the CALL command. A *CMD object acts like a "prototype". It holds the definitions of your parm variables and handles the formatting for the eventual CALL of your program that happens when your command is executed in batch. The CALL command has default rules for formatting. By creating your own command, you get to control the formatting. Personally, I wonder if IBM did us a true favor by giving us CMD(). Had they not, the practice of creating commands would be much more advanced (IMO); and perhaps related elements such as UIM (for help text) would be advanced as well. Tom Liotta
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.