lunes, 21 de febrero de 2011

Ejemplo 2: leer de SYSIN y escribir en fichero.

En este ejemplo vamos a ejecutar un programa SIN DB2, que recoge información de la SYSIN del JCL del mismo modo que vimos en el ejemplo 1. La diferencia estará en que en esta ocasión vamos a escribir la información en un fichero en lugar de en la SYSOUT.

JCL:

//******************************************************
//**************************** BORRADO *****************
//BORRADO EXEC PGM=IDCAMS
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
DEL FICHERO.CON.NOMBRES
SET MAXCC = 0
//******************************************************
//*********** EJECUCION DEL PROGRAMA PRUEBA2 ***********
//PROG1 EXEC PGM=PRUEBA2
//SYSOUT  DD SYSOUT=*
//FICHERO DD DSN=FICHERO.CON.NOMBRES,
//           DISP=(NEW, CATLG, DELETE),

//           SPACE=(TRK,(50,10))
//SYSIN DD *
JOSE LOPEZ VAZQUEZ HUGO CASILLAS DIAZ JAVIER CARBONERO PACO GONZALEZ
/*


En este ejemplo añadimos un nuevo paso, el IDCAMS. Este programa sirve para borrar ficheros que se crean a lo largo del JCL. En nuestro caso borrará el fichero que se va a crear en el programa. Así podremos ejecutarlo tantas veces como queramos sin generar el mismo fichero una y otra vez.
El paso de ejecución del programa PRUEBA2 es similar al del ejemplo 1, sólo le hemos añadido la definición del fichero de salida "FICHERO".

PROGRAMA:

 IDENTIFICATION DIVISION.
 PROGRAM-ID. PRUEBA2.
*==========================================================*
*     PROGRAMA QUE LEE DE SYSIN Y ESCRIBE EN FICHERO
*==========================================================*
*
 ENVIRONMENT DIVISION.
*
 CONFIGURATION SECTION.
*
 SPECIAL-NAMES.
     DECIMAL-POINT IS COMMA.
*
 INPUT-OUTPUT SECTION.
*
 FILE-CONTROL.
*
 SELECT FICHERO ASSIGN TO FICHERO
                STATUS IS FS-FICHERO.
*
 DATA DIVISION.
*
 FILE SECTION.
*
* Fichero de salida de longitud fija (F) igual a 20.
 FD FICHERO RECORDING MODE IS F
            BLOCK CONTAINS 0 RECORDS
            RECORD CONTAINS 20 CHARACTERS.
 01 REG-FICHERO PIC X(20).
*
 WORKING-STORAGE SECTION.
* FILE STATUS
 01 FS-STATUS.
    05 FS-FICHERO        PIC X(2).
       88 FS-FICHERO-OK          VALUE '00'.
*
* VARIABLES
 01 WI-INDICE            PIC 9(4) COMP.
 01 WX-SYSIN             PIC X(80).
 01 WX-TABLA-NOMBRES.
    05 WX-NOMBRE         PIC X(20) OCCURS 4 TIMES.
 01 WX-REGISTRO-SALIDA   PIC X(20).
*
************************************************************
 PROCEDURE DIVISION.
************************************************************
*  |     0000 - PRINCIPAL
*--|------------------+----------><----------+-------------*
* 1| EJECUTA EL INICIO DEL PROGRAMA
* 2| EJECUTA EL PROCESO DEL PROGRAMA
* 3| EJECUTA EL FINAL DEL PROGRAMA
************************************************************
 00000-PRINCIPAL.
*
     PERFORM 10000-INICIO
*
     PERFORM 20000-PROCESO
*
     PERFORM 30000-FINAL
     .
************************************************************
*  |     10000 - INICIO
*--|------------+----------><----------+-------------------*
*  | SE REALIZA EL TRATAMIENTO DE INICIO:
* 1| Inicialización de Áreas de Trabajo
* 2| Primera lectura de SYSIN
************************************************************
 10000-INICIO.
*
     INITIALIZE WX-SYSIN

                WX-REGISTRO-SALIDA
                WX-TABLA-NOMBRES

     ACCEPT WX-SYSIN FROM SYSIN

     PERFORM 11000-ABRIR-FICHERO
     .
*
************************************************************
*               11000 - ABRIR FICHEROS
*--|------------------+----------><----------+-------------*
* Abrimos el fichero de salida
************************************************************
 11000-ABRIR-FICHERO.
*
     OPEN OUTPUT FICHERO
*
     IF NOT FS-FICHERO-OK
        DISPLAY 'ERROR EN OPEN DEL FICHERO:'FS-FICHERO
     END-IF
     .
*
************************************************************
*  |     20000 - PROCESO
*--|------------------+----------><------------------------*
*  | SE REALIZA EL TRATAMIENTO DE LOS DATOS:
* 1| Realiza el tratamiento de cada registro recuperado de
* la SYSIN
************************************************************
 20000-PROCESO.
*
     MOVE WX-SYSIN TO WX-TABLA-NOMBRES
     MOVE 1        TO WI-INDICE

     PERFORM UNTIL WI-INDICE GREATER 4
        PERFORM 21000-INFORMAR-REGISTRO
        PERFORM 22000-ESCRIBIR-FICHERO

        ADD 1 TO WI-INDICE
     END-PERFORM

     .
*
************************************************************
*               21000 - INFORMAR REGISTRO
*--|------------------+----------><----------+-------------*
* MOVEMOS LA INFORMACION DESDE NUESTRA TABLA INTERNA A LA
* VARIABLE WX-REGISTRO-SALIDA
************************************************************
 21000-INFORMAR-REGISTRO.
*
     MOVE WX-NOMBRE(WI-INDICE) TO WX-REGISTRO-SALIDA

     .
*
************************************************************
*               22000 - ESCRIBIR FICHERO
*--|------------------+----------><----------+-------------*
* ESCRIBIMOS EN EL FICHERO DE SALIDA LA INFORMACION GUARDADA
* WX-REGISTRO-SALIDA
************************************************************
 22000-ESCRIBIR-FICHERO.
*
     WRITE REG-FICHERO FROM WX-REGISTRO-SALIDA

     IF NOT FS-FICHERO-OK
        DISPLAY 'ERROR EN WRITE DEL FICHERO:'FS-FICHERO
     END-IF

     .
*
************************************************************
*  |     30000 - FINAL
*--|------------------+----------><----------+-------------*
*  | FINALIZA LA EJECUCION DEL PROGRAMA
************************************************************
 30000-FINAL.
*
     PERFORM 31000-CERRAR-FICHERO

     STOP RUN
     .
*
************************************************************
*  |     31000 - CERRAR FICHERO
*--|------------------+----------><----------+-------------*
*  | CERRAMOS EL FICHERO DE SALIDA
************************************************************
 31000-CERRAR-FICHERO.
*
     CLOSE FICHERO

     IF NOT FS-FICHERO-OK
        DISPLAY 'ERROR EN CLOSE DEL FICHERO:'FS-FICHERO
     END-IF
     .


En el programa podemos ver las siguientes divisiones/secciones:
IDENTIFICATION DIVISION: existirá siempre.
ENVIRONMENT DIVISION: existirá siempre.
  CONFIGURATION SECTION: existirá siempre.
  INPUT-OUTPUT SECTION: en este ejemplo existirá porque utilizamos un fichero de salida.
DATA DIVISION: existirá siempre.
  FILE SECTION: en este ejemplo existirá pues utilizamos un fichero de salida.
  WORKING-STORAGE SECTION: exisitirá siempre.
  En este caso no exisistirá la LINKAGE SECTION pues el programa no se comunica con otros programas.
PROCEDURE DIVISION: exisitirá siempre.


En el programa podemos ver las siguientes sentencias:
PERFORM: llamada a párrafo
INITIALIZE: para inicializar variable
ACCEPT: esta sentencia recoge la información del campo indicado en el "FROM". En este caso recoge la información almacenada en "SYSIN"; la que nosotros hemos introducido en el JCL.
OPEN: "Abre" los ficheros del programa. Lo acompañaremos de "INPUT" para los ficheros de entrada y "OUTPUT" para los ficheros de salida.
DISPLAY: escribe el contenido del campo indicado en la SYSOUT del JCL.
MOVE/TO: movemos la información de un campo a otro
PERFORM UNTIL: bucle
ADD:Operador de adición (suma)
WRITE: Escribe la información indicada en el "FROM" en el fichero indicado.
STOP RUN: sentencia de finalización de ejecución.
CLOSE: "Cierra" los ficheros del programa.

Descripción del programa:
En el párrafo de inicio, inicializamos las variables que utilizaremos a lo largo del programa:
WX-SYSIN: donde guardaremos posteriormente mediante un ACCEPT la información que hemos escrito en la SYSIN del JCL.
WX-TABLA-NOMBRES: donde moveremos la información de la SYSIN para dividirla en los diferentes nombres.
WX-REGISTRO-SALIDA: donde guardaremos la información que vamos a escribir en el fichero de salida.
Abriremos el fichero de salida (OPEN OUTPUT) y controlaremos el file-status. Si todo va bien el código del file-status valdrá '00'. Podéis ver la lista de los file-status más comunes.

En el párrafo de proceso, informamos la tabla interna WX-TABLA-NOMBRES, donde el campo WX-NOMBRES se repetirá 4 veces (occurs 4 times). Recordad que el tratamiento de las tablas internas está explicado en detalle en el ejemplo 1.
Montaremos un bucle para escribir cada uno de los nombres guardados en la tabla interna en el fichero de salida.
Informaremos la variable WX-REGISTRO-SALIDA con cada uno de los nombres de la tabla.
Escribiremos el fichero de salida. Para ellos indicaremos a continuación del WRITE la variable definida en la FILE-SECTION, y a continuación del FROM la variable donde tenemos guardada la información que queremos escribir.
Controlaremos el file-status.

Nota: es importante controlar el FILE-STATUS en los accesos a ficheros (OPEN, READ, WRITE, CLOSE...) para, en caso de fallo en la ejecución, tener información sobre la causa del error.

2 comentarios:

Anónimo dijo...

Hola, tengo una consulta.
Cuando escribe el fichero de salida ¿no podría controlarse el File Status como se hace al abrir el fichero? Es decir, con un IF NOT. No entiendo por qué se inicializa el registro de salida.
Gracias.

Tallian dijo...

Ciertamente en este ejemplo no es necesario inicializar el registro de salida porque solo vamos a escribir una vez.

En el ejemplo 3 cobra sentido.

Lo modifico para evitar confusiones.

Gracias!!!