Desarrollando en Cobol y Natural sobre Plataforma Mainframe

domingo, 27 de octubre de 2013

Area de Comunicaciones SQLCA

El Area de Comunicaciones de SQL (SQLCA) es una estructura empleada por el gestor de Base de Datos para retornar información sobre errores a un programa Cobol. Necesitará ser declarada en nuestro programa siempre que vayamos a hacer uso de sentencias SQL.

El área SQLCA es una estructura que contiene una serie de variables estándar que van a ser empleadas para que nuestro programa reciba información acerca de cómo se han ejecutado nuestras sentencias SQL sobre una tabla DB2.



Este area contiene las siguientes variables: SQLCAID, SQLCABC, SQLCODE, SQLERRM, SQLERRP, SQLERRD, SQLWARN y SQLSTATE. De ellas, la más importante es la SQLCODE, ya que este código de retorno nos indicará si el acceso a la tabla DB2 ha sido correcto o no.

* AREA SQLCA
 01 SQLCA SYNC.
    05 SQLCAID PIC X(8) VALUE "SQLCA   ".
    05 SQLCABC PIC S9(9) COMP-5 VALUE 136.
    05 SQLCODE PIC S9(9) COMP-5.
    05 SQLERRM.
    05 SQLERRP PIC X(8).
    05 SQLERRD OCCURS 6 TIMES PIC S9(9) COMP-5.
    05 SQLWARN.
        10 SQLWARN0 PIC X.
        10 SQLWARN1 PIC X.
        10 SQLWARN2 PIC X.
        10 SQLWARN3 PIC X.
        10 SQLWARN4 PIC X.
        10 SQLWARN5 PIC X.
        10 SQLWARN6 PIC X.
        10 SQLWARN7 PIC X.
        10 SQLWARN8 PIC X.
        10 SQLWARN9 PIC X.
        10 SQLWARNA PIC X.
    05 SQLSTATE PIC X(5).
* 

Para declarar este área en nuestro programa Cobol bastará con incluir una claúsula INCLUDE en la sección WORKING-STORAGE. Si no hacemos esta declaración, la compilación del programa fallará, ya que el gestor de BBDD no tendrá definida el área de comunicaciones.

******************************************************************
* WORKING-STORAGE SECTION                                        
******************************************************************
 WORKING-STORAGE SECTION.                                        
*                                                                
* AREA COMUNICACIONES SQL                                    
* -----------------------                                     
     EXEC SQL                                                    
       INCLUDE SQLCA                                             
     END-EXEC.                                                   
*              
                                                  

Como vemos, la claúsula es muy sencilla. Unicamente hay que escribir INCLUDE SQLCA entre las claúsulas EXEC SQL y END-EXEC de SQL. De esta forma, en nuestro programa ya estarán disponibles para su uso todas las variables existentes en la estructura SQLCA.

Y eso es todo. Si la cláusula INCLUDE SQLCA se define de la forma indicada en el fragmento de código de más arriba, entonces no deberíamos tener ningún problema con nuestro proceso de compilación (en lo que respecta al área de comunicaciones SQLCA, obviamente).

Tratamiento de la variable SQLCODE

Para finalizar, vamos a ver cuál es el tratamiento que se suele realizar sobre la variable SQLCODE (del área SQLCA) cada vez que realizamos un acceso a una tabla DB2. Este tratamiento se debe incluir a continuación de la sentencia que accede a la tabla.
 
En nuestro programa, tras el acceso a DB2, deberemos recoger el valor de la variable SQLCODE para saber si el acceso se ha realizado de forma correcta o no. Un ejemplo de cómo se haría esto es el siguiente (este código se añadiría tras la ejecución de una sentencia SELECT, por ejemplo).

*                                                        
*    VALIDACION DEL ACCESO DB2                           
*    -------------------------                           
     EVALUATE TRUE                                       
       WHEN SQLCODE = ZEROES                             
         DISPLAY 'ACCESO DB2 OK'                         
       WHEN SQLCODE = +100                               
         DISPLAY 'NO EXISTE REGISTRO'                    
       WHEN OTHER                   
         DISPLAY 'ERROR ACCESO DB2. SQLCODE: ' SQLCODE
         PERFORM 9980-GENERAR-ERROR                      
            THRU 9980-GENERAR-ERROR-EXIT                 
     END-EVALUATE

*                                         

Como vemos en el código, lo que se hace es validar si la variable SQLCODE es igual a algo de lo siguiente:

- Valor Cero: En ese caso, el acceso DB2 ha sido correcto y podemos continuar con nuestro proceso en el programa Cobol.

- Valor +100: aquí nos está indicando que no existe el registro buscado.

