24
Tue, Dec
1 New Articles

Passing Parameters with the SBMJOB Command

CL
Typography
  • Smaller Small Medium Big Bigger
  • Default Helvetica Segoe Georgia Times

Brief: Parameter usage and programming go hand in hand. Yet, when it comes to submitting jobs to batch through the Submit Job (SBMJOB) command, parameters can cause you a lot of grief. This article will explain how OS/400 handles various parameter types and will illustrate several techniques to eliminate potential problems when parameters are passed through the SBMJOB command.

One of the greatest ironies I find in the OS/400 operating system is that the most common CL command to start programs-CALL-and the most common command to start a batch job-SBMJOB-do not work well together. I will show you how to avoid trouble when SBMJOB runs a CALL command.

The problem is that variables are passed as literals to the SBMJOB command through the CALL command. For clarification, I'll explain how CL programs handle parameters.

CALL and Literal Parameters

When a CL program calls another program, all parameters that are CL variables are passed to the called program exactly as they are defined in the calling program. Consider these fragments of code from a CL program.

 DCL &ACTION *CHAR 8 DCL &ACCOUNT_NO *DEC (5 0) ... CALL PGMB PARM(&ACTION &ACCOUNT_NO) 

PGMB will have no problem using the data passed to it if it defines entry parameters of the same type and length as the calling program. For instance, if PGMB is written in RPG, PGMB receives the parameters in the following way:

 *7890123456789012345678901234567890123456789012345 C *ENTRY PLIST C PARM ACTION 8 C PARM ACCTNO 50 

However, when a parameter is a literal, CL reformats it according to three rules.

1. A decimal literal is always formatted as a 15-digit number with five decimal places.

2. A character literal less than 32 bytes long is padded with blanks to a length of 32.

3. A character literal 32 bytes or longer is left as is.

For example, consider this code from a program we'll call PGMC.

 CALL PGM(PGMD) + PARM(500 GO + 'XYZ CORPORATION + AGED ACCOUNTS RECEIVABLE') 

PGMC passes a 15-digit, packed-decimal number with the value 0000000500.00000, a 32-character string with the value GO and 30 blanks, and a 40-character string with the value: 'XYZ CORPORATION AGED ACCOUNTS RECEIVABLE' PGMD should declare three parameters in a compatible manner:

 *7890123456789012345678901234567890123456789012345 C *ENTRY PLIST C PARM CUTOFF 155 C PARM ACTION 6 C PARM TITLE 40 

Although the CALL parameter passes the second parameter as 32 bytes, the called program can define the parameter as any length up to 32 bytes.

CALL does not actually pass the value of each parameter to the called program; it passes the memory address of each parameter. When a CL program calls another program, it furnishes the address of each parameter declared as a variable to the called program. But when the calling program finds a literal parameter, there is no CL variable whose address it can pass to the called program. Therefore, it makes a copy of the literal, reformatting its value according to the rules given above, and passes the address of the copy to the called program.

Using CALL and the SBMJOB Command

It's important to understand how CALL formats literal parameters before passing their addresses to another program, because that's how CALL formats all parameters, variable and literal, when it's used in the CMD parameter of the SBMJOB command. (All examples in this article will use the CMD parameter, but the same principles apply to the RQSDTA parameter.)

Here's the program fragment we saw earlier, except that now the program submits a job to batch, instead of directly calling program PGMB.

 DCL &ACTION *CHAR 8 DCL &ACCOUNT_NO *DEC (5 0) ... SBMJOB CMD(CALL PGMB PARM(&ACTION &ACCOUNT_NO)) ... 

When PGMB begins execution, it will receive the addresses of a 32-byte action code and a 15-digit account number with five decimal places, even though this is not the way the submitting program defined them.

Because the command sent to a submitted job is really a request message, the submitted job will interpret the request message the same way an interactive job interprets a command typed on a command line: it will not access the submitting CL program's variables.

Now you understand why SBMJOB and CALL do not cooperate with respect to passing parameters.

The fact that the system pads short character parameters to a length of 32 will never cause you a problem. Passing a character literal longer than 32 bytes causes problems only if it is passed as a literal with a length less than the length defined in the called program. The real problem is with decimal data.

There are methods to work around decimal data problems. I'd like to present five common ones to you.

Method 1: Declare Numeric Parameters In CALL Format

