lunes, 28 de diciembre de 2020

SORT vol.3: OUTFIL.

ACTUALIZADO: ejemplo de STARTREC/ENDREC

La estructura general de un SORT es la siguiente:

//SORT001  EXEC PGM=SORT,PARM=('DYNALLOC=(SYSALLDA,32)')
//SORTIN   DD DSN=nombre.fichero.entrada1,DISP=SHR
//         DD DSN=nombre.fichero.entrada2(opcional),DISP=SHR
//SORTOUT  DD DSN=nombre.fichero.salida1,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
  …
  …

PGM=SORT --> Indica el programa a utilizar, en este caso el SORT.
PARM=('DYNALLOC=(SYSALLDA,32)') --> Cantidad de memoria que se da a la ejecución del paso. Si se queda corto, aumentarla en valores de 8,12,32,64,128, 256 (como las memorias RAM)
SORTIN --> Ficheros de entrada
SORTOUT --> Ficheros de salida
SYSIN --> Indica el tipo de sort a realizar, las opciones disponibles son muchas y muy variadas, pudiendo utilizarse varias juntas en un mismo paso. Algunas de ellas son SORT, SUM, OMIT, INCLUDE, INREC, OUTREC, OUTFIL, OPTION … .

En este documento se explica en detalle algunas de estas funciones:


OUTFIL

Esta utilidad nos permite, a partir de un fichero(o varios) de entrada, filtrar en varios ficheros de salida.
Además, permite utilizar simultáneamente, todos las utilidades del SORT(OUTREC, INCLUDE, etc.) para filtrar cada fichero independientemente del otro.

NOTA: En este documento no vamos a entrar a explicar el OUTREC, INCLUDE, etc. Existen artículos en este blog que explican en detalle estas utilidades.

La definición de un OUTFIL es la siguiente:

//SORT001  EXEC PGM=SORT,PARM=('DYNALLOC=(SYSALLDA,32)')
//SORTIN   DD DSN=nombre.fichero.entrada1,DISP=SHR
//         DD DSN=nombre.fichero.entrada2,DISP=SHR
//SALIDA1  DD DSN=nombre.fichero.salida1,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SALIDA2  DD DSN=nombre.fichero.salida2,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SALIDA3  DD DSN=nombre.fichero.salida3,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SYSOUT   DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN    DD *
 SORT FIELDS=COPY
 OUTFIL FNAMES=SALIDA1,INCLUDE=(…),
                        OUTREC=(…) ,
                         INREC=(…) ,
                         …
 OUTFIL FNAMES=SALIDA2,INCLUDE=(…),
                        OUTREC=(…) ,
                         INREC=(…) ,
                         …
 OUTFIL FNAMES=SALIDA3,SAVE


Primero se han de definir los ficheros de salida, asignando un nombre a cada uno (SALIDA1, SALIDA2, SALIDA3, etc..)
Luego, por cada fichero de salida se introduce un OUTFIL, y en el FNAMES se asocia con el nombre asignado antes (ejemplo FNAMES=SALIDA1).
A continuación, indicar en cada fichero, el filtro que se va a utilizar mediante INCLUDE, OUTREC, etc…
Utilizando la opción SAVE, se indica que todos los registros que no cumplan ninguna de las condiciones anteriores se escribirán en el fichero indicado. En el caso del ejemplo en la SALIDA3.

Cosas a tener en cuenta:
- Cuidado al escribir el INCLUDE, OUTREC, etc. Normalmente se escribe "INCLUDE COND=", y sin embargo, en el OUTFIL se escribe "INCLUDE=". Lo mismo pasa con el "OUTREC FIELDS=", que pasa a ser "OUTREC=". Por norma general, se ha de quitar la segunda parte. El "OMIT COND=" quedaría "OMIT=", etc.

Vamos a ver un ejemplo:

Situación 1. Vamos a dividir el siguiente fichero en 2, filtrando por la Situación Laboral. En el fichero de salida 1 meteremos los Asalariados y en el fichero de salida 2 los autónomos. Además en cada fichero, vamos a sacar únicamente el Nombre y los Apellidos:


----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO
000000006ANTONIO   VILLA     SUSO     AUTONOMO  
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO  
000000001JOSE      LOPEZ     PITA     AUTONOMO  
000000004CARLOS    POLO      DEL BARROAUTONOMO  
000000003CARLOS    PEREZ     FANO     AUTONOMO  


La fórmula sería:

//OUTREC   EXEC SORTD
//SYSOUT   DD SYSOUT=*
//SORTIN   DD DSN=nombre.fichero.entrada1,DISP=SHR
//SALIDA1  DD DSN=nombre.fichero.asalariados,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SALIDA2  DD DSN=nombre.fichero.autónomos,
//            DISP=(,CATLG,DELETE),SPACE=(CYL,(500,100))
//SYSIN    DD *
SORT FIELDS=COPY
OUTFIL FNAMES=SALIDA1,INCLUDE=(39,10,CH,EQ,C'ASALARIADO'),
                       OUTREC=(10,29)