- Cualquier otro valor: significa que se ha producido un error en el acceso DB2. Por tanto, en nuestro programa deberemos indicar que la ejecución ha sido errónea.

Si establecemos así el tratamiento de SQLCODE tras cada acceso a una tabla DB2, entonces nuestro programa nos informará perfectamente de si dicho acceso se ha ejecutado correctamente o si, por contra, se ha producido un error.

Pues nada, esperamos que así hayan quedado aclaradas todas las dudas relacionadas con el área SQLCA.

Saludos.

sábado, 26 de octubre de 2013

Clausula DECLARE de una Tabla DB2

Siempre que queramos utilizar una tabla DB2 en un programa Cobol, previamente vamos a necesitar proceder a su declaración en la sección WORKING-STORAGE. Sin dicha declaración, el objeto nos dará un error en el proceso de compilación.



Para poder ejecutar una sentencia sobre una tabla DB2 necesitaremos en primer lugar realizar su declaración mediante la claúsula DECLARE. En ella se deberá especificar el nombre de la tabla DB2 y los nombres de los campos de la misma que van a ser empleados en el programa.

Aquí tenemos un ejemplo con un DECLARE de la tabla JJCLIEM0.

******************************************************************
* WORKING-STORAGE SECTION                                        
******************************************************************
 WORKING-STORAGE SECTION.                       

*                                       
* DECLARE JJCLIEM0                      
* ----------------                      
     EXEC SQL                           
       DECLARE JJCLIEM0 TABLE(          
         CLIENTE       NUMERIC(10),     
         NOMBRE        CHAR(20),        
         APELLIDO1     CHAR(20),        
         APELLIDO2     CHAR(20),        
         ALTURA        NUMERIC(3,2),    
         PESO          NUMERIC(3,2),    
         IMC           NUMERIC(3,2),    
         OBSERVACIONES CHAR(50),        
         FECHA         TIMESTAMP)       
     END-EXEC.                          
*
    
                                

Como vemos, la claúsula es bastante simple. Los pasos a seguir son los siguientes:

1º) Abrir un párrafo de SQL con las claúsulas EXEC SQL y END-EXEC. Entre ellas se declarará la información de la tabla DB2.

2º) Especificar, con DECLARE TABLE, el nombre de la tabla DB2.

3º) Finalmente, enumerar la lista de campos de la tabla DB2 (junto con su formato) que van a ser utilizados en el programa Cobol.

No hay mucho más que decir. El funcionamiento de esta claúsula es así de sencillo y no debería darnos ningún problema en compilación. Por supuesto, el único problema sería que se nos olvidara especificarla en nuestro programa.

Pues nada, otro día seguiremos comentando más cosas sobre las tablas DB2.

Saludos.

viernes, 25 de octubre de 2013

Sentencia SELECT para una Tabla DB2

La sentencia SELECT se emplea en los programas Cobol cuando únicamente queremos recuperar un registro de la tabla DB2 especificada. Esta sentencia extrae los campos que indiquemos y los carga en las variables que tengamos definidas para recibirlos.

El comando SELECT es el más sencillo que se puede usar cuando estamos trabajando con un programa Cobol DB2. No es necesario extraer listas de información ya que lo único que estamos buscando son los datos del registro sobre el que nos vamos a posicionar.



A continuación, mostramos un ejemplo de cómo sería el acceso a un registro de la tabla DB2 denominada JJCLIEM0 mediante la sentencia SELECT. 

*    CARGAMOS CLAVE CON CODIGO CLIENTE       
*    ---------------------------------       
     MOVE 0000000001 TO CLAVE-CLIENTE        
*                                            
*    OBTENCION DE INFORMACION DEL DB2 JJCLIEM0
*    -----------------------------------------
     EXEC SQL                                
       SELECT CLIENTE,                       
              NOMBRE,                        
              APELLIDO1,                     
              APELLIDO2,                     
              ALTURA,                        
              PESO,                          
              IMC,                           
              OBSERVACIONES,                 
              FECHA                          
         INTO                                 

              :S-CLIENTE,               
              :S-NOMBRE,                
              :S-APELLIDO1,             
              :S-APELLIDO2,             
              :S-ALTURA,                
              :S-PESO,                  
              :S-IMC,                   
              :S-OBSERVACIONES,         
              :S-FECHA                  
         FROM JJCLIEM0                  
         WHERE CLIENTE = :CLAVE-CLIENTE 
         ORDER BY CLIENTE               
     END-EXEC                            

