JCL: procesamiento condicional

Job Entry System utiliza dos enfoques para realizar el procesamiento condicional en un JCL. Cuando se completa un trabajo, se establece un código de retorno según el estado de ejecución. El código de retorno puede ser un número entre 0 (ejecución exitosa) y 4095 (un valor distinto de cero muestra una condición de error). Los valores convencionales más comunes son:

  • 0 = Normal - todo correcto

  • 4 = Advertencia: errores o problemas menores.

  • 8 = Error: errores o problemas importantes.

  • 12 = Error grave: errores o problemas importantes; no se debe confiar en los resultados.

  • 16 = Error de terminal - problemas muy serios, no use los resultados.

La ejecución de un paso de trabajo se puede controlar en función del código de retorno de los pasos anteriores mediante el COND parámetro y IF-THEN-ELSE constructo, que se ha explicado en este tutorial.

Parámetro COND

UN CONDEl parámetro se puede codificar en la sentencia JOB o EXEC de JCL. Es una prueba del código de retorno de los pasos de trabajo anteriores. Si la prueba se evalúa como verdadera, se omite la ejecución del paso del trabajo actual. Eludir es solo una omisión del paso del trabajo y no una terminación anormal. Puede haber como máximo ocho condiciones combinadas en una sola prueba.

Sintaxis

A continuación se muestra la sintaxis básica de un parámetro COND JCL:

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

Aquí está la descripción de los parámetros utilizados:

  • rc : Este es el código de retorno

  • logical-operator : Puede ser GT (mayor que), GE (mayor que o igual a), EQ (igual a), LT (menor que), LE (menor que o igual a) o NE (no igual a).

  • stepname : Este es el paso del trabajo cuyo código de retorno se usa en la prueba.

Las últimas dos condiciones (a) COND = PAR y (b) COND = ONLY, se han explicado a continuación en este tutorial.

El COND se puede codificar dentro de la instrucción JOB o EXEC, y en ambos casos, se comporta de manera diferente como se explica a continuación:

COND dentro de la declaración JOB

Cuando se codifica COND en la instrucción JOB, la condición se prueba para cada paso del trabajo. Cuando la condición es verdadera en cualquier paso del trabajo en particular, se omite junto con los pasos del trabajo que le siguen. A continuación se muestra un ejemplo:

//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.

COND dentro de la declaración EXEC

Cuando se codifica COND en la declaración EXEC de un paso de trabajo y se determina que es verdadero, solo se omite ese paso de trabajo y la ejecución continúa desde el siguiente paso de trabajo.

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

Cuando se codifica COND = EVEN, se ejecuta el paso del trabajo actual, incluso si alguno de los pasos anteriores termina de forma anormal. Si se codifica cualquier otra condición RC junto con COND = EVEN, entonces el paso de trabajo se ejecuta si ninguna de las condiciones RC es verdadera.

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

Cuando se codifica COND = ONLY, se ejecuta el paso del trabajo actual, solo cuando cualquiera de los pasos anteriores termina de forma anormal. Si se codifica cualquier otra condición RC junto con COND = ONLY, entonces el paso de trabajo se ejecuta si ninguna de las condiciones RC es verdadera y cualquiera de los pasos de trabajo anteriores falla anormalmente.

//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.

Construcción IF-THEN-ELSE

Otro enfoque para controlar el procesamiento del trabajo es mediante el uso de construcciones IF-THEN-ELSE. Esto brinda más flexibilidad y una forma fácil de usar de procesamiento condicional.

Sintaxis

A continuación se muestra la sintaxis básica de una construcción 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

A continuación se muestra la descripción de los términos utilizados en la construcción IF-THEN-ELSE anterior:

  • name : Esto es opcional y un nombre puede tener de 1 a 8 caracteres alfanuméricos comenzando con el alfabeto, #, $ o @.

  • Condition : Una condición tendrá un formato: KEYWORD OPERATOR VALUE, dónde KEYWORDSpuede ser RC (Código de retorno), ABENDCC (Código de finalización del sistema o del usuario), ABEND, RUN (paso iniciado en ejecución). UnOPERATOR puede ser un operador lógico (Y (&), O (|)) o un operador relacional (<, <=,>,> =, <>).

