📜  JCL-条件处理

📅  最后修改于: 2020-11-22 17:05:22             🧑  作者: Mango


作业录入系统使用两种方法在JCL中执行条件处理。作业完成后,将根据执行状态设置返回码。返回码可以是0(成功执行)到4095(非零表示错误情况)之间的数字。最常见的常规值为:

  • 0 =正常-一切正常

  • 4 =警告-小错误或问题。

  • 8 =错误-重大错误或问题。

  • 12 =严重错误-重大错误或问题,结果不可信。

  • 16 =终端错误-非常严重的问题,请勿使用结果。

可以使用COND参数和IF-THEN-ELSE构造基于上一步的返回代码来控制作业步骤的执行,这已在本教程中进行了说明。

COND参数

可以在JCL的JOB或EXEC语句中编码COND参数。这是对先前作业步骤的返回码的测试。如果测试评估为真,则绕过当前作业步骤执行。绕过只是作业步骤的遗漏,并非异常终止。单个测试中最多可以组合八个条件。

句法

以下是JCL COND参数的基本语法:

COND=(rc,logical-operator)
or
COND=(rc,logical-operator,stepname)
or
COND=EVEN
or 
COND=ONLY

这是所用参数的描述:

  • rc :这是返回码

  • 逻辑运算符:可以是GT(大于),GE(大于或等于),EQ(等于),LT(小于),LE(小于或等于)或NE(不等于)。

  • stepname :这是作业步骤,其返回代码在测试中使用。

最后两个条件(a)COND = Even和(b)COND = ONLY,已在本教程下面进行了说明。

可以在JOB语句或EXEC语句中编码COND,在两种情况下,其行为都不同,如下所述:

作业内的COND语句

当在JOB语句中编码COND时,将针对每个作业步骤测试条件。当条件在任何特定的工作步骤中为真时,它将随其后的工作步骤一起绕开。以下是一个示例:

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID,COND=(5,LE)
//*
//STEP10 EXEC PGM=FIRSTP  
//* STEP10 executes without any test being performed.

//STEP20 EXEC PGM=SECONDP 
//* STEP20 is bypassed, if RC of STEP10 is 5 or above. 
//* Say STEP10 ends with RC4 and hence test is false. 
//* So STEP20 executes and lets say it ends with RC16.

//STEP30 EXEC PGM=SORT
//* STEP30 is bypassed since 5 <= 16.

EXEC语句中的COND

如果在作业步骤的EXEC语句中对COND进行了编码,并发现其为true,则仅绕过该作业步骤,并从下一个作业步骤继续执行。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(0,EQ,STP01)
//* In STP02, condition evaluates to TRUE and step bypassed.

//STP03 EXEC PGM=IEBGENER,COND=((10,LT,STP01),(10,GT,STP02))
//* In STP03, first condition fails and hence STP03 executes. 
//* Since STP02 is bypassed, the condition (10,GT,STP02) in 
//* STP03 is not tested.

COND =偶数

编码COND = EVEN时,即使先前的任何步骤异常终止,也将执行当前作业步骤。如果将任何其他RC条件与COND = EVEN一起编码,则如果所有RC条件都不为真,则执行作业步骤。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(0,EQ,STP01)
//* In STP02, condition evaluates to TRUE and step bypassed.

//STP03 EXEC PGM=IEBGENER,COND=((10,LT,STP01),EVEN)
//* In STP03, condition (10,LT,STP01) evaluates to true,
//* hence the step is bypassed.

COND =仅

当编码COND = ONLY时,仅当任何先前的步骤异常终止时,才执行当前作业步骤。如果将任何其他RC条件与COND = ONLY一起编码,则如果所有RC条件都不为真且先前的任何作业步骤异常失败,则执行作业步骤。

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01 EXEC PGM=SORT
//* Assuming STP01 ends with RC0.

//STP02 EXEC PGM=MYCOBB,COND=(4,EQ,STP01)
//* In STP02, condition evaluates to FALSE, step is executed 
//* and assume the step abends.

//STP03 EXEC PGM=IEBGENER,COND=((0,EQ,STP01),ONLY)
//* In STP03, though the STP02 abends, the condition 
//* (0,EQ,STP01) is met. Hence STP03 is bypassed.

IF-THEN-ELSE构造

控制作业处理的另一种方法是使用IF-THEN-ELSE构造。这提供了更多的灵活性和用户友好的条件处理方式。

句法

以下是JCL IF-THEN-ELSE构造的基本语法:

//name IF condition THEN
list of statements //* action to be taken when condition is true
//name ELSE 
list of statements //* action to be taken when condition is false
//name ENDIF

以下是上述IF-THEN-ELSE构造中使用的术语的描述:

  • name :这是可选的,名称可以包含1到8个字母数字字符,以字母,#,$或@开头。

  • 条件:条件的格式为:关键字运算符VALUE ,其中关键字可以是RC(返回码),ABENDCC(系统或用户完成代码),ABEND,RUN(开始逐步执行)。运算符可以是逻辑运算符(AND(&),OR(|))或关系运算符(,> =,<>)。