*                                                         
*    VALIDACION DEL ACCESO DB2                            
*    -------------------------                            
     EVALUATE TRUE                                        
       WHEN SQLCODE = ZEROES                              
         DISPLAY 'ACCESO DB2 OK'                          
       WHEN SQLCODE = +100                                
         DISPLAY 'NO EXISTE REGISTRO'                     
       WHEN OTHER                                         
         MOVE SQLCODE TO SQLCODE-DIS                      
         DISPLAY 'ERROR ACCESO DB2. SQLCODE: ' SQLCODE-DIS
         PERFORM 9980-GENERAR-ERROR                       
            THRU 9980-GENERAR-ERROR-EXIT                  
     END-EVALUATE      
                                 

Los pasos que estamos siguiendo en este fragmento de código son los siguientes:

1º) Cargamos la clave por la que vamos a acceder a la tabla DB2 JJCLIEM0. En este caso, se trata del campo CLAVE-CLIENTE.

2º) A continuación, ejecutamos la sentencia SQL SELECT indicando los nombres de los campos que queremos extraer de la tabla JJCLIEM0. En este caso son CLIENTE, NOMBRE, APELLIDO1, APELLIDO2, ALTURA, PESO, IMC, OBSERVACIONES y FECHA.

3º) Con el comando INTO especificamos los nombres de las variables que van a recibir los datos extraidos de los campos de la tabla JJCLIEM0.

4º) Finalmente, tras la ejecución de la sentencia SELECT, evaluamos el resultado del acceso mediante el parámetro SQLCODE. Si es cero, entonces la operación de acceso ha sido correcta.

Y esos son, en resumen, los pasos que habría que seguir para implementar correctamente una sentencia SELECT en nuestro programa Cobol DB2. Si lo codificamos tal y como se indica en el ejemplo, no deberíamos tener problema alguno posteriormente en el proceso de compilación.

Pues nada, como siempre, esperamos que la información que os proporcionamos os sirva de ayuda para resolver las dudas que tengáis a la hora de enfrentaros con la programación Cobol DB2.

Saludos.

jueves, 24 de octubre de 2013

Bind de un programa Cobol DB2

Hace unos días vimos un ejemplo de cómo debía ser un JCL de Compilación de un programa Cobol DB2. Una vez generados el Módulo y el DBRM con dicho compilador, dijimos que aún quedaba un paso adicional antes de tener disponible el Ejecutable de nuestro programa. Se trata del paso de Bind.

Una vez que se ha generado el DBRM de nuestro fuente, dicho objeto DBRM no tiene información acerca de cómo acceder a los datos requeridos de las tablas DB2. Esto se consigue con el proceso de Bind, que enlaza el DBRM con un Plan. Este Plan contiene la información acerca de los recursos DB2 requeridos y sus caminos de acceso.

Para ello, al lanzar el Bind tendremos que especificar tanto el nombre del LOAD MODULE (Módulo Objeto) como el nombre del PLAN asociado.

El JCL de Bind quedaría del siguiente modo, para un programa con nombre "JJ0004CB" que está asociado a un Plan denominado "JJ00".

//JJRUN1CL JOB 102,'BIND Y RUN COBOL DB2',NOTIFY=&SYSUID,       
//  MSGCLASS=Q,CLASS=A,MSGLEVEL=(1,1),REGION=0M,TIME=(0,7)      
//*                                                             
//JOBLIB    DD DSN=DSN910.DB9G.SDSNEXIT,DISP=SHR                
//          DD DSN=DSN910.SDSNLOAD,DISP=SHR                     
//**************************************************************
//* BIND                                                        
//**************************************************************
//BIND           EXEC PGM=IKJEFT01,DYNAMNBR=20,COND=(4,LT)      
//DBRMLIB   DD DSN=LIBPR.DBRM.JJ00,DISP=SHR                     
//SYSTSPRT  DD SYSOUT=*                                         
//SYSPRINT  DD SYSOUT=*                                         
//SYSUDUMP  DD SYSOUT=*                                         
//SYSOUT    DD SYSOUT=*                                         
//SYSTSIN   DD *                                                
  DSN SYSTEM(DB9G)                                              
  BIND PLAN(JJ00) MEMBER(JJ0004CB) -                              

        ACT(REP) ISO(CS) ENCODING(EBCDIC)                         
  END                                                             
