Introducción a JCL.

15
221893

Introducción a JCL.

0. Índice de contenidos.


1. Introducción

Este tutorial está enfocado a intentar explicar de forma sencilla
el proceso que necesitamos para ejecutar cualquier proceso Batch
(proceso por lotes) en un entorno Host en el lenguaje JCL (Job Control
Lenguaje).

Para comenzar deciros que un conjunto coherente de sentencias es
conocido como un procedimiento, aunque también es llamado trabajo o Job; más que
nada porque dependiendo de donde estéis se llamarán de una forma u
otra. Y a su vez todo Job está dividido en Pasos (Step) que contienen
los parámetros y programas necesarios para poder ejecutar dicho Job con
éxito.


2. Lo básico.

Estas son algunas de las características básicas que se deben de tener en cuenta a la hora de codificar un Job:

  • La mayoría de las sentencias JCL comienzan con //
  • Hay un delimitador /* (que más adelante veremos)
  • Para realizar comentarios dentro del Job //*
  • El contenido de cada sentencia a partir de la columna 72 se considera comentario (no una sentencia)
  • La primera sentencia es JOB.
  • Todas las sentencias han de escribirse en MAYÚSCULAS, es que si no les gritas no funcionan 😉
  • Un Job debe tener como mínimo un paso o sentencia del tipo EXEC asociada al programa que se desea ejecutar.
  • El Job termina en una última línea que incluye solo los caracteres //

Como el fin de ejecutar cualquier Job es realizar el procesamiento de
datos, vamos a definir una serie de términos para ver la organización e
interpretación de dichos datos. Dentro del Job habrá que definir cuanto
espacio en máquina vamos a necesitar para guardar dichos datos. Existen
2 tipos:

  • PISTA (TRK): pequeña superficie de un disco físico.
  • CILINDRO (CYL): está formado por 15 pistas.

Para ficheros pequeños deberemos utilizar TRK, ya que si abusamos de
los CYL la máquina nos puede echar para atrás en procedimiento por
falta de espacio. Para la correcta gestión de los mismos debemos saber
que:

  • DATOS: Es la información que el ordenador necesita para realizar su proceso
  • CAMPOS: Es un área de datos concreta
  • REGISTRO: Conjunto de campos
  • FICHERO: Conjunto de registros

Para realizar una correcta ejecución de un Job tendremos que
asegurarnos tener una serie de registros coherentes, pudiendo ser el
formato de los mismos de las siguientes formas:

  • Fijo (F): todos tienen una misma longitud
  • Variable (V): de longitud variable
  • Bloqueado (B): los registros lógicos y físicos no tienen la misma longitud
  • Expandido (S): los registros lógicos pueden expandirse a diferentes registros físicos
  • Indefinido (U): son de longitud variable, no se especifica la longitud en el registro. Se genera un bloque del tamaño del registro

Una vez definidos los formatos de los registros habrá que ver cuáles son los tipos de ficheros que nos podemos encontrar:

  • SECUENCIAL: Se almacenan los registros uno detrás de otro,
    recuperándose, a la hora de su lectura, en el mismo orden en que fueron
    grabados en el fichero.
  • PARTICIONADO (PDS): Estos ficheros contienen miembros y un
    directorio. El directorio está situado al comienzo del fichero y
    contiene una entrada para cada miembro. Los miembros se pueden tratar
    como ficheros secuenciales.
  • VSAM: Organización de ficheros y método de acceso de alto
    rendimiento. Organiza y mantiene los datos mediante una estructura de
    catálogos, usando memoria virtual.

Después de ver todas estas características, estamos
preparados para comenzar a ver la estructura y comandos de un Job.


3. Estructura y comandos de un Job.

Vamos a ver un ejemplo de Job, teniendo en cuenta que los caracteres y
números que aparecen en primer lugar solo son una regla que nos sirve
de guía para no sobrepasar nunca los 72 caracteres de codificación
(recordar que a partir de ahí se considera comentario):

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB 102,'TUTORIAL',CLASS=A,
//         MSGCLASS=H,MSGLEVEL=(1,1),
//         NOTIFY=&SYSUID,REGION=4M,
//         TIME=NOLIMIT,COND=(0,NE),PRTY=15,
//         RESTART=PASOSORT,TYPRUN=SCAN

Sentencia JOB, primera sentencia (llamada también cabecera) que indica el principio del Job. Solo puede existir una por Job.

Definiremos los parámetros de palabra clave en esta sentencia:

  • CLASS: indica la cola de entrada donde esperará el trabajo para ser ejecutado.
  • MSGCLASS: indica la cola de salida donde dejará los mensajes que genere la ejecución.
  • MSGLEVEL: indica el tipo de mensajes que ha de imprimir el sistema, se
    realiza mediante dos sub-parámetros el primer ´1´ indica que queremos
    todos los mensajes JCL que se generen en el sistema y el segundo ´1´
    indica que también queremos los mensajes relacionados con la
    información de los ficheros que vaya a usar el Job. Si no queremos la
    información relacionada con los ficheros dejaremos (1, 0).
  • NOTIFY: indica el nombre del usuario al que el sistema enviará un mensaje cuando termine el trabajo.
  • TIME: indica el tiempo máximo de CPU que puede emplear el Job.
  • REGION: indica la cantidad de memoria que va a utilizar el Job en su ejecución.
  • COND: indica una condición para que los pasos del Job se sigan ejecutando.
  • PRTY: se establece una prioridad al Job dentro de la clase de entrada.
  • RESTART: indica desde que paso queremos re arrancar un Job (en caso de
    fallo del mismo) saltándose los pasos anteriores. Si no se especifica
    lanzaría todo el Job desde el principio y hay ocasiones en las que no
    es necesario.
  • TYPRUN: indica el tipo de ejecución del Job (SCAN, validación sintáctica…)

El nombre del Job seria PRUEBJOB y el nombre del programador seria
TUTORIAL. Un aspecto a tener en cuenta es que ni el nombre del Job ni
el del programador deben superar los 8 caracteres, y si pones más, no
te preocupes que al ejecutar el Job te lo dirá con un mensaje de error.
Ni que decir tiene que la mejor forma para que una cabecera este
correctamente codificada es realizar el típico copy/paste de un Job que
ya funcione ;_)

A continuación definiremos la sentencia EXEC, necesaria para ejecutar
un programa dentro de un Job, en este caso el programa TUTORPGM:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB EXEC PGM=TUTORPGM,REGION=10M,
//         TIME=(30,00),COND=((0,NE),(4,LT,EXTRAER)),
//         ACCT=(prestamos.),DYNAMNBR=10,
//         PARM=('TUTORIAL JCL PRUEBA 2010'),RD=NC,
//         ADDRSPC=REAL
  • REGION: especifica la cantidad de memoria que puede utilizar el paso.
  • TIME: indica el tiempo máximo que puede emplear el paso (minutos, segundos).
  • COND: específica bajo qué condiciones no se ejecutará el paso.
  • ACCT: especifica la información contable relativa al paso, exigida por la instalación.
  • DYNAMNBR: máximo número de ficheros que pueden asignarse en un momento determinado, para su reutilización en el siguiente paso.
  • PARM: se utiliza para pasar algún tipo de información al programa que
    está en proceso. Se pueden pasar como máximo 100 caracteres.
  • RD: controla las posibilidades de re arranque del paso en el que está codificado.
  • ADDRSPC: indica el tipo de memoria (virtual o real) en  que se ejecutará el paso.

Para poder continuar con la ejecución de nuestro Job necesitaremos
utilizar la sentencia DD, que describe los ficheros con los que se va a
trabajar (una sentencia DD por cada fichero). La cual identifica cada
fichero lógico definido en la SELECT del programa con su fichero físico.

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//FICHERO1 DD DSN=TUTORIAL.PRUEBA.FICHERO1,
//         DISP=(NEW,CATLG,DELETE),VOL=SYSDTB1,
//         UNIT=4200,LABEL=3,SPACE=(TRK,(10,5),RLSE),
//         SYSOUT=*,COPIES=4,DEST=RMT005,OUTLIM=1500,
//         RECFM=FB,LRECL=150,BLKSIZE=1500
  • DSN: nombre físico del fichero.
  • DISP: indica el estado en el que se encuentra el fichero cuando empieza el trabajo, y cómo quedará después de la ejecución.
  • formato para este parámetro es el siguiente:

        DISP=(NEW,CATLG,DELETE)

    • Parámetro 1: indica el estado del fichero al iniciarse el paso.
      • NEW: no existe y se crea en el paso.
      • OLD: existe y se debe utilizar de forma exclusiva.
      • SHR: existe y se puede compartir.
      • MOD: si el fichero ya existe, no se puede compartir, y se posiciona tras el último registro existente en el fichero.
        • Si el fichero no existe, equivale al estado NEW.
        • Si no se codifica, se asume por defecto NEW.
    • Parámetro 2: estado del fichero cuando termina bien el paso.
    • Parámetro 3: estado del fichero cuando el paso finaliza de manera anormal (ABEND).
      • DELETE: el fichero se borra, incluso del catálogo.
      • KEEP: el fichero se guarda al terminar el paso. Sin embargo, no guarda
        información de fichero (UNIT, VOL…) para pasos posteriores, habría
        que volver a codificarlas al usar el fichero.
      • CATLG: el fichero se guarda y se cataloga.
      • UNCATLG: el fichero se guarda, pero se elimina del catálogo.
      • PASS: el fichero se guarda al terminar el paso, pero se borra al
        terminar el Job. Guarda información del fichero para pasos posteriores.
        Sólo es válido para el Parámetro 2, ya que en caso de ABEND, se pierden
        todos los ficheros temporales.
        • Si no se codifica, se asume KEEP.
        • Si ya existe (OLD), y DELETE, si no existe (NEW).
  • VOL: volumen en el que residirá el nuevo fichero.
  • UNIT: se utiliza para indica al sistema que sitúe el fichero en un dispositivo específico (disco, cinta).
  • LABEL: especifica el tipo de etiqueta asociada con el fichero, el
    número relativo del fichero en la cinta y si el fichero tiene
    protección de entrada o de salida.
  • SPACE: permite solicitar espacio para un fichero nuevo en un volumen de acceso directo. Consta de los siguientes subparámetros:
    • Unidad en las que se mide el espacio (pistas (TRK), cilindros (CYL)).
    • Cantidad de espacio a asignar:
      • Extensión primaria: espacio que se reservará para el fichero en el momento de crearlo.
      • Extensión secundaria: cantidad de espacio que se añade cada vez que el fichero se quede pequeño.
    • RLSE: indica que el espacio no utilizado en la creación del fichero, se liberará al cerrarlo
  • SYSOUT: indica que el fichero lógico debe direccionarse a una clase de salida, en lugar de a un disco o a una cinta.
  • COPIES: número de copias que se desea obtener de un listado.
  • DEST: impresora física por la que se listará el informe a imprimir.
  • OUTLIM: número máximo de líneas que se van a imprimir.
  • RECFM: formato y bloqueo del registro.
  • LRECL: longitud del registro.
  • BLKSIZE: longitud del bloque.

La sentencia DD tiene algunos parámetros especiales:

  • JOBLIB: librería donde se encuentran los programas que se quieren ejecutar.
  • STEPLIB: librería donde se encuentra el programa del paso que se quiere ejecutar.
  • SYSABEND: realiza el volcado de memoria de usuario y de sistema en caso de abend del proceso.
  • SYSUDUMP: realiza el volcado de memoria de usuario en caso de abend del proceso.
  • SYSCHK: opción para que el sistema escriba un fichero de checkpoints para posibles re arranques en la ejecución de un programa.


4. Programas y utilidades.

Una vez vistas la sentencia EXEC y la sentencia DD, vamos a
ver una serie de programas (utilidades para IBM) que nos proporciona
MVS (Sistma operativo del MainFrame) y que nos pueden ser de gran ayuda:

IEBGENER: esta utilidad realiza varias funciones

  • Crear una copia de un fichero secuencial o de un miembro de un particionado.
  • Crear un particionado o un miembro a partir de un secuencial.
  • Añadir miembros a un particionado.
  • Generar una salida editada de un fichero secuencial o particionado.
  • Cambiar el blocaje de un fichero o modificar las longitudes de registro de un fichero.
         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//PROGRAMA EXEC PGM=IEBGENER
//SYSPRINT DD   SYSOUT=*    
//SYSUT1   DD   DSN=TUTORIAL.PRUEBA.FICHERO1,DISP=SHR    
//SYSUT2   DD   DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=SHR
//SYSIN    DD   *
       GENERATE MAXFLDS=80,MAXLITS=5
       RECORDS FIELD=(5,'PEREZ',,1),
               FIELD=(3,1,PZ,6)        EXITS         IOERROR=RUTINA
  • SYSPRINT: fichero de salida donde la utilidad deja los mensajes de ejecución.
  • SYSUT1: fichero de entrada.
  • SYSUT2: fichero de salida.
  • SYSIN: codificación de las sentencias de control
  • GENERATE MAXFLDS: número de campos que se van a dejar en el fichero de salida.
  • MAXLITS: número de caracteres, en literales, que se pueden dejar en los campos de salida del fichero.
  • RECORD: permite definir el registro de datos.
  • FIELD: longitud, posición inicial en entrada, conversión, posición inicial en salida.

DFSORT: esta utilidad realiza varias funciones

  • Ordenación de registros en un fichero
  • Unión de dos o más ficheros (un máximo de 16) de entrada en uno de salida. Se van incluyendo en el SORTINnn del ejemplo.
  • Copia de ficheros sin ordenación ni mezclar ficheros.
  • Eliminación de registros de un fichero.
  • Reformateo de registros de un fichero.
  • Acumular los valores de los registros.

Vamos a ver unos ejemplos (Ordenación, Unión y Copia) para poder
especificar cuáles son las sentencias control para la utilidad DFSORT.

Ordenación:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//PROGRAMA EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*    
//SYSIN    DD   *
       SORT FIELDS=(1,5,CH,A,7,8,CH,D)
       INCLUDE COND=(1,5,CH,EQ,'00001')
       SUM FIELDS=(14,9,PD)
       OUTREC FIELDS=(1,100)
//SORTIN   DD DSN=TUTORIAL.PRUEBA.FICHERO1,DISP=SHR
//SORTOUT  DD DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=...
//SORTWKnn DD UNIT=SYSDA,SPACE=(CYL,(1,1),RLSE)
  • SYSOUT: fichero de salida donde la utilidad SORT deja los mensajes de la ejecución.
  • SORTIN: fichero de entrada que se quiere ordenar hasta un total de 99 ficheros.
  • SORTOUT: fichero de salida ya ordenado y reformateado.
  • SORTWKnn: ficheros de trabajo que se utilizan para que el sistema
    tenga mejor rendimiento al realizar la ordenación del fichero.
  • SYSIN: codificación de las sentencias de control:
    • SORT FIELDS=(inicio, longitud, tipo, orden):
      Indica los campos por los que se quiere ordenar el fichero. Dichos
      campos se especifican mediante su posición de inicio y su longitud, el
      orden puede ser Ascendente o Descendente, y el tipo de campo: CH
      (carácter); BI (binario); PD (empaquetado); ZD (decimal).
    • INCLUDE COND=(inicio, longitud, tipo, operador comparación, valor)
      Incluye únicamente los registros que cumplen la condición especificada,
      en este caso que sean iguales a ‘00001’. Para poner varias condiciones,
      se utilizan los operadores lógicos (AND, OR) separados por comas.
    • OMIT COND
      Se excluyen los registros que cumplen una condición especificada. Tiene el mismo formato que la sentencia INCLUDE COND.
    • SUM FIELDS=(posición inicio campo, longitud, tipo)
      Permite sumar los valores del campo que comienza en la posición
      indicada y que ocupa los bytes indicados. Sólo se pueden sumar campos
      numéricos, empaquetados o decimales.
    • SUM FIELDS=NONE
      Se eliminan registros duplicados.
    • OUTREC FIELDS=(posición, longitud)
      Se utiliza para reformatear el registro de salida, en este caso le
      decimos que solo saque en el fichero de salida desde la posición 1
      ocupando 100. Reformatea los registros después de ordenar.
    • INREC FIELDS
      Reformatea los registros antes de ordenar. Tiene el mismo formato que la sentencia OUTREC FIELDS.

Unión:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//PROGRAMA EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*	
//SYSIN    DD   *
       MERGE FIELDS=(1,5,CH,A,7,8,CH,D)
       INCLUDE COND=(1,5,CH,GT,6,5,CH)
       SUM FIELDS=(14,9,PD)
       OUTREC FIELDS=(1,100)
//SORTINnn DD DSN=?,DISP=SHR
//SORTOUT  DD DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=...

Copia:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//PROGRAMA EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*	
//SYSIN    DD   *
       SORT FIELDS=COPY
       INCLUDE COND=(1,5,CH,GT,6,5,CH)
       OUTREC FIELDS=(1,100)
//SORTIN   DD DSN=TUTORIAL.PRUEBA.FICHERO1,DISP=SHR 
//SORTOUT  DD DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=...

IDCAMS: esta utilidad realiza varias funciones

  • Definir y borrar un fichero VSAM.
  • Copiar un fichero en otro.
  • Construir índices alternativos.
  • Listar catálogos.
  • Imprimir ficheros.
  • Transferir ficheros de un sistema a otro.

Vamos a ver unos ejemplos (Definición, Borrado y
Copia) para poder especificar cuáles son las sentencias control para la
utilidad IDCAMS.

Definición:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//DEFINIR  EXEC PGM=IDCAMS
//SYSPRINT DD   SYSOUT=*	
//SYSIN    DD   *
       DEFINE CLUSTER(NAME(TUTORIAL.PRUEBA)      -
                      RECORDS (500 50)           -
                      RECSZ   (25  25)           -
                      KEYS    (10   0)           -
                      VOLUME  (DIR003)           -
                      SHR     (2    3)           -
                      INDEXED)                   -
              DATA (NAME(TUTORIAL.PRUEBA.DATA))  -
              INDEX(NAME(TUTORIAL.PRUEBA.INDEX))
  • CLUSTER: como se define un fichero VSAM en su creación
    • NAME: identifica el fichero dentro del catálogo. Posteriormente se identificará en una DSN.
    • RECORDS: el espacio requerido se puede indicar en registros, pistas (TRAKS) o cilindros (CYLINDERS).
    • RECSZ: el tamaño del registro consta de dos parámetros, el primero
      indica el tamaño medio en bytes de los registros que se van a almacenar
      en el fichero; el segundo indica el tamaño máximo en bytes de dichos
      registros. Si son iguales indica que los registros son de longitud fija.
    • KEYS: define la clave. Consta de dos subparámetros, el primero indica
      el tamaño en bytes de la clave, y el segundo indica la posición desde
      el comienzo del registro. Generalmente, la clave comienza en la primera
      posición del registro.
    • VOL: indica el nombre del disco en el que el fichero va a grabarse.
    • SHR: indica el grado de compartición del fichero. Consta de dos subparámetros:
    • El primero indica la compartición en distintos trabajos.
      El segundo indica la compartición en distintos sistemas.

    • INDEXED: indica que el fichero es del tipo KSDS. NONINDEXED indica que
      el fichero es del tipo ESDS y NUMBERED con un fichero RRDS.
  • DATA: se utiliza para definir los datos del fichero VSAM.
  • INDEX: se utiliza para definir el índice del fichero VSAM. Sólo se codifica cuando el fichero es KSDS.

Borrado:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//BORRADO  EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*    
//SYSIN    DD   *
       DELETE TUTORIAL.PRUEBA CLUSTER -
                             
PURGE          
  • CLUSTER: indica que se tiene que borrar un fichero VSAM. Cuando se
    elimina el CLUSTER, se borran también los DATA e INDEX asociados al
    fichero.
  • PURGE: permite borrar un fichero aunque no haya llegado su fecha de caducidad.
  • ERASE: se machacan los datos del fichero con ceros binarios.

Copia:

         1         2         3         4         5         6         7
----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
//PRUEBJOB JOB    
//COPIAR   EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//FICHERO1 DD DSN=?
//FICHERO2 DD DSN=?	
//SYSIN    DD   *
       REPRO INFILE  (FICHERO1) -
             OUTFILE (FICHERO2) -
             SKIP    (100)      -
             COUNT   (1500)       
  • REPRO: parámetro que indica que se trata de una copia.
  • INFILE y OUTFILE: identifican los nombres de los ficheros de entrada y salida.
  • INDATASET y OUTDATASET: opcional, pueden especificarse en lugar de INFILE y OUTFILE.
  • SKIP: número de registros que deben saltarse desde el inicio del
    fichero antes de comenzar el proceso de copiado. También se pueden
    codificar:

    • FROMKEY: indica la clave inicial (KSDS).
    • FROMADDRESS: indica la dirección inicial (ESDS).

  • FROMNUMBER: indica el número de registro inicial (RRDS).

  • COUNT: número de registros que queremos copiar. También se pueden codificar:
    • TOKEY: indica la clave final (KSDS).
    • TOADDRESS: indica la dirección final (ESDS).
    • TONUMBER: indica el número de registro final (RRDS).

    IEBCOPY: esta utilidad realiza varias funciones

    • Copiar de un fichero particionado a otro fichero particionado o a un secuencial.
    • Copiar de uno o más ficheros secuenciales a un fichero particionado.
    • Copiar o mezclar varios ficheros particionados.
    • Comprimir un fichero particionado (copiándolo sobre sí mismo).
    • Reemplazar miembros de un particionado.
    • Renombrar miembros de un particionado.

    Vamos a ver un ejemplo para poder especificar cuáles son las sentencias control para la utilidad IEBCOPY.

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PRUEBJOB JOB   
    //COPIAR   EXEC PGM=IEBCOPY
    //SYSPRINT DD SYSOUT=*
    //SYSUT1   DD DSN=TUTORIAL.PRUEBA.FICHERO1,DISP=SHR
    //SYSUT2   DD DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=SHR
    //SYSUT3   DD SPACE=(CYL,(2,1),RLSE),UNIT=SYSDA
    //SYSUT4   DD SPACE=(CYL,(2,1),RLSE),UNIT=SYSDA
    //SYSIN    DD *
           COPY   OUTDD=SYSUT2,INDD=SYSUT1
           SELECT MEMBER=((MIEMBRO1,R),MIEMBRO2,
                         	(MIEMBRO3,MIEMBROZ),MIEMBRO4) 
    
    • COPY: copia un fichero particionado.
      • OUTDD: indica el fichero de salida.
      • INDD: indica el fichero o ficheros de entrada. Con la opción ‘R’ se
        reemplazan los miembros que tengan el mismo nombre en el fichero
        particionado de salida.
      • COPY  OUTDD=nombreDD
        INDD=(nombreDD,(nombreDD,R),…)

    • SELECT: especifica los nombres de los miembros de los ficheros de entrada que se van a copiar.
    • EXCLUDE: indica los nombres de los miembros que se excluirán de la copia.

    IEBCOMPR: utilidad que se emplea para la comparación de ficheros, tanto secuenciales como particionados.
    Se utilizan las mismas sentencias que en la utilidad IEBCOPY, con la única excepción de que no se necesitan ficheros de trabajo.
    Devuelve un código de retorno 8 cuando los ficheros no son iguales.

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PRUEBJOB JOB   
    //PROGRAMA EXEC PGM=IEBCOMPR
    //SYSPRINT DD SYSOUT=*
    //SYSUT1   DD DSN=TUTORIAL.PRUEBA.FICHERO1,DISP=SHR
    //SYSUT2   DD DSN=TUTORIAL.PRUEBA.FICHERO2,DISP=SHR
    //SYSIN    DD *
           COMPARE TYPORG=PS
    
    • COMPARE – PS indica ‘fichero secuencial’ y PO ‘fichero particionado’


    5. Utilidades no MVS.

    A continuación vamos a analizar otras utilidades, no MVS, que pienso os pueden ser de gran utilidad en el día a día.

    LOAD

    Utilidad que permite cargar registros en tablas y construir o ampliar índices de las mismas.

    Si la tabla ya contiene datos, se podrían añadir otros nuevos, o bien,
    reemplazar los datos ya existentes. Ni que decir tiene que antes de
    realizar la carga los datos serán previamente validados.

    Ejemplo:

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //***********************************************************      
    //* ABRE UT                                                           
    //***********************************************************      
    //*                                                                     
    //ABRER10  EXEC DB2COMMN,SISTEMA='DBD1',COND=EVEN                       
    //SYSTSIN  DD  *                                                                           
    DSN SYSTEM(DBD1) SN SYSTEM(DBD1)                                                        
    -START DB(OI45859) SPACE(DES45859) ACCESS(FORCE)                       
    -START DB(OI45859) SPACE(SRAFNMRH) ACCESS(FORCE) 
    //***********************************************************       
    //* BORRAR FICHEROS DE CARGA                                            
    //***********************************************************       
    //*                                                                     
    //DELETE   EXEC PGM=IDCAMS                                              
    //SYSPRINT  DD SYSOUT=*                                                 
    //SYSIN     DD *                                                           
    DEL TUTORIAL.PRUEBA.LOAD.SORTOUT.NNAAA                                     
    DEL TUTORIAL.PRUEBA.LOAD.SYSERR.NNAAA                                     
    DEL TUTORIAL.PRUEBA.LOAD.SYSMAP.NNAAA                                      
    DEL TUTORIAL.PRUEBA.LOAD.SYSDISC.NNAAA                                     
    DEL TUTORIAL.PRUEBA.LOAD.SYSUT1.NNAAA                                      
    SET MAXCC = 0                                                        
    //*
    //LOAD     EXEC DSNUPROC,SYSTEM=DBD1,UID='LOADAFNM',                                  
    //     UTPROC='',SIZE=0M                                                         
    //SORTOUT   DD DSN=TUTORIAL.PRUEBA.LOAD.SORTOUT.NNAAA,                                  
    //             DISP=(NEW,CATLG,DELETE),UNIT=SYSALLDA,                                 
    //             SPACE=(TRK,(210,15),RLSE)                                         
    //SYSERR    DD DSN=TUTORIAL.PRUEBA.LOAD.SYSERR.NNAAA,                                    
    //             DISP=(NEW,CATLG,DELETE),UNIT=SYSALLDA,                                 
    //             SPACE=(TRK,(15,15),RLSE)                                          
    //SYSMAP    DD DSN=TUTORIAL.PRUEBA.LOAD.SYSMAP.NNAAA,                                    
    //             DISP=(NEW,CATLG,DELETE),UNIT=SYSALLDA,                                 
    //             SPACE=(TRK,(15,15),RLSE)                                          
    //SYSDISC   DD DSN=TUTORIAL.PRUEBA.LOAD.SYSDISC.NNAAA,                                   
    //             DISP=(NEW,CATLG,DELETE),UNIT=SYSALLDA,                                 
    //             SPACE=(TRK,(15,15),RLSE)
    //SYSUT1    DD DSN=TUTORIAL.PRUEBA.LOAD.SYSUT1.NNAAA,                                    
    //             DISP=(NEW,CATLG,DELETE),UNIT=SYSALLDA,                                 
    //             SPACE=(TRK,(30,15),RLSE)
    //* FICHERO QUE CONTIENE LOS DATOS A CARGAR                                    
    //SYSREC00  DD DSN=TUTORIAL.PRUEBA.FICHERO.CARGA,                                       
    //             DISP=SHR                                                          
    //SYSIN    DD  *                                                                    
    LOAD DATA LOG NO                                                                   
    INDDN SYSREC00                                                                     
    RESUME NO REPLACE                                                                   
    INTO TABLE    TABLA_MAESTRA                                                   
    /*                                                                      
    //**********************************************************            
    //* ABRE PARA R/W                                                       
    //**********************************************************                         
    //*                                                                             
    //ABRER10  EXEC DB2COMMN,SISTEMA='DBD1',COND=EVEN                               
    //SYSTSIN  DD  *                                                                     
    DSN SYSTEM(DBD1)                                                                      
    -START DB(OI45859) SPACE(DES45859) ACCESS(FORCE)                                       
    -START DB(OI45859) SPACE(SRAFNMRH) ACCESS(FORCE)                                     
    //*                                                                     
    //**********************************************************                         
    //* BORRAR FICHEROS CARGA                             
    //**********************************************************                         
    //*                                                                             
    //DELETE   EXEC PGM=IDCAMS                                                    
    //SYSPRINT  DD SYSOUT=*                                                          
    //SYSIN     DD *                                                                     
    DEL TUTORIAL.PRUEBA.LOAD.SORTOUT.NNAAA                                                 
    DEL TUTORIAL.PRUEBA.LOAD.SYSUT1.NNAAA                                                   
    //*   
    //CARGA01  JOB (CDT),'LOAD',NOTIFY=&SYSUID,                 
    //             CLASS=C,MSGCLASS=H,MSGLEVEL=(1,1)               
    //*       *********************************************        
    //*       * LOAD UTILITY REPLACE NOCOPYPEND           *        
    //*       *********************************************        
    //PASO010  EXEC DBAAPROC,SYSTEM=DBAA,UID='LOAD.DATA',UTPROC='' 
    //SYSREC00 DD DSN=TUTORIAL.PRUEBA.UNLOAD1,DIS=SHR         
    //SYSUT1   DD DSN=&&TEMPS,SPACE=(CYL,(10,5),,,ROUND),UNIT=SYSDA
    //SORTOUT  DD DSN=TUTORIAL.PRUEBA.SORTOUT1,DISP=(NEW,DELETE,CATLG),    
    //            SPACE=(CYL,(10,5),,,ROUND),UNIT=SYSDA            
    //UTPRINT  DD SYSOUT=*                                         
    //SYSIN    DD *                                                
      LOAD DATA INDDN SYSREC00 LOG NO RESUME YES NOCOPYPEND        
           INTO TABLE TABLA_MAESTRA;                                  
    /*                                                             
    //*     
    
    • SYSREC: fichero de entrada que contiene los datos a cargar.
    • SYSPRINT: fichero de salida donde la utilidad deja los mensajes de ejecución.
    • SYSUT1: fichero de trabajo temporal que se usa para ordenar ficheros de entrada.
    • SORTOUT: fichero de trabajo temporal que se usa para ordenar ficheros de salida.
    • SYSERR: fichero de errores de proceso.
    • SYSMAP: fichero de trabajo para mapear el identificador de las columnas de una tabla, en caso de error.
    • SYSDISC: fichero de trabajo que contiene los registros no cargados.
    • UTPRINT: fichero que contiene mensajes desde DFSORT.
    • SYSIN: codificación de los mandatos o sentencias de control.

    Siendo las sentencias control para la utilidad LOAD las siguientes:

    • DATA: identifica los datos seleccionados para cargar con el nombre de la tabla que se indica en INTO TABLE.
    • INDDN: especifica el nombre del fichero de entrada. Dicho fichero
      tiene que ser de acceso secuencial y formato fijo o variable. Por
      defecto es SYSREC.
    • RESUME: indica si los registros van a ser cargados en un table space vacío o no.
      • NO: valor por defecto. Carga registros en un table space vacío. Por si
        acaso no estuviese vacío, habría que utilizar REPLACE para evitar
        errores.
      • YES: carga registros en un table space no vacío. Si estuviese vacío,
        daría un warning, pero los datos se cargarían correctamente.
    • REPLACE: indica si el table space y todos sus índices necesitan ser
      reseteados, para vaciar antes de cargar los registros. Con esta opción,
      las columnas nuevas a cargar reemplazarán a todas las existentes.
    • LOG: indica si la entrada al sistema ocurre durante la fase de reload o en el proceso de carga.
      • NO: valor por defecto . Entrada al sistema durante el proceso de carga.
      • YES: esta opción pone la restricción COPY-pending, por la cual
        no se puede actualizar ninguna tabla. A través de NOCOPYPEND, se indica
        al LOAD que no fije el status de COPY-pending.

    UNLOAD

    Utilidad que permite recuperar datos de tablas DB2, descargando las tablas enteras, o bien, especificando ciertas columnas.

    Ejemplo:

    //DESCARG1 JOB (CDT00),'UNLOAD ',CLASS=C,                             
    //            MSGCLASS=X,MSGLEVEL=(1,1),NOTIFY=&SYSUID,               
    //            REGION=4096K                                            
    //********************************************************************
    //* DESCARGA A TRAVES DE UNA SELECT                                   
    //********************************************************************
    //*                                                                   
    //PASO010  EXEC PGM=IKJEFT01
    //SYSTSPRT DD SYSOUT=*                              
    //SYSTSIN  DD *                                     
      DSN SYSTEM(DBAA)                                  
      RUN PROGRAM(DSNTIAUL) PLAN(DSNTIB71) PARM('SQL') -
          LIB('LIBRERIA.TUTORIAL.RUNLIB.LOAD')                   
      END                                               
    //SYSPRINT DD SYSOUT=*                              
    //SYSUDUMP DD SYSOUT=*                              
    //SYSPUNCH DD SYSOUT=*                              
    //SYSREC00 DD DSN=TUTORIAL.PRUEBA.UNLOAD1,     
    //            SPACE=(TRK,(10,10),RLSE),             
    //            DISP=(NEW,CATLG,DELETE),              
    //            UNIT=SYSDA                            
    //SYSIN    DD *                                     
      SELECT * FROM TABLA_MAESTRA
      ;                                                 
    /*
    
    • SYSREC: fichero de salida que contiene los datos descargados.
    • SYSPRINT: fichero de salida donde la utilidad deja los mensajes de ejecución.
    • SYSPUNCH: fichero de trabajo que contiene las sentencias de LOAD necesarias para un proceso de recarga de datos.
    • SYSIN: codificación de los mandatos o sentencias de control.

    RESTART

    Si lanzamos un Job y por cualquier circunstancia falla o es cancelado,
    no hace falta volver a ejecutarlo desde el principio, con esta utilidad
    le decimos desde que paso queremos que comience de nuevo la ejecución.
    Hay que tener en cuenta que si relanzamos un Job puede que se hayan
    creado los ficheros de salida correspondientes al paso que se relanza o
    a paso posteriores. Dichos ficheros deben borrarse antes de relanzarlo
    ya que si no fallará el Job por duplicidad de ficheros.

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PRUEBJOB JOB   ...,RESTART=PASO004

    COND (Ejecución condicional)

    Comprobación de los códigos de retorno de los pasos anteriores, para
    ver si continuamos ejecutando el paso siguiente o damos por terminado o
    fallado el Job.

    • Si la condición es verdadera no se ejecuta el paso. Si no se indica nombre del paso se referirá al paso previo.
    • Si codificamos COND en la sentencia JOB se ignorarán los COND que existan en la sentencia EXEC.

    Solo se pueden codificar un máximo de 8 condiciones (incluyendo EVEN u ONLY)

    • COND=EVEN, efectúa la ejecución incluso si los pasos previos terminan de forma anormal (ABEND).
    • COND=ONLY, efectúa la ejecución sólo si los pasos previos terminan de forma anormal.

    Los operadores de comparación validos son:

    • GT    Mayor que
    • GE    Mayor o igual que
    • EQ    Igual a
    • LT    Menor que
    • LE    Menor o igual que
    • NE    Distinto de
             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PASO1    EXEC  PGM=PROGRAM1
    //PASO2    EXEC  PGM=PROGRAM2,COND=(4,EQ,PASO1)
    //PASO3    EXEC  PGM=PROGRAM3
    

    En este caso si RC=4 es verdadero no se ejecutará el PASO2, mientras
    que si es falso, sí se ejecutará. Es decir, el PASO2 sólo se ejecutará
    cuando el retorno del PASO1 sea distinto de 4.

    IF/THEN/ELSE/ENDIF

    Se utiliza para ejecutar condicionalmente pasos dentro de un trabajo, y puede tener tres campos:

    • Nombre (opcional)
    • Operación
      • IF, siempre va seguida de una expresión relacional y de la palabra
        clave THEN. Especifica los pasos del trabajo que el sistema procesará
        cuando la evaluación de la expresión relacional de la cláusula IF sea
        una condición verdadera.
      • ELSE, puede aparecer a continuación del IF. Especifica los pasos del
        trabajo que el sistema procesará cuando la evaluación de la expresión
        relacional de la cláusula IF sea una condición falsa.
      • ENDIF, indica el final de la estructura de sentencia.
    • El campo de la expresión relacional

    Pueden anidarse estructuras hasta un máximo de 15 niveles.

    Una expresión relacional consta de:

    • operadores de comparación, lógicos y NOT().
    • OPERADOR OPERACIÓN ORDEN
      OPERADOR NOT
      NOT NO PRIMERO
      OPERADOR DE COMPARACIÓN
      GT > MAYOR QUE SEGUNDO
      LT < MENOR QUE
      NG ┐> NO MAYOR QUE
      NL ┐< NO MENOR QUE
      EQ = IGUAL A
      NE ┐= DISTINTO DE
      GE >= MAYOR O IGUAL QUE
      LE <= MENOR O IGUAL QUE
      OPERADORES LÓGICOS
      AND
      OR
      &
      |
      Y
      O
      TERCERO

    • palabras clave:
      • RC, indica el código de retorno.
      • ABEND=TRUE, indica que se ha producido una terminación anormal.
      • ABEND=FALSE, indica que no se ha producido ninguna terminación anormal.
      • ABENDCC=Sxxx o ABENDCC=Uxxxx, indica un código de terminación anormal específico del sistema (S0C4) o del usuario (U0100).
      • nombrepaso.RUN=TRUE, indica que se ha ejecutado el paso especificado.
      • nombrepaso.RUN=FALSE, indica que no se ha ejecutado el paso especificado.

    GDG

    Generation Data Group (GDG), es un grupo de archivos que están funcional y cronológicamente relacionados entre sí.
    No son ficheros VSAM.
    Su nombre lo asigna el sistema de la siguiente manera:
    Nombfich.GnnnnVnn

    • Nombfich, corresponde a la denominación de grupo.
    • Gnnnn, número de generación (de 0000 a 9999). Cuando se llega al máximo
      número de ficheros para un GDG, dependiendo de los parámetros del
      sistema, el GDG se vacía por completo o sólo el más antiguo. Al añadir
      un nuevo fichero al grupo, siempre será GEN(+1), siendo el actual
      siempre GEN(0).
    • Vnn, versión de la generación (de 00 a 99). Sólo se conserva la versión más reciente.

    Creación de un GDG

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PROGRAMA EXEC PGM=IDCAMS
    //SYSPRINT DD SYSOUT=*
    //SYSIN    DD *
           DEFINE GDG                            -
                  (NAME(FICHERO.PRUEBA.TUTORIAL) -
                  LIMIT(25)                      -
                  EMPTY                          -
                  NOSCRATCH)
    

    Los parámetros empleados son los siguientes:

    • LIMIT: especifica el número máximo de GDS’s (ficheros) que puede tener un GDG.
    • EMPTY: al llegar al máximo, se descatalogan (se borran) todos los
      ficheros de generación; NOEMPTY, al llegar al máximo, sólo se
      descataloga el fichero más antiguo.
    • SCRATCH / NOSCRATCH: especifica si se borrará o no del volumen la
      información existente del fichero, cuando éste se descatalogue.

    Creación de un GDS

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //PROGRAMA EXEC PGM=PGMGDS
    //SALIDA   DD DSN=FICHERO.PRUEBA.TUTORIAL(+1),
    //            DISP=(,CATLG,DELETE),UNIT=SYSDA, //            SPACE=(TRK,(25,5),RLSE), //            RECFM=FB,LRECL=95,BLKSIZE=0

    El nombre completo del fichero empleado en el ejemplo sería:
                
    FICHERO.PRUEBA.TUTORIAL.G0001V01

    Al acabar de ejecutarse el paso, el GDG pasa a ser el actual (versión 0).
    Si un paso posterior crea otro fichero nuevo (+1), al acabar de
    ejecutarse el paso, el GDG pasa a ser el actual (versión 0), y el que
    teníamos anteriormente sería la versión (-1).

    Borrado de un GDS

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //DEL GDS EXEC PGM=IDCAMS
    //SYSPRINT DD SYSOUT=*
    //SYSIN    DD  *
           DELETE   FICHERO.PRUEBA.TUTORIAL(0) PURGE 
    

    Borrado de un GDG

             1         2         3         4         5         6         7
    ----+----0----+----0----+----0----+----0----+----0----+----0----+----0--
    //DELGDG EXEC PGM=IDCAMS
    //SYSPRINT DD SYSOUT=*
    //SYSIN    DD  *
           DELETE FICHERO.PRUEBA.TUTORIAL GDG PURGE 
    


    6. Referencias.


    07. Conclusiones.

    Bueno, pues colorín colorado… espero que toda esta información os ayude
    en algún momento de vuestra carrera profesional, o que al menos os haya
    hecho lo más ameno posible esta incursión por el mundo JCL.

    Un saludo.

    Javier Alonso.

    15 COMENTARIOS

    1. Hola Francisco, muy buen tutorial, yo soy programador analista , me especialicé en cobol , pero hace muchos años que lo dejé y me dediqué al trabajo social, actualmente en paro y realizando un curso cobol-mainframe on line que se imparte en Brasil, pero la verdad es que lo veo algo dificil, tu como aprendiste? tardaste mucho en controlar todo esto? y sobre todo hay realmente trabajo en este sector? Espero tu respuesta como profesional del sector que eres.
      Un saludo

    2. Hola, yo quiero hacer un temario para JCL utilerias y demás cursos Mainframe para darlos aqui en MEXICO,DF. (CIUDAD DE MÉXICO)
      Te dejo mi e-maily espero me puedas contestar para poder contactarte por correo.Gracias

    3. Hola, te queria preguntar si es posible ejecutar un programa pero desde una libreria personal mediante un JCL, sin tener que tener dicho programa dentro de un package compilado.
      Saludos.

    4. Consulta,
      Tengo una lista de alias. esos alias tienen, files(vsam, po, ps,gdg). En 3.4 pones «aliasxxx» y me lista 7gdg’s, 5 vsam, 6 po’s. por ejemplo. Hay alguna forma de capturar en una salida eso files de ese alias?

    5. P/Mauricio, en la misma pantalla de tso, hay una opcion para imprimir la salida a un archilvo de log., luego sales solo accedes al archivo en cuestionq ue eta con el pref de tu user..

      P/bruno. hasta donde se solo esposible si compilas (no importando si el ejecutable esta en una bib personal), ya que Cobol no es un lenguaje interpretado como lo es REXX

    6. Hola, ¿Me podrías ayudar con este problema?
      Quiero unir en un único registro de salida varios registros de un fichero de entrada. Quiero hacerlo sin ninguna condición.
      Ejemplo:
      Entrada
      AAAA
      BBBB
      CCCC
      DDDD
      La salida tendría que ser:
      AAAABBBBCCCCDDDD

      Muchas gracias. Un saludo, Esther.

    7. Hola: Podrías ayudarme con esto? Necesito a partir de un archivo de entrada, generar un archivo de salida con único registro que cuente la cantidad de registros (COUNT) y la suma de un campo en particular. Para el count tenía esta CTC:
      SORT FIELDS=COPY
      OUTFIL REMOVECC,NODETAIL,
      TRAILER1=(COUNT)

      y después agregué esto:
      SUM FIELDS=(53,10,ZD)

      Pero no funciona.
      Gracias anticipadas!

    8. Hola Francisco.
      Muchas gracias por tu post, me está ayudando mucho, sobre todo porque pones los posibles valores en cada parámetro y el significado. Recién estoy entrando al mundo de COBOL, y buscaba algo como esto.
      Saludos desde Perú.

    9. Buenas. Muchísimas gracias por el tutorial, sirve de mucha ayuda 😀

      Acabo de empezar a aprender JCL y me surge una duda sobre la sentencia JOB. En el tutorial aparece //PRUEBJOB JOB 102,’TUTORIAL’, y mi pregunta es: ¿por qué 102?
      He visto en otros JCL que ponen //EJEMPLO JOB (19),’EJEMPLO’, en otras ocasiones ponen //EJEMPLO JOB (42,,25),’EJEMPLO’. En resumen, no se para qué es 102 o (19) o (42,,25). ¿Qué es lo que indican?

      Muchas gracias de antemano!

      Es posible que esté explicado en el tutorial y no me haya percatado, si es así, sorry por preguntar algo que está puesto jajajaja

    10. Excelente material y muy didácticamente explicado. Me estoy reinsertando en el mercado del MF, y este blog se me ha hecho una gran guía y ayuda.

      Saludos.
      Juan Manuel Onofre

    11. FELICIDADES POR ESTA GRAN TRABAJO DE JCL MUY BIEN EXPLICADO. ME GUSTARÍA SABER SI PUEDE DAR UN CURSO PARA UNA EMPRESA EN MÉXICO. TE AGRADECERÉ SI ME PUEDES CONTESTAR. SALUDOS

    DEJA UNA RESPUESTA

    Por favor ingrese su comentario!

    He leído y acepto la política de privacidad

    Por favor ingrese su nombre aquí

    Información básica acerca de la protección de datos

    • Responsable:
    • Finalidad:
    • Legitimación:
    • Destinatarios:
    • Derechos:
    • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad