lunes, 20 de diciembre de 2010

SQL en JCL.

En este artículo vamos a ver una manera de hacer querys a través de un JCL:

//PASO001  EXEC IKJEFT01
//SYSTSIN  DD *
DSN SYSTEM(DB2D)
RUN PROGRAM(DSNTEP2) PLAN(DSNTEP2) -
    LIB('LIBRERIA.DE.TU.INSTALACION')
END
//SYSIN    DD *
Aquí escribiríamos la query
/*


Por ejemplo:
//SYSIN    DD *
  UPDATE TBPRU01
   SET CAMPO1 = 'SI'
   WHERE CLAVE = '01'
  ;
/*

Ó

//SYSIN    DD *
INSERT INTO TBPRU01
      (CAMPO1, CAMPO2, CAMPO3)
      VALUES
      ('01', '02', '03')
      ;
/*

Otra utilidad de las querys en JCLs podría ser hacer un inventario de todas las tablas de las aplicaciones, con sus campos, índices, etc. Lo que viene siendo la típica documentación que nadie quiere hacer, pero que con este JCL te llevará 1 minuto.

Para ello utilizaríamos las ya conocidas tablas del SYSIBM: SYSTABLES, SYSCOLUMS, SYSINDEXES, SYSKEYS.

Os dejo dos ejemplos: uno para obtener la información de los campos de cada tabla (con su formato) y otro para obtener la información de los índices de cada tabla (con los campos que los componen).

Inventario tablas:

//UNLOAD EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB2D)
RUN PROGRAM(DSNTIAUL) PLAN(DSNTIAUL) -
LIB('LIBRERIA.DE.TU.INSTALACION')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSPUNCH DD SYSOUT=*
//SYSREC00 DD DSN=XXXX.UNLOAD.TABLAS,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(CYL,(100,50),RLSE)
//SYSIN DD *
  SELECT B.TBNAME || ';' ||
        A.REMARKS || ';' ||
        B.NAME    || ';' ||
        CASE
         WHEN B.COLTYPE = 'INTEGER' THEN
           STRIP(B.COLTYPE,T,' ') || '(' ||
           STRIP(DIGITS(B.LENGTH),L,'0') || ')'
         WHEN B.COLTYPE = 'CHAR' THEN
           STRIP(B.COLTYPE,T,' ') || '(' ||
           STRIP(DIGITS(B.LENGTH),L,'0') || ')'
         WHEN B.COLTYPE = 'DECIMAL' THEN
           STRIP(B.COLTYPE,T,' ') || '(' ||
           STRIP(DIGITS(B.LENGTH),L,'0') || ',' ||
           STRIP(DIGITS(B.SCALE),L,'0') || ')'
        ELSE
           STRIP(B.COLTYPE,T,' ')
        END || ';' ||
        B.NULLS || ';' ||
        B.REMARKS
   FROM SYSIBM.SYSTABLES A
       ,SYSIBM.SYSCOLUMNS B
  WHERE A.NAME = B.TBNAME
    AND B.TBNAME LIKE 'TBPRU%'
    AND A.CREATOR = 'DB2O'
    AND B.CREATOR = 'DB2O'
 ORDER BY B.TBNAME,
          B.COLNO;
/*

Incluimos entre cada campo un separador ";" para poder guardar la información en un archivo .csv y poder abrirlo con el EXCEL.

El resultado una vez exportado a .csv sería:
Columna 1: Nombre físico
Columna 2: Nombre descriptivo
Columna 3: Campo
Columna 4: Tipo de dato
Columna 5: Acepta nulos
Columna 6: Descripción del campo

TBPRU01;TABLA NUMERO 1;CAMPO1;DECIMAL(9,2);N;ES EL CAMPO NUMERO 1


Inventario índices:

//UNLOAD EXEC PGM=IKJEFT01,DYNAMNBR=20
//SYSTSPRT DD SYSOUT=*
//SYSTSIN DD *
DSN SYSTEM(DB2D)
RUN PROGRAM(DSNTIAUL) PLAN(DSNTIAUL) -
LIB('LIBRERIA.DE.TU.INSTALACION')
//SYSPRINT DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//SYSPUNCH DD SYSOUT=*
//SYSREC00 DD DSN=XXXX.UNLOAD.INDICES,
//            DISP=(NEW,CATLG,DELETE),UNIT=SYSDA,
//            SPACE=(CYL,(100,50),RLSE)
//SYSIN DD *
SELECT A.TBNAME || ';' ||
     A.NAME || ';' ||
     B.COLNAME
FROM SYSIBM.SYSINDEXES A
    ,SYSIBM.SYSKEYS B
WHERE A.NAME = B.IXNAME
 AND A.TBNAME LIKE 'TBPRU%'
 AND A.CREATOR = 'DB2O'
 AND B.CREATOR = 'DB2O'
ORDER BY A.TBNAME
      ,A.NAME
      ,B.COLNO;
/*

El resultado una vez exportado a .csv sería:
Columna 1: Nombre físico tabla
Columna 2: Nombre índice
Columna 3: Campo

TBPRU01;INPRU011;CAMPO1


Y por supuesto podéis hacer las combinaciones de campos que os parezcan.

8 comentarios:

Anónimo dijo...

LIB('LIBRERIA.DE.TU.INSTALACION')

hola, como puedo saber su localizacion?

Tallian dijo...

La base sería la DSN*.RUNLIB.LOAD, pero según la instalación podría cambiar.
Un saludo!

Anónimo dijo...

Buenas tardes.
Me podria decir con que estructura de dato genera un UNLOAD las variables tipo integer. en el fichero de salida??
Agradezco su atención

Tallian dijo...

Buenas.
Las variables definidas como INTEGER equivalen a un S9(9) COMP.

Saludos.

Anónimo dijo...

Buen día.
Tengo una consulta. Cómo puedo hacer para por JCL hacer una consulta DB2 donde los campos de búsqueda son campos de un archivo de entrada y luego la selección de columnas que yo haga de la tabla salgan en otro archivo.

Desde ya, muchas gracias.
Saludos cordiales

Tallian dijo...

Puedes utilizar el lenguaje REXX. Aquí tienes un ejemplo de querys dinámicas:
http://consultoriocobol.blogspot.com/2010/12/utilidades-rexx-i-querys-dinamicas.html

Guillermo Cotera Correa dijo...

En un UNLOAD puedo dejar en mi archivo de salida los valores de variables INTEGER o SMALLINT en formato DISPLAY y no COMP.?
Si acaso se puede, como sería?
Gracias por el apoyo.
Saludos

Tallian dijo...

Hola Guillermo. Puedes indicar en la query de la unload que te lo convierta a char:
SELECT CHAR(CAMPO_INTEGER), CAMPO2, CAMPO3....