Cruce de ficheros con Joinkeys básico

El modo más sencillo de realizar un enfrentamiento de ficheros por JCL es usando la utilidad Joinkeys de DFSORT. Está disponible en z/OS desde 2009. Hasta entonces solo era posible enfrentar ficheros mediante Icetool usando el operador SPLICE.

Veamos un ejemplo sencillo de Joinkeys para cruzar dos ficheros y generar un fichero de salida con los registros que cruzan.

Tenemos dos ficheros de entrada de 10 posiciones . El primero contiene nombres de personas y el segundo los teléfonos de las mismas. Están relacionados por un código de persona que se encuentra en las tres primeras posiciones de ambos ficheros.

Queremos generar un fichero de salida que contenga un registro de salida por persona con la clave, el nombre y el teléfono.

No es necesario que los ficheros de entrada estén ordenados, ya que la utilidad los ordena automáticamente por las posiciones de cruce.

El paso de ejecución de Sort completo sería el siguiente:

//CRUCE EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTJNF1 DD DSN=FIC.ENTRADA1,DISP=SHR
//SORTJNF2 DD DSN=FIC.ENTRADA2,DISP=SHR
//SORTOUT DD DSN=FIC.SALIDA,DISP=(,CATLG,DELETE)
//SYSIN DD *
JOINKEYS FILE=F1,FIELDS=(1,3,A)
JOINKEYS FILE=F2,FIELDS=(1,3,A)
REFORMAT FIELDS=(F1:1,10,F2:4,7)
SORT FIELDS=COPY

Las fichas SORTJNF1 y SORTJNF2 contienen los ficheros de entrada, mientras que en SORTOUT se define el fichero de salida, como en cualquier Sort.

SYSIN contiene los parametros del proceso, que podemos dividir en tres bloques:

  1. JOINKEYS FILE: posiciones por las que se ordenará cada fichero de entrada antes del cruce, que serán también las de enfrentamiento. También se indica el criterio de ordenación (A: ascendente; D: descendente) .
  2. REFORMAT FIELDS: formato del fichero resultado del cruce, que puede contener posiciones de cualquiera de los dos ficheros. En el ejemplo, las 10 primeras del fichero 1 y 7 posiciones a partir de la cuarta del fichero 2.
  3. SORT final: el fichero resultado del cruce pasa por un Sort que nos permite cualquier tipo de formateo. En el ejemplo no es necesario, por lo que simplemente copiamos el fichero con un SORT FIELDS=COPY.

En el siguiente artículo se explican más opciones de esta utilidad, que no se limita a lo mostrado en este ejemplo. Podemos obtener en salida tanto los registros que cruzan como los que no, filtrar los ficheros de entrada antes del cruce, etc.



7 respuestas a «Cruce de ficheros con Joinkeys básico»

  1. Estoy intentando hacer un JOINKEYS pero debido a que quiero poner bastantes campos en FIELDS no me cabe en una linea. Intento ponerlo en dos pero me da error ¿cómo tendría que
    ponerlo? He probado con guión y con nada…

    JOINKEYS F1=IN1,FIELDS=(11,4,A,15,4,A,19,3,A,22,7,A, –
    29,7,A,59,56,A,39,10,A,49,10,A, –
    215,10,A,128,2,A)

    Muchas gracias.

    1. El guión no es necesario salvo que vayas a cortar un operador al final de una línea. Prueba sin guiones y si te sigue fallando publica el JCL completo y los mensajes de error que te aparezcan.

      Saludos.

      1. Hola,

        Muchas gracias por contestar. Ya lo conseguí, al final acorté la condición agrupándola.

        Ahora tengo otro problema. Querría que en el fichero de salida solo estuviesen los registros del fichero de entrada 2 en los que coinciden las claves pero me escribe todos ya que el cruce es N:1. He leido algo de la sentencia SOLOENF2 pero no se como utilizarla.

        Este es el paso:

        //****************************************************************
        //JOIN21 EXEC PGM=SORT,COND=(0,NE)
        //IN1 DD DSN=DES.IZ.LR.SORT02.SECUEN,
        // DISP=SHR
        //IN2 DD DSN=DES.IZ.LR.CONT.SEC0,
        // DISP=SHR
        //SORTOUT DD DSN=DES.IZ.LR.CONT.SEC,
        // SPACE=(TRK,(15,15),RLSE),
        // DISP=(,CATLG,),
        // DCB=(RECFM=FB,LRECL=259,BLKSIZE=0,DSORG=PS)
        //SORTOUT DD SYSOUT=*
        //SYSOUT DD SYSOUT=*
        //SYSIN DD *
        JOINKEYS F1=IN1,FIELDS=(11,25,A,59,56,A,39,20,A)
        JOINKEYS F2=IN2,FIELDS=(11,25,A,59,56,A,39,20,A)
        REFORMAT FIELDS=(F2:1,35,F1:36,3,F2:39,86,F1:125,5,F2:130,130)
        SORT FIELDS=(11,4,CH,A,15,4,CH,A,19,3,CH,A,22,7,CH,A,
        29,7,CH,A,59,56,CH,A,39,10,CH,A,49,10,CH,A,
        128,2,CH,A)
        //****************************************************************

        Gracias. Saludos.

  2. Entiendo que lo que quieres es hacer un cruce 1:1, pero tu problema es que en el primer fichero tienes registros duplicados.

    Para solucionarlo bastaría con eliminar los duplicados con un sort previo.

    Otra opción más eficiente sería utilizar la ficha //JNF1CNTL, que permite incluir sentencias de control para el sort que se hace sobre el fichero 1 antes del cruce. El fichero 2 tiene otra ficha equivalente: //JNF2CNTL.

    Saludos.

    1. Si, he eliminado duplicados y ya está 🙂 Pero lo que quería también es que en salida estuviesen todos los del fichero 2 cuyas claves estén en el 1 (como F2:1,35,F1:36,3,F2:39,86,F1:125,5,F2:130,130) pero que también estuviesen los que no coinciden la clave (el registro del fichero 2 tal cual). ¿Se te ocurre como hacerlo?

      Gracias! Saludos.

Deja un comentario