OUTFIL FNAMES=SALIDA2,INCLUDE=(39,10,CH,EQ,C'AUTONOMO  '),
                       OUTREC=(10,29)

La salida quedará del siguiente modo:

SALIDA1 - ASALARIADOS:


----+----1----+----2----+----
JAVIER    MARTINEZ   CARRETERO


SALIDA2 - AUTONOMOS:


----+----1----+----2----+----
ANTONIO   VILLA     SUSO     
YOLANDA   LOPEZ     ALONSO   
JOSE      LOPEZ     PITA     
CARLOS    POLO      DEL BARRO
CARLOS    PEREZ     FANO     


STARTREC/ENDREC:
Con OUTFIL no están disponibles las opciones SKIPREC/STOPAFT, en su lugar utilizamos STARTREC y ENDREC con el mismo principio.

Retomando el fichero de entrada anterior:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO 
000000006ANTONIO   VILLA     SUSO     AUTONOMO   
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO   
000000001JOSE      LOPEZ     PITA     AUTONOMO   
000000004CARLOS    POLO      DEL BARROAUTONOMO   
000000003CARLOS    PEREZ     FANO     AUTONOMO   

//SYSIN    DD * 
SORT FIELDS=(10,29,CH,A) 
OUTFIL FNAMES=SALIDA1,ENDREC=1 
OUTFIL FNAMES=SALIDA2,STARTREC=2,ENDREC=4 

Primero se ordenan los registros:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000006ANTONIO   VILLA     SUSO     AUTONOMO   
000000003CARLOS    PEREZ     FANO     AUTONOMO   
000000004CARLOS    POLO      DEL BARROAUTONOMO   
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO 
000000001JOSE      LOPEZ     PITA     AUTONOMO   
000000005YOLANDA   LOPEZ     ALONSO   AUTONOMO   

Y luego genera los diferentes ficheros de salida:
SALIDA1:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000006ANTONIO   VILLA     SUSO     AUTONOMO   


SALIDA2:
----+----1----+----2----+----3----+----4----+----5----+----6----+----7--
000000003CARLOS    PEREZ     FANO     AUTONOMO   
000000004CARLOS    POLO      DEL BARROAUTONOMO   
000000002JAVIER    MARTINEZ  CARRETEROASALARIADO 
000000001JOSE      LOPEZ     PITA     AUTONOMO   

12 comentarios:

José dijo...

Gran post, todo clarito y de gran ayuda.

Por cierto me uno a lo apadrina un picador, help us!! jajaja

Anónimo dijo...

esta bueno el ejemplo aunque falta el save

MaNNiako dijo...

sale. grax.

Jorge Martin dijo...

¿Se podría usar esta funcionalidad pero que los ficheros de salida tuvieran distinta longitud para que en una guardaras una copia de los ficheros de entrada, y el último solo unos campos ordenados?

Gracias :)

Tallian dijo...

Hola Jorge. La longitud de los ficheros puede ser la que quieras, no tiene que ser la misma.
Para guardar una copia de los ficheros de entrada ya te lo hace el propio sort fields=copy. Si quisieses ordenarlos tendrías que incluirlo ahí.
Para la salida 2 puedes añadir las condiciones que necesites como el OUTREC para seleccionar solo ciertos campos.
Un saludo.

Ernesto dijo...

Este comentario ha sido eliminado por el autor.

Ernesto dijo...

Buenas Tardes,
Rectifico
Tengo el siguiente problema:
Tengo un
Fichero de entrada con la siguiente información:
01 xxx
01 yyy
01 zzz
02 xxx
03 xxx
03 yyy

Y quisiera un
Fichero de salida resultante:
01 xxx yyy zzz
02 xxx
03 xxx yyy

Usando Sort de JCL

Gracias

Tallian dijo...

Hola Ernesto. Solo se me ocurre que lo hagas con easytrieve.

felipe rosillo dijo...

Hola. me podría decir cuando hay alternate index que es lo que se incluye de los mismos en el JCL, el index el PATH el BLDINDEX?

Unknown dijo...

buenas! primero de todo gracias por el curso.
me puedes ayudar con siguiente caso:
tengo un fichero con siguientes registros:
1
2
1
3
necesito dividirlo en 2 ficheros, uno contine todos los registros de 1 y otro con los restos (2 y 3).
con tu ejemplo me ocurre es separar en 3 ficheros para luego juntar los de 2 y 3, pero me pregunto si hay algo mas facil de hacer.
muchas gracias

Tallian dijo...

Sería la opción SAVE, como dice el artículo:
Utilizando la opción SAVE, se indica que todos los registros que no cumplan ninguna de las condiciones anteriores se escribirán en el fichero indicado.
:-)

leo dijo...
Este comentario ha sido eliminado por el autor.