PDA

Ver la Versión Completa : [Sintaxis] Informar variable JCL con contenido de fichero.


RaulC
28 de marzo de 2018, 09:10
Buenos días,

Me va a llegar un fichero (por ejemplo F1), procedente de otra máquina, dicho fichero tiene un único registro con el nombre de otro fichero (F2).

Lo que quiero tratar el F2, y sobre todo poder validar si tiene contenido.

Con outrec he conseguido rellenar algunas fichas sysin, como las de LISTCAT con lo que puedo "preguntar" directamente por el fichero F2

ejemplo


//************************************************** ********
//SORT002 EXEC SORTD
//SORTIN DD DISP=SHR,DSN=F1
//SORTOUT DD DSN=F3.SYSIN,
// DISP=(,CATLG,DELETE),
// SPACE=(CYL,(1,1),RLSE),
// RECFM=FB,BLKSIZE=0,LRECL=35
//SYSIN DD *
SORT FIELDS=COPY
OUTREC FIELDS=(C' LISTCAT ENT(',1,20,C')')



//************************************************** *******************
//LISTCA01 EXEC PGM=IDCAMS
//SYSPRINT DD DUMMY
//SYSIN DD DSN=F3.SYSIN,DISP=SHR


Que es como si hubiera hecho esto.


//************************************************** *******************
//LISTCA01 EXEC PGM=IDCAMS
//SYSPRINT DD DUMMY
//SYSIN DD *
LISTCAT ENT(F2)


Lo malo es que este método no me funciona para otros procesos.

Por favor ¿hay alguna manera de informar o setear una variable jcl con el contenido del F1 (el F2)?

Saludos y gracias.

Kuk
28 de marzo de 2018, 10:52
RaulC, a lo mejor podrías intentar grabando el dato que te interesa a un miembro de PDS el cual luego introduces en tu JCL con INCLUDE:


// JCLLIB ORDER=MI.LIBRERIA.PDS
// INCLUDE MIEMBRO


Otra opción sería crear un JOB en dinámico (con un programa, o SORT OUTREC) y lanzarlo desde el JOB que lo ha creado con el siguiente step:


//STEPJCL EXEC PGM=IEBGENER,COND=(5,LT)
//SYSIN DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSUT2 DD SYSOUT=(A,INTRDR)
//SYSUT1 DD DSN=&&FICHJLC,DISP=(OLD,DELETE,DELETE)
/*


Lugo está el REXX que no conozco mucho, pero se puede hacer muchas cosas. Lo mismo lo más fácil es tirar por ahí.

RaulC
28 de marzo de 2018, 12:10
RaulC, a lo mejor podrías intentar grabando el dato que te interesa a un miembro de PDS el cual luego introduces en tu JCL con INCLUDE:


// JCLLIB ORDER=MI.LIBRERIA.PDS
// INCLUDE MIEMBRO


Otra opción sería crear un JOB en dinámico (con un programa, o SORT OUTREC) y lanzarlo desde el JOB que lo ha creado con el siguiente step:


//STEPJCL EXEC PGM=IEBGENER,COND=(5,LT)
//SYSIN DD DUMMY
//SYSPRINT DD SYSOUT=*
//SYSUT2 DD SYSOUT=(A,INTRDR)
//SYSUT1 DD DSN=&&FICHJLC,DISP=(OLD,DELETE,DELETE)
/*


Lugo está el REXX que no conozco mucho, pero se puede hacer muchas cosas. Lo mismo lo más fácil es tirar por ahí.

Estoy analizando las propuestas que me has comentado, aunque creo que están todas prohibidas en mi instalación.

He visto en algún ejemplo como se vuelcan fichas DD a variables JCL, como por ejemplo un sysprint. ¿Habría algún programa de utilidad o algo así para sacar el contenido de un fichero por sysout (u otra ficha DD)?

Voy a mirarlo en detalle, saludos y muchas gracias.

Kuk
29 de marzo de 2018, 13:49
RaulC, puedes hacer lo siguiente:

En tu OUTREC escribe esto:

REPRO INFILE(NOMBRE.FICHERO.OBTENIDO) -

Luego con IDCAMS copias el fichero el nombre del cual has escrito con OUTREC a uno con nombre definido por ti. Esto te permite reutilizarlo en DSN de los step siguientes:

Para copiar el fichero usa:


//S2002640 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//OUT DD DSN=FICHERO.DESTINO,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(10,10),RLSE),
// RECFM=FB,LRECL=80
//SYSIN DD DSN=FICHERO.OUTREC
// DD *
OUTDATASET(OUT)
END
/*


Ya cuentas qué tal.

RaulC
2 de abril de 2018, 17:11
RaulC, puedes hacer lo siguiente:

En tu OUTREC escribe esto:

REPRO INFILE(NOMBRE.FICHERO.OBTENIDO) -

Luego con IDCAMS copias el fichero el nombre del cual has escrito con OUTREC a uno con nombre definido por ti. Esto te permite reutilizarlo en DSN de los step siguientes:

Para copiar el fichero usa:


//S2002640 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//OUT DD DSN=FICHERO.DESTINO,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(10,10),RLSE),
// RECFM=FB,LRECL=80
//SYSIN DD DSN=FICHERO.OUTREC
// DD *
OUTDATASET(OUT)
END
/*


Ya cuentas qué tal.

Estoy teniendo el mismo problema que tuve yo en su momento antes de hacer esta consulta.

Se produce este error:
IDCAMS SYSTEM SERVICES TIM

REPRO INFILE(nombre.fichero.largo) -
IDC3201I CONSTANT 'nombre.fichero.largo' EXCEEDS LENGTH LIMIT
OUTDATASET(OUT)
IDC3202I ABOVE TEXT BYPASSED UNTIL NEXT COMMAND. CONDITION CODE IS 12

END

IDC0002I IDCAMS PROCESSING COMPLETE. MAXIMUM CONDITION CODE WAS 12

En el INFILE no puede estar el nombre completo de un fichero, o por lo menos no el nombre de un fichero que yo necesito, ya que como en toda instalación, necesito un nombre de fichero bastante largo, debido a la normativa sobre nomenclatura.

Realmente lo que necesito es comprobar si el fichero contenido (F2/nombre.fichero.largo en los ejemplos) tiene o no tiene datos.

En esta instalación se usa este método para ver si el fichero tiene datos o no.

//************************************************** ********
//************************************************** ********
//CONTROL2 EXEC PGM=IDCAMS
//FILETEST DD DSN=nombre.fichero.largo,DISP=SHR
//SYSIN DD *
PRINT CHARACTER -
COUNT(1) -
INFILE(FILETEST)
//*

Por eso intento meter el contenido del fichero en una variable, para poder hacer esto

//************************************************** ********
//************************************************** ********
//CONTROL2 EXEC PGM=IDCAMS
//FILETEST DD DSN=&&FICH2,DISP=SHR
//SYSIN DD *
PRINT CHARACTER -
COUNT(1) -
INFILE(FILETEST)
//*

Quería informar &&FICH2 con el contenido del fichero contenedor F1, y es lo que no consigo.

Con el LISTCAT no hay problema, porque el parámetro LISTCAT ENT sí acepta nombre largo.

Me quedo con la idea de intentar copiar el contenido del fichero contenido F2, en otro fichero, con un nombre fijo. A ver si lo consigo.

Muchas gracias.

---------- Post añadido : 17:11 ---------- Post anterior : 12:26 ----------

Al final me han dicho un programa que copia el contenido de los ficheros, cuyo nombre está en el fichero de entrada, al fichero de salida. Parece un travalenguas :)

Ya con eso puedo comprobar si tiene contenido o no, y ya trabajar con un fichero con nombre fijo.

Saludos y muchas gracias por la ayuda. Espero que esto pueda servirle a alguien, que pena que el programa/utilidad es de la instalación, no de IBM :(

Kuk
2 de abril de 2018, 21:58
En el INFILE no puede estar el nombre completo de un fichero, o por lo menos no el nombre de un fichero que yo necesito, ya que como en toda instalación, necesito un nombre de fichero bastante largo, debido a la normativa sobre nomenclatura.
No lo entiendo. Si el límite de la longitud del nombre de fichero para IDCAMS es el mismo que para z/OS, creo que eran 44 caracteres y también un máximo de 8 entre los puntos. O sea qeu si el SO lo acepta, lo debería aceptar también IDCAMS.

IBM Knowledge Center (https://www.ibm.com/support/knowledgecenter/zosbasics/com.ibm.zos.zjcl/zjclt_dstypesNnames.htm)


Qualified names: Multiple unqualified names joined by periods. Each qualifier is coded like an unqualified name; therefore, the name must contain a period after every 8 characters or fewer. The maximum length of a qualified data set name is:


44 characters, including periods.
For a generation data group, 35 characters, including periods.
For an output tape data set, 17 characters, including periods.




Realmente lo que necesito es comprobar si el fichero contenido (F2/nombre.fichero.largo en los ejemplos) tiene o no tiene datos.
Yo lo que había entendido es que el problema era acceder a ese fichero extrayendo su nombre desde el fichero Nº1.

Quería informar &&FICH2 con el contenido del fichero contenedor F1
Una variable que empieza por && es una variable de fichero temporal, es decir es el JES es que gestiona y asigna un nombre temporal de un dataset que se eliminará al finalizar el JOB.

Un variable normal empieza por un solo &.

Con el LISTCAT no hay problema, porque el parámetro LISTCAT ENT sí acepta nombre largo.
Lo veo muy raro. ¿Puedes ejecutar el step que te pasé poniendo un fichero de nombre más corto a mano y ver si hace lo que esperábamos? Para cerciorarnos de que el método funciona.

RaulC
4 de abril de 2018, 08:23
Ya tengo el problema resuelto, pero voy a intentar dejar esto lo mejor posible para el que se encuentre con este problema en el futuro.

No lo entiendo. Si el límite de la longitud del nombre de fichero para IDCAMS es el mismo que para z/OS, creo que eran 44 caracteres y también un máximo de 8 entre los puntos. O sea qeu si el SO lo acepta, lo debería aceptar también IDCAMS.

IBM Knowledge Center (https://www.ibm.com/support/knowledgecenter/zosbasics/com.ibm.zos.zjcl/zjclt_dstypesNnames.htm)


Pues da el error CONSTANT 'nombre.fichero.largo' EXCEEDS LENGTH LIMIT

En este ejemplo, el fichero es nombre.fichero.largo, que se referencia en la ficha FILETEST, y en la sentencia INFILE lo que espera es el nombre de la ficha DD del fichero sobre el que se va a trabajar ¿no?

//************************************************** ********
//CONTROL2 EXEC PGM=IDCAMS
//FILETEST DD DSN=nombre.fichero.largo,DISP=SHR
//SYSIN DD *
PRINT CHARACTER -
COUNT(1) -
INFILE(FILETEST)
//*




Yo lo que había entendido es que el problema era acceder a ese fichero extrayendo su nombre desde el fichero Nº1.


Sí, tienes razón. Lo que yo quería en primera instancia es comprobar si el fichero contenido(F2), cuyo nombre está en el fichero contenedor(F1), está vacío o no.

Para ello quería sacar el nombre del fichero F2 a una variable jcl, para poder meterlo en el INFILE del control de si está vacío y para todo lo que me pudiera hacer falta.

El tema es que al conseguir volcar el contenido del fichero F2 a un fichero cuyo nombre conozco, ya no me hace falta pasar el contenido del F1 a una variable JCL.


Una variable que empieza por && es una variable de fichero temporal, es decir es el JES es que gestiona y asigna un nombre temporal de un dataset que se eliminará al finalizar el JOB.

Un variable normal empieza por un solo &.


Estoy muy pez con lo de las variables JCL, me lo apunto, gracias.


Lo veo muy raro. ¿Puedes ejecutar el step que te pasé poniendo un fichero de nombre más corto a mano y ver si hace lo que esperábamos? Para cerciorarnos de que el método funciona.

Yo creo que es lo que te he comentado unas líneas antes, que en el INFILE lo que espera no es un nombre de fichero sino una ficha DD. Y LISTCAT ENT espera un nombre de fichero, con lo que ya tiene más sentido.

Aunque lo haya resuelto de otra manera, muchas gracias por tu ayuda, de verdad.

Kuk
4 de abril de 2018, 09:26
RaulC, desde hace ya varios años no trabajo con z/OS así que no puedo comprobar los ejemplos. El caso es que tenía un ejemplo que funciona al 100% que es el siguiente:


//S2002640 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//IN DD DISP=SHR,DSN=VSHRDV.P3ADALCE.DAABBCC
//SYSIN DD *
REPRO INFILE(IN) -
OUTDATASET(PREFIJO.NOMBRE.FICHERO)
END
/*


Y lo he querido adaptar. Lo que pasa es que acabo de verificar que efectivamente el subcomando INFILE espera el nombre DD y no DSN.

http://docweb.cns.ufl.edu/docs/d0071/ar09.html

Así que lo correcto sería reemplazar INFILE por INDATASET que como OUTDATASET espera DSN.

Resumiendo, el ejemplo correcto sería este: en el OUTREC pones


REPRO INDATASET(NOMBRE.FICHERO.OBTENIDO) -


Y el step de copiado no sería con OUTDATASET sino con OUTFILE para que apunte a la ficha DD:


//S2002640 EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//OUT DD DSN=FICHERO.DESTINO,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(10,10),RLSE),
// RECFM=FB,LRECL=80
//SYSIN DD DSN=FICHERO.OUTREC
// DD *
OUTFILE(OUT)
END
/*


Si lo pudieras comprobar estaría genial.

Y gracias por tus comentarios, siempre se agradece cuando la gente publica las soluciones que haya encontrado para que los demás puedan aprovecharlas.

Un saludo.

RaulC
4 de abril de 2018, 14:36
Ha funcionado perfectamente, y me gusta más que la solución que he usado yo, aunque cada una tiene sus pros y sus contras. Lo malo es que ya he implantado en producción esta mañana :mm:

Lo bueno es que tu solución sirve para todas las instalaciones host, porque tira de idcams y no de un programilla propio de mi instalación, como en mi caso.

Y gracias por tus comentarios, siempre se agradece cuando la gente publica las soluciones que haya encontrado para que los demás puedan aprovecharlas.

Es de bien nacidos, ser agradecidos.

Un saludo y gracias de nuevo.

Kuk
4 de abril de 2018, 20:47
Ha funcionado perfectamente
:bien: Me alegro. Queda confirmado entonces.

Yo siempre solía tirar de utilidades estándar precisamente por lo que dices. Así mis chanchullos me servían en cualquier instalación.

Siempre me han interesado este tipo de retos, me parece interesante :D

Un saludo.