Hace algunas semanas comenzamos a ver cómo se podía realizar un cruce de ficheros en un JCL mediante el comando SPLICE de la herramienta ICETOOL. Hoy completaremos dicha revisión, de manera que, a la conclusión del post, ya deberíamos ser capaces de crear nuestro propio Job para realizar este tipo de procesamiento.
En la primera parte del artículo empezamos a examinar cuáles eran las fichas que había que incluir en el paso 1 del JCL, esto es, en el paso necesario para reformatear los ficheros de entrada (ver post
ICETOOL - Como cruzar Ficheros con SPLICE - 1). En esta segunda parte nos concentraremos en revisar las fichas correspondientes al paso 2 del JCL, en el que se procederá a generar los ficheros de salida.
PASO 2: PASO ICETOOL PARA GENERAR SALIDAS
6º)
Invocación a ICETOOL: Al
iniciar el paso, como siempre, se debe realizar la invocación a la
herramienta ICETOOL mediante el comando EXEC PGM.
//JJ0107 EXEC PGM=ICETOOL
7º)
Ficheros de entrada: En esta
ficha especificamos como entrada el fichero CONCAT, que será la unión de los dos
ficheros indicados en el código: SIST.JJ0105T1.DDD.X0060X.POBL.T1 y
SIST.JJ0105T2.X0060X.DDD.POBL.T2. Se puede apreciar que estos dos datasets son
los ficheros de salida del Paso anterior del JCL.
//* CONCAT: FICHERO UNIFICADO PARA REALIZAR EL ICETOOL
//CONCAT DD DSN=SIST.JJ0105T1.DDD.X0060X.POBL.T1,
// DISP=SHR
// DD DSN=SIST.JJ0105T2.X0060X.DDD.POBL.T2,
// DISP=SHR
8º)
Ficheros de salida: Aquí se
deben indicar los nombres de los ficheros de salida de la herramienta ICETOOL,
que contendrán los registros modificados por el operador. En nuestro ejemplo son
el SIST.JJ0107S1.X0060X.DDD.POBL.MD (que contiene los registros del MASTER
modificados según la relación del KEYS) y el SIST.JJ0107S1.X0060X.DDD.POBL.RS
(que contiene los registros que no han sido modificados en la operación).
//* OUT : FICHERO SALIDA CON LOS REGISTROS MODIFICADOS
//OUT DD DSN=SIST.JJ0107S1.X0060X.DDD.POBL.MD,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(CYL,(00100,00100),RLSE), // UNIT=DISCO
//* OUT1 : FICHERO SALIDA CON LOS REGISTROS NO MODIFICADOS
//OUT1 DD DSN=SIST.JJ0107S2.X0060X.DDD.POBL.RS,
// DISP=(,CATLG,DELETE),
// SPACE=(CYL,(00100,00100),RLSE),
// UNIT=DISCO
9º)
Ficha TOOLIN: Aquí es donde
tenemos que indicarle a la utilidad cuáles son las acciones que debe realizar.
En nuestro caso, como estamos haciendo cruce de ficheros, tendremos que usar el
operador SPLICE.
En la primera sentencia indicamos que, partiendo del fichero CONCAT, se debe
transferir la información al fichero OUT realizando el cruce por el campo de
longitud 6 que empieza en la posición 1 (Población). La forma de realizar dicho
cruce se especificará en la ficha de control CTL3.
La cláusula WITHALL se emplea para que, en el
caso de que una clave esté más de una vez en el fichero Maestro de Poblaciones
(
POBL.T2), se recojan todos los registros que la contengan. Si no
se especifica WITHALL, entonces el filtrado se quedará únicamente con el primer
registro encontrado. Por otra parte, al no incluir los comandos KEEPNODUPS y
KEEPBASE, sólo saldrán en la salida los registros cuyas claves existan en ambos
ficheros (POBL.T1 y POBL.T2).
Del mismo modo, en la segunda sentencia indicamos
que, partiendo del fichero CONCAT, se debe transferir la información al fichero
OUT1 realizando el cruce por el campo de longitud 6 que empieza en la posición
1 (Población). La forma de realizar dicho cruce se especificará en la ficha de
control CTL4.
Las cláusulas KEEPNODUPS y KEEPBASE se emplean para
mostrar en el fichero de salida los registros del fichero
POBL.T1 cuya clave no existe en el fichero
POBL.T2. Es decir, con estas cláusulas le indicamos al filtrado que
nos saque toda la información de los ficheros, incluidos los registros de
POBL.T1 cuyas claves no se localicen en el Maestro de Poblaciones (POBL.T2).
*--------------------------------------------------------*
* <<< FICHA JJRS1A06 >>>
* OUT: REGISTROS QUE COINCIDEN *
* INCLUIMOS TODO DEL MASTER MAS POBLACION NUEVA DE KEY *
* MAS UN INDICADOR NUEVO DE MODIFICADO
* OUT1: RESTO DE REGISTROS QUE NO COINCIDEN *
*--------------------------------------------------------*
SPLICE FROM(CONCAT) TO(OUT) ON(1,6,CH) WITHALL -
WITH(7,40) USING(CTL3)
SPLICE FROM(CONCAT) TO(OUT1) ON(1,6,CH) WITHALL -
WITH(7,40) USING(CTL4) KEEPNODUPS KEEPBASE
10º)
Fichas de Control: En esta
tarjeta es donde tenemos que indicar cómo queremos que se realice la función
SPLICE de la herramienta ICETOOL. En nuestro ejemplo, aquí estarían incluidas
las fichas CTL3 y CTL4.
*--------------------------------------------------------*
* <<< FICHA JJRS1A07 >>>
* SUSTITUIMOS POBL ENCONTRADOS POR POBL NUEVAS
* SE INCLUYE INDICADOR DE MODIFICADO
*--------------------------------------------------------*
OUTFIL FNAMES=OUT,
INCLUDE=(47,1,CH,EQ,C'D'),
OUTREC=(7,2,48,6,15,32)
Esta primera
ficha de control (CTL3) hace referencia al primer comando
SPLICE de las sentencias del TOOLIN anterior. Como podemos ver en su
codificación, en ella se hacen tres cosas con los datos de entrada.
-
OUTFIL: Se indica que la información se debe enviar
desde el fichero de entrada CONCAT al fichero de salida OUT.
-
INCLUDE: Se establece la Condición de Filtrado. En esta
sentencia se indica que debemos quedarnos únicamente con aquellos registros que
en la posición 47 tengan un campo alfanumérico de longitud 1 igual a ‘D’
(INCLUDE=(47,1,CH,EQ,C’D’)).
-
OUTREC: A continuación, transfiere del CONCAT al OUT la
siguiente información de los registros: el campo de longitud 2 que empieza en
la posición 7 (7,2), el campo de longitud 6 que empieza en la posición 48 (la
Población nueva) y el campo de longitud 32 que empieza en la posición 15
(15,32).
*--------------------------------------------------------*
* <<< FICHA JJRS1A08 >>>
* SACAMOS REGISTROS NO ENCONTRADOS PARA CUADRAR ENTRADA
*--------------------------------------------------------*
OUTFIL FNAMES=OUT1,
INCLUDE=(47,1,CH,EQ,C' '),
OUTREC=(7,40)
La segunda
ficha de control (CTL4) hace referencia al segundo comando SPLICE
de las sentencias de la TOOLIN especificada anteriormente. Al igual que en la
ficha CTL3 anterior, aquí también se realizan tres acciones sobre los registros
de entrada.
-
OUTFIL: Se indica que la información se debe enviar
desde el fichero de entrada CONCAT al fichero de salida OUT1.
-
INCLUDE: Se establece la Condición de Filtrado. Debemos
quedarnos únicamente con aquellos registros que en la posición 47 tengan un
campo alfanumérico de longitud 1 igual a un espacio en blanco
(INCLUDE=(47,1,CH,EQ,C’ ’)).
-
OUTREC: A continuación, transfiere del CONCAT al OUT1 el
campo de longitud 40 que empieza en la posición 7 (7,40).
Una vez especificados todos los puntos anteriores, ya se podrían ejecutar
sin problemas los dos pasos JCL comentados. Para personalizar estas fichas,
recordad que tendríamos que cambiar tanto los nombres de los ficheros de
entrada y de salida como la ubicación de los campos (de los registros) indicados
en las sentencias asociadas.
Ejecución de un JCL con SPLICE
Para ver el impacto que tendría la ejecución de un operador SPLICE,
podemos
ver cómo irían quedando los ficheros que se generen en los dos pasos JCL
anteriores. Recordemos que inicialmente partimos del fichero con la relación
clave antigua – clave nueva
SIST.UNLOAD.X0005X.POBL.KEYS y del fichero de poblaciones
SIST.UNLOAD.X0005X.POBL.MASTER.
Tras la ejecución del primer paso, se generan dos
ficheros de salida, con
denominación
SIST.JJ0105T1.X0060X.DDD.POBL.T1 y
SIST.JJ0105T2.X0060X.DDD.POBL.T2. El fichero POBL.T1 es
el fichero de relaciones entre claves (KEYS) al que, al final, se ha añadido un
literal ‘D’ y el código de la clave nueva de la población.
----+----1----+----2----+----3----+----4----+----5---
***************************** Top of Data ***********
000002-100002 D100002
000004-100004 D100004
000005-100005 D100005
000006-100006 D100006
000007-100007 D100007
000008-100008 D100008
000010-100010 D100010
**************************** Bottom of Data *********
El fichero POBL.T2 se corresponde con el fichero maestro de poblaciones
(MASTER), al que al final se le han añadido siete posiciones en blanco. Con
esto se consigue que POBL.T1 y POBL.T2 tengan la misma longitud de registro.
----+----1----+----2----+----3----+----4----+----5---
***************************** Top of Data ***********
000002B-000002-ALMERIA................ALM01300
000004B-000004-SANTANDER..............SAN01500
000005B-000005-TARRAGONA..............TAR01600
000006B-000006-BADAJOZ................BAD01700
000007B-000007-SALAMANCA..............SAL01800
000008B-000008-BURGOS.................BUR01900
000010B-000010-SEGOVIA................SEG01100
000011B-000011-TOLEDO.................TOL01000
000012B-000012-GRANADA................GRA00900
000014B-000014-CASTELLON..............CAS00700
000015A-000015-ZARAGOZA...............ZAR00600
000017A-000017-VALENCIA...............VAL00400
000018A-000018-BARCELONA..............BAR00300
000019B-000019-CIUDAD REAL............CRE00200
000020A-000020-MADRID.................MAD00100
**************************** Bottom of Data *********
A continuación,
el segundo paso del JCL usa como entrada los dos ficheros
que se acaban de generar (POBL.T1 y POBL.T2). La salida la constituyen el
fichero con los registros modificados
SIST.JJ0107S1.X0060X.DDD.POBL.MD y el fichero con el resto de registros que no ha
sufrido ningún cambio por parte de la utilidad ICETOOL
SIST.JJ0107S2.X0060X.DDD.POBL.RS.
En el dataset POBL.MD encontraremos los registros cuya clave de población
antigua ha sido sustituida por la nueva (según la relación establecida en el
fichero KEYS): 100002, 100004, 100005, etc…
----+----1----+----2----+----3----+----4
***************************** Top of Data *****
B-100002-ALMERIA................ALM01300
B-100004-SANTANDER..............SAN01500
B-100005-TARRAGONA..............TAR01600
B-100006-BADAJOZ................BAD01700
B-100007-SALAMANCA..............SAL01800
B-100008-BURGOS.................BUR01900
B-100010-SEGOVIA................SEG01100
**************************** Bottom of Data ***
Del mismo modo, en el fichero POBL.RS se almacenan los registros que no han
sufrido ninguna modificación. Y, por tanto, continúan estando identificados por
la clave de población antigua: 000011, 000012, 000014, etc…
----+----1----+----2----+----3----+----4
***************************** Top of Data *****
B-000011-TOLEDO.................TOL01000
B-000012-GRANADA................GRA00900
B-000014-CASTELLON..............CAS00700
A-000015-ZARAGOZA...............ZAR00600
A-000017-VALENCIA...............VAL00400
A-000018-BARCELONA..............BAR00300
B-000019-CIUDAD REAL............CRE00200
A-000020-MADRID.................MAD00100
**************************** Bottom of Data ***
Finalmente, si unimos en un fichero resultante los registros de los datasets
POBL.MD y POBL.RS, dispondremos del
nuevo maestro de poblaciones en el que ya
se han realizado los cambios de código de población requeridos.
----+----1----+----2----+----3----+----4
***************************** Top of Data *****
B-000011-TOLEDO.................TOL01000
B-000012-GRANADA................GRA00900
B-000014-CASTELLON..............CAS00700
A-000015-ZARAGOZA...............ZAR00600
A-000017-VALENCIA...............VAL00400
A-000018-BARCELONA..............BAR00300
B-000019-CIUDAD REAL............CRE00200
A-000020-MADRID.................MAD00100
B-100002-ALMERIA................ALM01300
B-100004-SANTANDER..............SAN01500
B-100005-TARRAGONA..............TAR01600
B-100006-BADAJOZ................BAD01700
B-100007-SALAMANCA..............SAL01800
B-100008-BURGOS.................BUR01900
B-100010-SEGOVIA................SEG01100
**************************** Bottom of Data ***
Como vemos, en el fichero anterior se pueden apreciar tanto códigos antiguos
de población (000011-TOLEDO, 000012-GRANADA, 000014-CASTELLON, etc…) como
códigos nuevos de población (100002-ALMERIA, 100004-SANTANDER,
100005-TARRAGONA, etc…). En un cliente real, a partir de ahora este sería el
nuevo fichero maestro de Poblaciones.
Conclusiones del cruce de ficheros
mediante SPLICE
La verdad es que, si no la hemos realizado nunca con anterioridad, la
ejecución de un cruce de ficheros mediante SPLICE nos puede parecer algo
compleja. Tengo que reconocer que, al menos a mí, así me lo pareció la primera
ocasión en la que tuve que enfrentarme con esta operación.
Sin embargo, os aseguro que, una vez que hayáis practicado con algunos
ejemplos, os daréis cuenta de que
el empleo del SPLICE del ICETOOL nos puede
ahorrar muchos pasos (y mucho trabajo) a la hora de elaborar un JCL. Pensad:
¿cuánto nos habría costado implementar el ejemplo (sencillo) del artículo sin
usar el SPLICE?
Siempre es complicado empezar a pelearse con una nueva
utilidad Host. Pero eso no
significa que lo más óptimo sea seguir trabajando con nuestros antiguos
operadores de toda la vida. Aunque nos pueda parecer tedioso a corto plazo,
el
empleo de las utilidades más potentes nos ahorrará mucho tiempo de codificación
a largo plazo. No lo olvidéis la próxima vez que os tengáis que enfrentar con
un SPLICE.
En este artículo hemos tratado de ver cómo se puede realizar un cruce de
ficheros mediante el operador SPLICE. Ciertamente, existen otros muchos comandos
relacionados con la utilidad ICETOOL, pero este es uno de los más utilizados.
De todas formas, en el Blog iremos viendo poco a poco cómo se deben implementar
las operativas JCL con aquellos operadores que considero como los más
importantes.
Pues nada, espero que lo comentado aquí os sirva para tener un poco más
claro cuáles son los pasos a seguir a la hora de elaborar un SPLICE. Si lo he
conseguido, con eso ya me puedo dar por satisfecho…
Saludos.