/*                                                                
//*****************************************************************
//* RUN PGM                                                       
//*****************************************************************
//RUNPGM   EXEC PGM=IKJEFT01,DYNAMNBR=20 COND=(4,LT)              
//STEPLIB  DD DSN=DSN910.SDSNLOAD,DISP=SHR                        
//SYSTSPRT DD SYSOUT=*                                            
//SYSPRINT DD SYSOUT=*                                            
//SYSUDUMP DD SYSOUT=*                                            
//SYSOUT   DD SYSOUT=*                                            
//SYSTSIN DD *                                                    
  DSN SYSTEM(DB9G)                                                
  RUN PROGRAM(JJ0004CB) PLAN(JJ00) LIB('LIBPR.MODULOS.JJ01')      
  END                                                             
//*
      
                                                         

En este JCL hemos incluido dos pasos: el primero es el propio Bind y el segundo es el lanzamiento de la ejecución (RUN) del programa.

1º) Bind: hay que resolver la librería DBRM. Y para su lanzamiento hay que indicar el nombre del programa y el nombre del Plan asociado.

2º) Run: hay que indicar la librería STEPLIB. Para su lanzamiento habría que especificar el nombre del programa, el nombre del Plan asociado y la librería donde se encuentra el objeto Módulo.

Tras ejecutar este JCL, la salida del mismo debería mostrar la información extraída por la ejecución del programa especificado. En el caso de nuestro ejemplo, programa JJ0004CB, se mostraría la siguiente salida.


Pues nada, esperamos que lo indicado os sirva de ayuda a la hora de ejecutar la Compilación y el Bind de un programa Cobol con DB2.

Saludos.

miércoles, 23 de octubre de 2013

Compilador de Cobol DB2 sin Prelinkedit

Cuando queramos compilar un programa Cobol que contenga invocaciones a DB2 no nos bastará con usar el Compilador estándar de Cobol, que tiene únicamente los pasos de Compilación y de Linkedit. Por contra, habremos de incluir, además, un paso de Precompilación y, opcionalmente, otro paso de Prelinkedit.



En este post vamos a indicar cómo debería ser nuestro JCL de Compilación Cobol DB2 con los pasos de Precompilación, Compilación y Linkedit. Otro día indicaremos cómo quedaría el JCL si quisiésemos incluir el paso de Prelinkedit.

A continuación, mostramos cómo sería el JCL completo para el fuente "JJ0004CB".

//JJCOM8CL JOB 102,'COMPILADOR COBOL DB2',NOTIFY=&SYSUID,      
//  MSGCLASS=Q,CLASS=A,MSGLEVEL=(1,1),REGION=0M,TIME=(0,7)     
//**************************************************************
//* SYSLIB  ES LA LIB. DE COPYS                                
//* SYSIN   ES LA LIB. DE PROGRAMAS FUENTES                    
//* SYSLMOD ES LA LIB. DE PROGRAMAS OBJETOS O EJECUTABLES      
//**************************************************************
//STEP0          EXEC DSNHICOB                                  
//* 1 - LIBRERIAS DEL PRECOMPILADOR DSNHPC                     
//* --------------------------------------                     
//PC.SYSIN       DD DSN=LIBPR.FUENTES.JJ00(JJ0004CB),DISP=SHR  
//PC.SYSLIB      DD DSN=CEE.SCEELKED,DISP=SHR                  
//PC.DBRMLIB     DD DSN=LIBPR.DBRM.JJ00(JJ0004CB),DISP=SHR     
//* 2 - LIBRERIAS DEL COMPILADOR IGYCRCTL                      
//* -------------------------------------                      
//COB.STEPLIB  DD DSN=IGY410.SIGYCOMP,DISP=SHR                   

//* 3 - LIBRERIAS DE LINKED IEWL                               
//* ----------------------------                               
//LKED.SYSLMOD   DD DSN=LIBPR.MODULOS.JJ01(JJ0004CB),DISP=SHR  
//LKED.SYSLIB    DD DSN=CEE.SCEELKED,DISP=SHR                  
//               DD DSN=LIBPR.COPYS.JJ00,DISP=SHR              
//               DD DSN=DSN910.SDSNLOAD,DISP=SHR                
//* 4 - INCLUIR DB2 INTERFACE FUNCTION

//* ----------------------------------    
//LKED.SYSIN     DD *                                          
  INCLUDE SYSLIB(DSNELI)                                       
//
       
                                          
          

Como vemos, contiene los siguientes pasos:

1º) Precompilación: aquí hay que incluir las librerías SYSIN, SYSLIB y DBRMLIB.

2º) Compilación: únicamente se precisa resolver la librería STEPLIB.

3º) Linkedit: hay que especificar SYSLMOD y SYSLIB.

4º) DB2 Interface Function: finalmente, hay que añadir un INCLUDE con el objeto DSNELI.

Una vez ejecutado este JCL de Compilación, ya tendremos generados tanto el objeto LOAD MODULE como el objeto DBRM. Para enlazar ambos y crear nuestro Ejecutable tendremos que lanzar el proceso de BIND sobre ellos.

Otro día, en otro post, os pondremos un ejemplo de cómo quedaría un JCL con el paso de BIND de un programa Cobol DB2.

Y nada más. Esperamos que la cosa haya quedado bastante clara con el ejemplo indicado.


Saludos.

Related Posts Plugin for WordPress, Blogger...