以下是显示IF-THEN-ELSE用法的简单示例:

//CNDSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//PRC1   PROC
//PST1       EXEC PGM=SORT
//PST2       EXEC PGM=IEBGENER
//       PEND
//STP01  EXEC PGM=SORT 
//IF1    IF STP01.RC = 0 THEN
//STP02     EXEC PGM=MYCOBB1,PARM=123
//       ENDIF
//IF2    IF STP01.RUN THEN
//STP03a    EXEC PGM=IEBGENER
//STP03b    EXEC PGM=SORT
//       ENDIF
//IF3    IF STP03b.!ABEND THEN
//STP04     EXEC PGM=MYCOBB1,PARM=456
//       ELSE
//       ENDIF
//IF4    IF (STP01.RC = 0 & STP02.RC <= 4) THEN
//STP05     EXEC PROC=PRC1
//       ENDIF
//IF5    IF STP05.PRC1.PST1.ABEND THEN
//STP06     EXEC PGM=MYABD
//       ELSE
//STP07     EXEC PGM=SORT
//       ENDIF

让我们尝试研究以上程序以更详细地了解它:

  • STP01的返回码在IF1中进行了测试。如果为0,则执行STP02。否则,处理转到下一个IF语句(IF2)。

  • 在IF2中,如果STP01已开始执行,则将执行STP03a和STP03b。

  • 在IF3中,如果STP03b不存在,则执行STP04。在ELSE中,没有语句。它称为NULL ELSE语句。

  • 在IF4中,如果STP01.RC = 0且STP02.RC <= 4为TRUE,则执行STP05。

  • 在IF5中,如果作业步骤STP05中的PROC PRC1中的过程步骤PST1终止,则执行STP06。否则执行STP07。

  • 如果IF4评估为false,则不执行STP05。在那种情况下,不测试IF5,并且不执行步骤STP06,STP07。

如果作业异常终止(例如用户取消作业,作业时间到期或数据集向后引用到绕过的步骤),则不会执行IF-THEN-ELSE。

设置检查点

您可以使用DD语句SYSCKEOV在JCL程序中设置检查点数据集。

CHKPT是在DD语句中为多卷QSAM数据集编码的参数。当CHKPT编码为CHKPT = EOV时,在输入/输出多卷数据集的每个卷的末尾,将检查点写入SYSCKEOV语句中指定的数据集。

//CHKSAMP JOB CLASS=6,NOTIFY=&SYSUID
//*
//STP01     EXEC PGM=MYCOBB
//SYSCKEOV  DD DSNAME=SAMPLE.CHK,DISP=MOD
//IN1       DD DSN=SAMPLE.IN,DISP=SHR
//OUT1      DD DSN=SAMPLE.OUT,DISP=(,CATLG,CATLG)
//          CHKPT=EOV,LRECL=80,RECFM=FB    

在上面的示例中,在输出数据集SAMPLE.OUT的每个卷的末尾将检查点写入数据集SAMPLE.CHK中。

重新开始处理

您可以使用RD参数以自动方式重新启动以太币处理,或者使用RESTART参数以手动方式重新开始以太币处理。

RD参数在JOB或EXEC语句中编码,它有助于自动JOB / STEP重新启动,并且可以保存以下四个值之一:R,RNC,NR或NC。

  • RD = R允许自动重新启动,并考虑在DD语句的CHKPT参数中编码的检查点。

  • RD = RNC允许自动重新启动,但是覆盖(忽略)CHKPT参数。

  • RD = NR指定不能自动重新启动作业/步骤。但是,当使用RESTART参数手动重新启动它时,将考虑CHKPT参数(如果有)。

  • RD = NC不允许自动重启和检查点处理。

如果仅要求对特定的异常结束代码执行自动重启,那么可以在IBM系统parmlib库的SCHEDxx成员中指定它。

RESTART参数编码在JOB或EXEC语句中,它有助于在作业失败后手动重新启动JOB / STEP。 RESTART可以附带一个checkid,它是在SYSCKEOV DD语句中编码的数据集中编写的检查点。当对一个checkid进行编码时,应该对SYSCHK DD语句进行编码,以在JOBLIB语句(如果有)之后引用该检查点数据集,否则在JOB语句之后。

//CHKSAMP JOB CLASS=6,NOTIFY=&SYSUID,RESTART=(STP01,chk5)
//*
//SYSCHK    DD DSN=SAMPLE.CHK,DISP=OLD
//STP01     EXEC PGM=MYCOBB
//*SYSCKEOV    DD DSNAME=SAMPLE.CHK,DISP=MOD
//IN1       DD DSN=SAMPLE.IN,DISP=SHR
//OUT1      DD DSN=SAMPLE.OUT,DISP=(,CATLG,CATLG)
//          CHKPT=EOV,LRECL=80,RECFM=FB    

在上面的示例中,chk5是checkid,即STP01在checkpoint5重新启动。请注意,在“设置检查点”部分中说明的上一个程序中添加了SYSCHK语句,并注释了SYSCKEOV语句。