Surrender to CALL's demands and declare decimal parameters in the called program as 15 digits with five decimal positions to the left of the decimal point. This is the "if you can't beat 'em, join 'em" philosophy.

This method works unless you pass a decimal value with more than 10 positions to the left of the decimal point, or a decimal value with more than five decimal positions to the right.

The worst thing about this method is that it puts the caller, rather than the called program, in the driver's seat and thus violates a basic programming rule. Each module, whether it's a program or a subroutine within a program, should define what data it needs to do its job. Modules should pass data according to the called module's definition.

Method 2: Convert numeric values to character data

Place the value of a decimal number into a character variable, which is passed to the called program. The called program must receive all parameters as character data.

Let's look at the previous example using this method.

 DCL &ACTION *CHAR 8 DCL &ACCOUNT_NO *DEC (5 0) DCL &ACCOUNT_X *CHAR 5 ... CHGVAR VAR(&ACCOUNT_X) VALUE(&ACCOUNT_NO) SBMJOB CMD(CALL PGM(PGMB) PARM(&ACTION + &ACCOUNT_X))... 

At the time the SBMJOB command is executed, the variables would have these values:

 &ACCOUNT_NO 19232 (X'19232F') &ACCOUNT_X 19232 (X'F1F9F2F3F2') 

The called program, PGMB, must receive the account number as character data or zoned-decimal data. If it receives the account number as character data, it must move the parameter to a numeric field.

 *7890123456789012345678901234567890123456789012345 C *ENTRY PLIST C PARM ACTION 8 C PARM ACCTXX 5 C MOVE ACCTXX ACCTNO 50 

This commonly used method works well, except with negative numbers and numbers with decimal positions. When copying a decimal value to a character variable, the CL CHGVAR command can store a decimal point and/or a leading minus sign. Let's say we want to pass a seven digit number with two decimal positions through a character variable.

 DCL &GROSS_AMT *DEC (7 2) DCL &ALPHA_AMT *CHAR 9 ... CHGVAR VAR(&ALPHA_AMT) VALUE(&GROSS_AMT) SBMJOB CMD(CALL PGMF PARM(&ALPHA_AMT)) ... 

If the called program is written in CL, this works well. CHGVAR will de-edit &AMOUNT_P-which surely contains a decimal point and may contain a leading minus sign-and copy the correct value to &GROSS.

 PGM PARM(&AMOUNT_P) DCL &AMOUNT_P *CHAR 9 DCL &GROSS *DEC (7 2) CHGVAR VAR(&GROSS) VALUE(&AMOUNT_P) ... 

It is more difficult if the called program (PGMF) is written in RPG, which has no de-editing features.

As with the first method, the caller, not the called program, determines the format of the passed data. This method is not suitable if you prefer that numbers be passed as numbers as opposed to edited numeric data stored in character variables.

Method 3: Pass data through another object

Use some other object, such as a data area, data queue, user space, or file, to pass the data. Anyone who has spent time programming the S/34 or S/36 will be very familiar with this approach, since programming these systems requires heavy use of the local data area.

Using this method, you avoid problems of decimal parameters and character parameters greater than 32 bytes. In addition, more data can be passed to the called program than with the previous two methods.

Disadvantages of this method are that another object is required (using parameters requires no additional objects); more code may be required to store and receive the data (e.g., a call to SNDDTAQ or to the user space APIs); and programs may compete for the same resources (e.g., the same data area or the same positions of the local data area).

Method 4: Passing hexadecimal literals

To pass a numeric constant in any format other than a length of 15 and a precision of 5, code the constant in hexadecimal format. The following CALL command shows how to pass the value 15.7 to a program variable that is declared as LEN(5 2):

CALL PGM(PGMB) PARM(GO X'01570F')

This special format is actually how the AS/400 represents a packed decimal value. It requires appending a sign character-F for a positive value and D for negative value-to the end of the character string, and the number of characters must always be even. This is not a method for carrying out production work, but it is a good way to test a program from a command line.

It is possible to use this method to pass decimal values through the parameters of a CALL command executed by SBMJOB. It requires a program that will copy a decimal value to a character variable from left to right, one byte at a time, until it finds a byte with a digit of D or F. The character variable is used as the parameter in place of the decimal variable.

I'll leave this as an exercise for the interested reader. Using this technique can get you into trouble, so I do not recommend it for production work. Let's move along to another method of solving our problem.