Ejemplo

A continuación, se muestra un ejemplo simple que muestra el uso de 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

Intentemos mirar el programa anterior para entenderlo con más detalle:

  • El código de retorno de STP01 se prueba en IF1. Si es 0, entonces se ejecuta STP02. De lo contrario, el procesamiento pasa a la siguiente instrucción IF (IF2).

  • En IF2, si STP01 ha comenzado la ejecución, se ejecutan STP03a y STP03b.

  • En IF3, si STP03b no ABEND, entonces se ejecuta STP04. En ELSE, no hay declaraciones. Se llama instrucción NULL ELSE.

  • En IF4, si STP01.RC = 0 y STP02.RC <= 4 son TRUE, se ejecuta STP05.

  • En IF5, si el paso de proceso PST1 en PROC PRC1 en el paso de trabajo STP05 ABEND, entonces se ejecuta STP06. De lo contrario, se ejecuta STP07.

  • Si IF4 se evalúa como falso, entonces STP05 no se ejecuta. En ese caso, IF5 no se prueba y los pasos STP06, STP07 no se ejecutan.

El IF-THEN-ELSE no se ejecutará en el caso de una terminación anormal del trabajo, como que el usuario cancele el trabajo, expire el tiempo del trabajo o un conjunto de datos se referencia hacia atrás a un paso que se omite.

Establecer puntos de control

Puede establecer un conjunto de datos de punto de control dentro de su programa JCL usando SYSCKEOV, que es una declaración DD.

UN CHKPTes el parámetro codificado para conjuntos de datos QSAM de varios volúmenes en una declaración DD. Cuando un CHKPT se codifica como CHKPT = EOV, se escribe un punto de control en el conjunto de datos especificado en la declaración SYSCKEOV al final de cada volumen del conjunto de datos de múltiples volúmenes de entrada / salida.

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

En el ejemplo anterior, se escribe un punto de control en el conjunto de datos SAMPLE.CHK al final de cada volumen del conjunto de datos de salida SAMPLE.OUT.

Reiniciar procesamiento

Puede reiniciar el procesamiento de éter de forma automática utilizando el RD parameter o manual usando el RESTART parameter.

RD parameter está codificado en la instrucción JOB o EXEC y ayuda en el reinicio automatizado de JOB / STEP y puede contener uno de los cuatro valores: R, RNC, NR o NC.

  • RD=R permite reinicios automáticos y considera el punto de control codificado en el parámetro CHKPT de la declaración DD.

  • RD=RNC permite reinicios automáticos, pero anula (ignora) el parámetro CHKPT.

  • RD=NRespecifica que el trabajo / paso no se puede reiniciar automáticamente. Pero cuando se reinicia manualmente usando el parámetro RESTART, se considerará el parámetro CHKPT (si lo hay).

  • RD=NC no permite el reinicio automático y el procesamiento de puntos de control.

Si existe el requisito de realizar un reinicio automático solo para códigos de finalización anormal específicos, se puede especificar en el SCHEDxx miembro de la biblioteca parmlib del sistema IBM.

RESTART parameterestá codificado en la instrucción JOB o EXEC y ayuda en el reinicio manual del JOB / STEP después del error del trabajo. RESTART puede ir acompañado de un checkid, que es el punto de control escrito en el conjunto de datos codificado en la declaración SYSCKEOV DD. Cuando se codifica un checkid, la declaración SYSCHK DD debe codificarse para hacer referencia al conjunto de datos del punto de control después de la declaración JOBLIB (si corresponde), o después de la declaración 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

En el ejemplo anterior, chk5 es el checkid, es decir, STP01 se reinicia en el checkpoint5. Tenga en cuenta que se agrega una declaración SYSCHK y la declaración SYSCKEOV se comenta en el programa anterior explicado en la sección Configuración del punto de control.