JCL - 条件处理

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

  • 0 =正常 - 一切正常

  • 4 =警告 - 轻微错误或问题.

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

  • 12 =严重错误 - 重大错误或问题,结果不值得信任.

  • 16 =终端错误 - 非常严重的问题,不要使用结果.

可以根据上一步的返回代码控制作业步骤执行(s)使用 COND 参数和 IF-THEN-ELSE 结构,本教程已对此进行了解释.

COND参数

可以在JCL的JOB或EXEC语句中对 COND 参数进行编码.它是对前面作业步骤的返回码的测试.如果评估测试为真,则绕过当前作业步骤执行.绕过只是省略了工作步骤而不是异常终止.单个测试中最多可以组合8个条件.

语法

以下是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(不等于).

  • 步骤名称:这是其返回代码用于的作业步骤测试.

最后两个条件(a)COND = EVEN和(b)COND = ONLY,本教程下面已经解释过.

COND可以在JOB语句或EXEC语句中编码,在这两种情况下,它都表现出来不同如下所述:

JOB语句中的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时一个工作步骤被发现是真的,只有那个工作步骤被绕过,并且从下一个工作步骤继续执行.

//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 = EVEN

当编码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 = ONLY

当编码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个以字母,#,$或@开头的字母数字字符.

  • 条件 :条件将具有以下格式: KEYWORD OPERATOR VALUE ,其中 KEYWORDS 可以是RC(返回代码),ABENDCC(系统或用户完成代码),ABEND,RUN(步骤开始执行). OPERATOR 可以是逻辑运算符(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


让我们试着看一下上面的程序,以便更详细地理解它:

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

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

  • 在IF3中,如果STP03b没有ABEND,则执行STP04.在ELSE中,没有任何陈述.它被称为NULL ELSE语句.

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

  • 在IF5中,如果PROC PRC1中的proc-step PST1在jobstep STP05 ABEND中,则执行STP06.执行其他STP07.

  • 如果IF4的计算结果为false,则不执行STP05.在这种情况下,IF5未经过测试,STP06,STP07也未执行.

IF-THEN-ELSE不会在作业异常终止的情况下执行,例如用户取消作业,作业时间到期或数据集向后参考被绕过的步骤.

设置检查点

您可以使用 SYSCKEOV,这是一个DD语句在JCL程序中设置检查点数据集.

A 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.CHK的末尾.输出数据集的体积SAMPLE.OUT.

重新启动处理

您可以使用 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,即在checkpoint5重新启动STP01.请注意,在设置检查点部分中解释的先前程序中添加了SYSCHK语句并注释掉了SYSCKEOV语句.