Method 5: Define a command

Submit a command that you write yourself, rather than submitting a CALL. PGMB's entry parameter list looks like this:

 *7890123456789012345678901234567890123456789012345 C *ENTRY PLIST C PARM ACTION 8 C PARM ACCTNO 50 

1 illustrates the command source I'll call CMDB for a command to execute PGMB.

Figure 1 illustrates the command source I'll call CMDB for a command to execute PGMB.

Here's how the command would be used by SBMJOB.

 DCL &ACCOUNT_NO *DEC (5 0) DCL &ACTION *CHAR 8 ... SBMJOB CMD(CMDB ACTION(&ACTION) ACCOUNT(&ACCOUNT_NO)... 

The beauty of this approach is that CMDB, unlike CALL, knows what format the submitted program uses for each parameter and automatically reformats the data accordingly. No matter how the data is defined in the submitting job, the command processor will reformat it according to the command definition. This completely eliminates the conflict inherent in the use of CALL in SBMJOB commands.

Other advantages are:

o You don't have to pass any parameter for which you've defined a default value in the command source.

o All the power of the command processor, such as validity checking, is available to you.

o The format of a parameter does not have to be the same in the submitting program and the called program.

o You can change the size of a parameter in the command and the called program

Now, let's take a look at a technique that will allow you to prompt the user for information prior to submitting a command to batch through the SBMJOB command.

Prompt-and-Submit Jobs

Using your own commands can help with a common task-prompting for information before submitting a job to run in batch. 2 contains the source for a command I'll call CMDA. 3 illustrates its command processing program, PGMA.

Using your own commands can help with a common task-prompting for information before submitting a job to run in batch. Figure 2 contains the source for a command I'll call CMDA. Figure 3 illustrates its command processing program, PGMA.

PGMA's first task is to determine whether it is running in an interactive job or in a batch job. If PGMA is running interactively (&JOBTYPE = '1') it submits itself to batch by submitting CMDA. The interactive invocation of PGMA ends and a batch job running PGMA begins.

PGMA runs PGMB, and has no parameter conflicts because the CALL is issued within a program, not as part of SBMJOB.

There is no mechanism in this CL program to prompt the user to enter an action code and account number, because OS/400 has a way to handle that sort of thing. You're already familiar with this method if you've ever typed a command and pressed the F4 key.

To run this job, a user could type CMDA at a command line and press the F4 key, but a better way is to assign the following command to a menu option.

? CMDA ?-SBMTOJOBQ(Y)

The leading question mark, like the F4 key, causes OS/400 to prompt for command parameters. The "?-" combination doesn't let the user see or modify the SBMTOJOBQ parameter, forcing the job to submit to batch. Of course, you, the programmer, may want to run the job interactively for testing or debugging. SBMTOJOBQ gives you a way to do that.

You could allow different capabilities to different users by giving the users distinct versions of the command on their menus. 4 shows some sample command prompting for three fictitious users. Bob can use any action code, but Sally and Leroy are each limited to only one action. All users can choose an account number; none are allowed to run the job interactively.

You could allow different capabilities to different users by giving the users distinct versions of the command on their menus. Figure 4 shows some sample command prompting for three fictitious users. Bob can use any action code, but Sally and Leroy are each limited to only one action. All users can choose an account number; none are allowed to run the job interactively.

Writing your own command not only solves the problem of passing parameters, but also relieves you of the chore of prompting for parameter values.

The Verdict, Please

All five of these methods have their merits. A good programmer should understand all of them and use each one when it is appropriate. I would encourage you to not use method 1 or method 4 for production work. Method 1 is too limited, and method 4 is too risky.

It's easier to continue to use CALL when the submitted program has no parameters or has only character parameters 32 bytes or less in length. My favorite by far is the fifth one-submitting my own commands rather than CALLs. It is the only one that consistently allows straightforward submission of jobs to batch without undesirable side effects. If you are in the habit of starting all your programs with CALL, let me encourage you to begin to write your own commands.

Ted Holt is an associate technical editor for Midrange Computing.


Passing Parameters with the SBMJOB Command

Figure 1 User-written Command for Command Processing

 Program PGMB CMD PROMPT('Print report by account number') PARM KWD(ACTION) TYPE(*CHAR) LEN(8) RSTD(*YES) + DFT(GO) VALUES(GO REPRINT REBUILD CLOSE) + EXPR(*YES) PROMPT('Action') PARM KWD(ACCOUNT) TYPE(*DEC) LEN(5 0) MIN(1) + PROMPT('Account number') 
Passing Parameters with the SBMJOB Command

Figure 2 User-written Command with Job Queue Option

 CMD PROMPT('Print report by account number') PARM KWD(ACTION) TYPE(*CHAR) LEN(8) RSTD(*YES) + DFT(GO) VALUES(GO REPRINT REBUILD CLOSE) + EXPR(*YES) PROMPT('Action') PARM KWD(ACCOUNT) TYPE(*DEC) LEN(5 0) MIN(1) + PROMPT('Account number') PARM KWD(SBMTOJOBQ) TYPE(*CHAR) LEN(1) RSTD(*YES) + DFT(Y) VALUES(Y N) PROMPT('Submit to job + queue?') 
Passing Parameters with the SBMJOB Command

Figure 3 Command Processing Program PGMA for

 Command CMDA PGM PARM(&ACTION &ACCOUNT_NO &SBMTOJOBQ) DCL VAR(&ACCOUNT_NO) TYPE(*DEC) LEN(5 0) DCL VAR(&ACTION) TYPE(*CHAR) LEN(8) DCL VAR(&JOBTYPE) TYPE(*CHAR) LEN(1) DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) DCL VAR(&SBMTOJOBQ) TYPE(*CHAR) LEN(1) RTVJOBA TYPE(&JOBTYPE) IF COND(&JOBTYPE *EQ '1' *AND &SBMTOJOBQ *NE + 'N') THEN(DO) SBMJOB CMD(CMDA ACTION(&ACTION) + ACCOUNT(&ACCOUNT_NO)) JOB(MYJOB) GOTO CMDLBL(FWDMSG) ENDDO CALL PGM(PGMB) PARM(&ACTION &ACCOUNT_NO) RETURN FWDMSG: RCVMSG MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + SNDMSGFLIB(&MSGFLIB) IF COND(&MSGID *NE ' ') THEN(DO) SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + MSGDTA(&MSGDTA) MONMSG MSGID(CPF2469) GOTO CMDLBL(FWDMSG) ENDDO ENDPGM 
