在运行i/OS 6.1的iSeries上,我有一个CL程序正在清理。在这个程序中有一堆剪切粘贴代码的形式:
IF COND(&ENV='PRD') THEN(DO)
CALL JCHKSTS PARM(&RS '127.0.0.1' '6500')
/* more junk here */
ENDDO
IF COND(&ENV='TST') THEN(DO)
CALL JCHKSTS PARM(&RS '127.0.0.1' '16500')
/* more junk here, same as in the first block */
ENDDO
/* repeat for several more &ENV values */
当我看到这一点时,我的第一个想法是,让我们将端口号移动到一个变量中,并消除所有重复的代码块,所以我最终得到了:
DCL &ENVPORT *CHAR(6)
IF COND(&ENV='PRD') THEN(CHGVAR VAR(&ENVPORT) VALUE('6500'))
IF COND(&ENV='TST') THEN(CHGVAR VAR(&ENVPORT) VALUE('16500'))
CALL JCHKSTS PARM(&RS '127.0.0.1' &ENVPORT)
/* more junk here, but only one copy of it now. */
当我运行这段代码时,它失败了,因为事实证明,JCHKSTS程序需要一个字符串作为它的第三个参数(它在内部将其转换为整数),并且&尽管ENVPORT变量被声明为字符串并用字符串值初始化,但它显然不是作为字符串传递的。(检查JCHKSTS中的参数显示端口值的MAXINT值。)
我通过将值从'6500'
更改为'6500 '
这一廉价的权宜之计来解决这个问题,但我不明白为什么它一开始就不起作用;IBM文档中写道:
如果调用是从CL程序或ILE CL过程进行的,则可以传递程序变量,在这种情况下,接收程序必须声明字段以匹配调用CL程序或FILE CL过程中定义的变量。
在我看来,接收程序需要一个字符串,我将变量声明为6个字符的字符串,它应该可以工作。
那么,我错过了什么吗?我应该如何声明变量,以便接收程序将其视为数字的字符串表示,而不是实际数字?
作为文字传递的字符变量的默认长度为32。我的猜测是JCHKSTS期望一个32字节的变量。尝试DCL &ENVPORT *CHAR 32
您的样本出现问题。
第一个DCL &ENVPORT *CHAR(6)
无效。
它应该是DCL &ENVPORT *CHAR 6
或完全DCL VAR(&ENVPORT) TYPE(*CHAR) LEN(6)
。
第二个JCHKSTS被调用一次,常数值为'6500'
,再次调用'16500'
,而您的解决方法是'6500 '
,它们的长度都不是6。
如果您设置了正确的字符串长度,它应该会像您期望的那样工作。
我在之前没有见过这种类型的声明
DCL &ENVPORT *CHAR(6)
我习惯于这样看:
DCL VAR(&ENVPORT) TYPE(*CHAR) LEN(6)
或者这样:
DCL &ENVPORT *CHAR LEN(6)
IBM参考