Passing Parameters with the SBMJOB Command

Figure 4 Sample User Prompting

 User Command Bob ?CMDA ?-SBMTOJOBQ(Y) Sally ?CMDA ?-ACTION(REBUILD) ?-SBMTOJOBQ(Y) Leroy ?CMDA ?-ACTION(CLOSE) ?-SBMTOJOBQ(Y) 
BLOG COMMENTS POWERED BY DISQUS

LATEST COMMENTS

Support MC Press Online

$

Book Reviews

Resource Center

  • SB Profound WC 5536 Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application. You can find Part 1 here. In Part 2 of our free Node.js Webinar Series, Brian May teaches you the different tooling options available for writing code, debugging, and using Git for version control. Brian will briefly discuss the different tools available, and demonstrate his preferred setup for Node development on IBM i or any platform. Attend this webinar to learn:

  • SB Profound WP 5539More than ever, there is a demand for IT to deliver innovation. Your IBM i has been an essential part of your business operations for years. However, your organization may struggle to maintain the current system and implement new projects. The thousands of customers we've worked with and surveyed state that expectations regarding the digital footprint and vision of the company are not aligned with the current IT environment.

  • SB HelpSystems ROBOT Generic IBM announced the E1080 servers using the latest Power10 processor in September 2021. The most powerful processor from IBM to date, Power10 is designed to handle the demands of doing business in today’s high-tech atmosphere, including running cloud applications, supporting big data, and managing AI workloads. But what does Power10 mean for your data center? In this recorded webinar, IBMers Dan Sundt and Dylan Boday join IBM Power Champion Tom Huntington for a discussion on why Power10 technology is the right strategic investment if you run IBM i, AIX, or Linux. In this action-packed hour, Tom will share trends from the IBM i and AIX user communities while Dan and Dylan dive into the tech specs for key hardware, including:

  • Magic MarkTRY the one package that solves all your document design and printing challenges on all your platforms. Produce bar code labels, electronic forms, ad hoc reports, and RFID tags – without programming! MarkMagic is the only document design and print solution that combines report writing, WYSIWYG label and forms design, and conditional printing in one integrated product. Make sure your data survives when catastrophe hits. Request your trial now!  Request Now.

  • SB HelpSystems ROBOT GenericForms of ransomware has been around for over 30 years, and with more and more organizations suffering attacks each year, it continues to endure. What has made ransomware such a durable threat and what is the best way to combat it? In order to prevent ransomware, organizations must first understand how it works.

  • SB HelpSystems ROBOT GenericIT security is a top priority for businesses around the world, but most IBM i pros don’t know where to begin—and most cybersecurity experts don’t know IBM i. In this session, Robin Tatam explores the business impact of lax IBM i security, the top vulnerabilities putting IBM i at risk, and the steps you can take to protect your organization. If you’re looking to avoid unexpected downtime or corrupted data, you don’t want to miss this session.

  • SB HelpSystems ROBOT GenericCan you trust all of your users all of the time? A typical end user receives 16 malicious emails each month, but only 17 percent of these phishing campaigns are reported to IT. Once an attack is underway, most organizations won’t discover the breach until six months later. A staggering amount of damage can occur in that time. Despite these risks, 93 percent of organizations are leaving their IBM i systems vulnerable to cybercrime. In this on-demand webinar, IBM i security experts Robin Tatam and Sandi Moore will reveal:

  • FORTRA Disaster protection is vital to every business. Yet, it often consists of patched together procedures that are prone to error. From automatic backups to data encryption to media management, Robot automates the routine (yet often complex) tasks of iSeries backup and recovery, saving you time and money and making the process safer and more reliable. Automate your backups with the Robot Backup and Recovery Solution. Key features include:

  • FORTRAManaging messages on your IBM i can be more than a full-time job if you have to do it manually. Messages need a response and resources must be monitored—often over multiple systems and across platforms. How can you be sure you won’t miss important system events? Automate your message center with the Robot Message Management Solution. Key features include:

  • FORTRAThe thought of printing, distributing, and storing iSeries reports manually may reduce you to tears. Paper and labor costs associated with report generation can spiral out of control. Mountains of paper threaten to swamp your files. Robot automates report bursting, distribution, bundling, and archiving, and offers secure, selective online report viewing. Manage your reports with the Robot Report Management Solution. Key features include:

  • FORTRAFor over 30 years, Robot has been a leader in systems management for IBM i. With batch job creation and scheduling at its core, the Robot Job Scheduling Solution reduces the opportunity for human error and helps you maintain service levels, automating even the biggest, most complex runbooks. Manage your job schedule with the Robot Job Scheduling Solution. Key features include:

  • LANSA Business users want new applications now. Market and regulatory pressures require faster application updates and delivery into production. Your IBM i developers may be approaching retirement, and you see no sure way to fill their positions with experienced developers. In addition, you may be caught between maintaining your existing applications and the uncertainty of moving to something new.

  • LANSAWhen it comes to creating your business applications, there are hundreds of coding platforms and programming languages to choose from. These options range from very complex traditional programming languages to Low-Code platforms where sometimes no traditional coding experience is needed. Download our whitepaper, The Power of Writing Code in a Low-Code Solution, and:

  • LANSASupply Chain is becoming increasingly complex and unpredictable. From raw materials for manufacturing to food supply chains, the journey from source to production to delivery to consumers is marred with inefficiencies, manual processes, shortages, recalls, counterfeits, and scandals. In this webinar, we discuss how:

  • The MC Resource Centers bring you the widest selection of white papers, trial software, and on-demand webcasts for you to choose from. >> Review the list of White Papers, Trial Software or On-Demand Webcast at the MC Press Resource Center. >> Add the items to yru Cart and complet he checkout process and submit

  • Profound Logic Have you been wondering about Node.js? Our free Node.js Webinar Series takes you from total beginner to creating a fully-functional IBM i Node.js business application.

  • SB Profound WC 5536Join us for this hour-long webcast that will explore:

  • Fortra IT managers hoping to find new IBM i talent are discovering that the pool of experienced RPG programmers and operators or administrators with intimate knowledge of the operating system and the applications that run on it is small. This begs the question: How will you manage the platform that supports such a big part of your business? This guide offers strategies and software suggestions to help you plan IT staffing and resources and smooth the transition after your AS/400 talent retires. Read on to learn: