Desarrollando en Cobol y Natural sobre Plataforma Mainframe
Mostrando entradas con la etiqueta SQL. Mostrar todas las entradas
Mostrando entradas con la etiqueta SQL. Mostrar todas las entradas

lunes, 13 de junio de 2016

Ver campos Hexadecimales en QMF con HEX (y 2)

Hace algunas semanas comenzamos a revisar los pasos que hay que seguir para ver campos hexadecimales en QMF mediante la cláusula HEX. Aunque en su momento ya estuvimos viendo cómo hacer esto mismo con la ventana FORM, nunca viene mal tener formas alternativas de hacer esta decodificación. Recordad que, si no realizamos ningún tratamiento sobre los datos, el informe de QMF nos mostrará los campos hexadecimales en un formato no legible

En la primera parte del post ya estuvimos viendo los primeros puntos del procedimiento (acceder al post Ver campos Hexadecimales en QMF con HEX - 1). Hoy nos centraremos en finalizar el examen de los pasos a seguir, de manera que completemos la visión global de este método de decodificación. Si nos dedicamos al análisis de incidencias, esta alternativa nos resultará muy útil. Vamos con ello.

4º) Una vez codificada la query anterior, la ejecutamos desde QMF. De esta forma obtendremos el informe de la tabla DB2 con el listado de registros extraidos.







Como vemos en la imagen, ahora el informe ya no muestra datos hexadecimales. Por un lado, la cláusula HEX ha hecho que se nos presente la información en formato alfanumérico. Por otro lado, los comandos SUBSTR que hemos incluido nos han permitido dividir el campo hexadecimal en cada uno de los subelementos con significación propia.

                                           SITU    LOCA
ORCI         VERSIO  TJALON  SITU    LOCA   1       1 
-----------  ------  ------  ------  ----  ------  ----
00662341105  000     C2      990003  290   900001  002
01458141303  000     C2      990003  839   900001  002
02180781101  002     C2      990003  290   900001  002
03038681303  000     C2      990003  290   900001  002
03422721304  000     E3      990002  031   900001  002
03560631304  000     C2      990003  290   900001  002
03560631304  000     C2      990003  290   900001  002
03560631304  000     C2      990003  290   900001  002
03560631304  000     C2      990003  290   900001  002
03560631304  000     C2      990003  290   900001  002
03560631304  000     C2      990003  290   900001  002
03723801304  000     D2      990003  788   900001  002


Si nos centramos en un único registro, podremos apreciar con mayor claridad lo cómoda que resulta ahora la lectura de la información del antiguo campo hexadecimal. Parece que ha merecido la pena dedicar algo de tiempo a la codificación.

                                           SITU    LOCA
ORCI         VERSIO  TJALON  SITU    LOCA   1       1 
-----------  ------  ------  ------  ----  ------  ----
03560631304  000     C2      990003  290   900001  002


Fijaos que estos son los mismos datos que vimos en la alternativa anterior de decodificación. La única diferencia es que de este modo  son más fáciles de leer.

03560631304  000     C2      990003  290   900001  002

Creo que ahora ya entenderéis por qué os digo que, de esta forma, os va a resultar mucho más fácil analizar los registros DB2. Si os dedicáis al análisis de incidencias, como es el caso de muchos programadores Cobol, a largo plazo esto supondrá un gran ahorro de tiempo. Y si ahora no os dedicáis a ello, bueno, guardáos este post por ahí, porque en el mundo Host tarde o temprano tendréis que resolver incidencias...



¿Cuál de las dos alternativas es mejor?


Una vez vistas estas dos formas de traducir campos hexadecimales en QMF, nos podríamos hacer la pregunta: ¿cuál de las dos alternativas es mejor? Realmente no podemos decir que uno de los procedimentos sea mejor que el otro, cada uno tiene su aplicación específica. Va a ser cuestión nuestra decidir cuál de los dos métodos es el adecuado para la situación con la que nos estemos enfrentando.

-------------------------------------------------------------------------------------------------------------------------------
Tip: Aquí podéis ver diversas herramientas clave del entorno Host
-------------------------------------------------------------------------------------------------------------------------------

Por ejemplo, si únicamente queremos hacer una consulta rápida de un dato y no vamos a acceder a esta tabla DB2 nunca más, entonces la alternativa 1 será la mejor. Para un escenario de este tipo no tiene sentido invertir demasiado tiempo en la traducción del campo hexadecimal. Aquí va a primar la rapidez frente a la comodidad, ya que no se va a tratar de una extracción periódica.

En cambio, si lo que nos están pidiendo es algo que vamos a tener que consultar una vez cada semana (o cada mes), entonces yo me plantearía acometer la alternativa 2. En este caso sí que va a merecer la pena invertir un poco más de trabajo en desarrollar la query para mostrar los subcampos hexadecimales de la forma más legible posible. Posteriormente, eso nos supondrá un gran ahorro de tiempo a la hora de revisar los datos extraídos de forma periódica.


En cualquier caso, la idea del post es que dispongáis de un par de opciones para traducir los campos hexadecimales con los que os vayáis encontrando en vuestro día a día. En realidad, seleccionar una alternativa u otra es un problema secundario una vez que ya somos conscientes de que la información hexadecimal no es un obstáculo insalvable para nosotros. En última instancia, elegid la solución que os resulte más óptima en vuestra instalación.

Pues nada, eso es todo por lo que respecta a la visualización de campos hexadecimales en QMF. Espero que lo comentado en el texto os ayude a superar este tipo de problemas de formato. Cualquier duda que tengáis, ya sabéis, me la dejáis aquí abajo en los comentarios...

Saludos.

lunes, 6 de junio de 2016

Ver campos Hexadecimales en QMF con HEX (1)

Hace algunas semanas estuvimos viendo la forma de decodificar campos hexadecimales mediante la clásusula X de la ventana FORM de QMF. Como ya os podéis imaginar, se trata de un método para salir del paso, así que hoy examinaremos otra forma de visualizar datos hexadecimales de forma más amigable. Os adelanto que tiene que ver con la implementación de queries mediante los comandos HEX y SUBSTR.

En su momento ya estuvimos viendo un método rápido para decodificar información hexadecimal (ver post Ver campos Hexadecimales en QMF con FORM - y 2). Dicho método es muy útil para cuando tenemos que hacer una consulta puntual y no disponemos de mucho tiempo. Sin embargo, la alternativa que vamos a revisar hoy estaría más orientada a escenarios de consulta que se nos plantean periódicamente. El uso de HEX nos va a requerir algo más de trabajo de codificación, pero luego nos servirá para ahorrar tiempo a la hora de leer la información.

Visualizar Hexadecimales mediante SELECT con HEX


Otra de las alternativas para visualizar campos hexadecimales en QMF es usar una query SELECT con la cláusula HEX. Esta solución es algo más compleja de implementar que la anterior (X en ventana FORM). Pero, a cambio, los resultados mostrados serán mucho más cómodos de leer, lo que nos permitirá analizar el contenido con mucha mayor rapidez.

A continuación, vamos a ver los pasos que habría que seguir para poner en práctica esta alternativa de traducción de datos. Recordemos que la query de partida era la siguiente.

SELECT INCI_CO_ORIGEN, INCI_IN_ORIGEN,INCI_TS_TIMEST
FROM A0DB22.A0INCIT0
WHERE  SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN
             ('900001','900002','900003',
              '900005','900006','900007','900008')

Los pasos 1º) y 2º) serían los mismos que en el método anterior, ya que lo único que hacíamos en ellos era mostrar cómo era la extracción inicial de datos sin decodificar. Continuamos, pues, con los siguientes puntos.

3º) Teniendo en cuenta que, en nuestro ejemplo, el dato Hexadecimal es el denominado INCI_CO_ORIGEN, lo que vamos a hacer es aplicar la cláusula HEX a este campo del registro. Esto se conseguiría fácilmente especificando esta declaración SELECT.

SELECT HEX(INCI_CO_ORIGEN)

Adicionalmente, en nuestro caso el campo INCI_CO_ORIGEN en realidad está compuesto por varios subcampos. Por ello, vamos a usar el comando SUBSTR para establecer un nombre específico para cada uno de dichos subelementos. De esta forma, conseguiremos que el informe extraído tenga un formato mucho más legible.

SELECT SUBSTR(HEX(INCI_CO_ORIGEN),1,11) AS ORCI,
       SUBSTR(HEX(INCI_CO_ORIGEN),13,3) AS VERSIO,
       SUBSTR(HEX(INCI_CO_ORIGEN),17,2) AS TJALON,
       SUBSTR(HEX(INCI_CO_ORIGEN),22,6) AS SITU,
       SUBSTR(HEX(INCI_CO_ORIGEN),29,3) AS LOCA,
       SUBSTR(HEX(INCI_CO_ORIGEN),34,6) AS SITU_1,
       SUBSTR(HEX(INCI_CO_ORIGEN),41,3) AS LOCA_1

Una vez explicado lo anterior, ya podemos codificar la query entera. Lo que haríamos es tomar el código inicial y aplicarle las cláusulas indicadas HEX y SUBSTR.
 


Como vemos en la imagen anterior, la query SQL se corresponde con la original, pero ahora hemos incorporado el traductor hexadecimal HEX y el comando SUBSTR. Con estos cambios ya conseguiríamos el objetivo inicialmente buscado de decodificar los campos hexadecimales.

SELECT SUBSTR(HEX(INCI_CO_ORIGEN),1,11) AS ORCI,
       SUBSTR(HEX(INCI_CO_ORIGEN),13,3) AS VERSIO,
       SUBSTR(HEX(INCI_CO_ORIGEN),17,2) AS TJALON,
       SUBSTR(HEX(INCI_CO_ORIGEN),22,6) AS SITU,
       SUBSTR(HEX(INCI_CO_ORIGEN),29,3) AS LOCA,
       SUBSTR(HEX(INCI_CO_ORIGEN),34,6) AS SITU_1,
       SUBSTR(HEX(INCI_CO_ORIGEN),41,3) AS LOCA_1,
       INCI_IN_ORIGEN, INCI_TS_TIMEST
FROM A0DB22.A0INCIT0
WHERE  SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN
                     ('900001','900002','900003','900005',
                      '900006','900007','900008')

Es cierto que ahora la query queda un poco más compleja que el SQL de partida, pero es el precio que hay que pagar por obtener un informe más cómodo de leer. La codificación requiere un poco más de dedicación por nuestra parte, pero luego ganaremos mucho tiempo a la hora de realizar el análisis de los datos obtenidos. Si tenéis que descubrir la causa de una incidencia, creo que agradeceréis hacer las cosas siguiendo este procedimiento.

-------------------------------------------------------------------------------------------------------------------------------
Tip: Aquí podéis ver cómo se pueden almacenar queries en QMF
-------------------------------------------------------------------------------------------------------------------------------

El próximo día, en un nuevo post, continuaremos viendo los pasos que hay que seguir para visualizar los campos hexadecimales en QMF mediante la cláusula HEX. Mientras tanto, si tenéis mucha necesidad de decodificar información que se encuentre en dicho formato, podéis recurrir al artículo que escribimos en su día hablando de la ventana FORM. En cualqueir caso, recordad que siempre es conveniente disponer de varias alternativas para poder ejecutar una misma acción.

Pues nada, eso es todo por ahora. Como ya sabéis, quedáis invitados a la segunda parte del post, así que espero veros por aquí dentro de unas semanas. Disfrutad del Cobol mientras tanto...

Saludos.

lunes, 30 de mayo de 2016

Ver campos Hexadecimales en QMF con FORM (y 2)

Hace algunas semanas comenzamos a ver los pasos que había que seguir para visualizar campos hexadecimales en QMF con FORM. Aunque existen otras técnicas para decodificar este tipo de formatos, la verdad es que el uso del comando X de FORM es una de las más rápidas. Afortunadamente, también es una de las más fáciles de poner en práctica.

En la primera parte del post estuvimos viendo los primeros pasos de esta técnica (ver post Ver campos Hexadecimales en QMF con FORM - 1). Hoy simplemente nos centraremos en terminar de examinar los puntos requeridos para implementar la visualización mediante X de FORM. Como veremos, se trata de un procedimiento que no nos debe dar ningún problema una vez aprendido.

Visualizar Hexadecimales con X en FORM


Llegados a este punto, una de las alternativas de que disponemos para visualizar los campos hexadecimales en QMF es el uso de la etiqueta X de FORM. Se trata de una funcionalidad sencilla de ejecutar y que siempre tendremos disponible en la herramienta QMF. Nos permitirá traducir los campos encriptados a alfanuméricos, que pasarán a estar en un formato inteligible aunque, como veremos, no del todo cómodo de leer.

3º) Desde la pantalla de REPORT que nos muestra el informe extraído por la sentencia SQL, pulsamos la tecla PF9 para ir a la ventana FORM.




4º) A continuación, nos situamos en la columna EDIT y en la fila correspondiente al campo hexadecimal que queremos decodificar. Introducimos una X en esa ubicación y pulsamos PF12 para obtener de nuevo el informe optimizado.






En la imagen anterior podemos ver cómo se mostraría el informe tras realizar la acción anterior. Los registros ya han dejado de mostrar caracteres extraños y ahora nos aparecen en formato alfanumérico. Tal y como he dicho más arriba, la información no es cómoda de visualizar pero, eso sí, al menos son datos legibles. Aquí ya tendríamos un punto de partida para analizar el problema que tengamos en nuestra aplicación.

 INCI                                         
  CO                                          
ORIGEN                                        
-----------------------------------------------
00662341105C000CC2C50990003C290C0900001C002C002
01422001600C000CE3C80990002C031C0900001C002C003
01458141303C000CC2F20990003C839C0900001C002C001
02180781101C002CC2C50990003C290C0900001C002C002
03038681303C000CC2C50990003C290C0900001C002C001
03422721304C000CE3C80990002C031C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001
03560631304C000CC2C50990003C290C0900001C002C001


Si tomamos, por ejemplo, el último registro, veremos que ahí ya se podría hacer una lectura de la información contenida en el campo hexadecimal de la tabla DB2.

 INCI                                         
  CO                                          
ORIGEN                                        
-----------------------------------------------

03560631304C000CC2C50990003C290C0900001C002C001

Cada subcampo del registro estaría separado de los demás mediante el carácter "C". Sabiendo esto, ya podríamos identificar cada uno de los datos informativos.

03560631304C000CC2C50990003C290C0900001C002C001

En la línea anterior hemos coloreado cada uno de los subcampos que existen en el registro que estamos usando de ejemplo. Ya tenemos la información disponible. Queda claro que no es la forma más rápida de trabajar pero, al menos, tenemos un camino por el que seguir avanzando (cosa que no ocurría al principio, cuando sólo teníamos registros con caracteres extraños).

Una vez que hemos visto la forma de visualizar campos hexadecimales con FORM, el próximo día os mostraré una forma alternativa de hacerlo, mediante la cláusula HEX. Pero bueno, con lo que hemos examinado hoy al menos ya tenéis un método para decodificar este tipo de campos y mostrarlos con un formato más amigable. Lo importante es que dispongamos de algo que nos permita seguir avanzando en el análisis de nuestra base de datos DB2.

Pues nada, eso es todo por lo que respecta a la utilización de la cláusula X en FORM. Espero que su empleo haya quedado lo suficientemente claro en el post. Si no es así, dejadme las dudas que tengáis aquí abajo...

Saludos.

lunes, 23 de mayo de 2016

Ver campos Hexadecimales en QMF con FORM (1)

Hay ocasiones en las que estamos ejecutando una query SQL y nos damos cuenta de que la extracción nos recupera campos en formato hexadecimal. Obviamente, se trata de información que no podemos interpretar a primera vista. ¿Qué podríamos hacer para mostrar estos campos en un formato más amigable? En este post vamos a tratar de contaros una forma de resolver este problema.

Campos Hexadecimales en QMF


Cuando empecé en esto del mundo Cobol, recuerdo que las primeras veces que me encontré con extracciones de campos hexadecimales me llamó mucho la atención el formato con el que se visualizaban en la herramienta QMF. Se mostraban una serie de símbolos extraños que eran imposibles de interpretar y, por tanto, era muy complicado ponerse a analizar la información de los registros extraídos. Si en vuestra Base de Datos no hay campos hexadecimales, entonces no entenderéis de qué os estoy hablando...

En la siguiente imagen podéis ver a qué me refiero. Si nos vamos al QMF y extraemos la información de un campo encriptado, veremos que los registros nos muestran caracteres especiales. Si eres un programador novato, entonces probablemente no sabrás qué hacer para solucionar esta situación. Y si, por ejemplo, estás analizando una incidencia, entonces va a ser complicado llegar a alguna conclusión.





Afortunadamente, en QMF existe una forma muy sencilla de transformar estos campos hexadecimales en un formato interpretable. Con ello conseguiremos que la información se muestre en caracteres alfanuméricos, cosa que nos permitirá avanzar en nuestro trabajo. O, al menos, nos servirá para decodificar el contenido de los registros que estamos leyendo.

¿Cómo visualizar campos Hexadecimales en QMF?


Dicho lo anterior, vamos a ver rápidamente qué es lo que tendríamos que hacer para pasar de una extracción de campos hexadecimales a unos registros en formato alfanumérico normal. Como veremos, se trata de una acción muy sencilla. Pero, a pesar de su simplicidad, se trata de una actividad que nos permitirá evitar problemas innecesarios. Los pasos a seguir son los siguientes.

1º) Una vez que estamos en la herramienta QMF, procedemos a codificar la query. Recordemos que se tratará de un SQL que accederá a una tabla que posea campos en formato hexadecimal.




En el ejemplo anterior se puede observar que la query implementada es la siguiente. He escogido una sentencia sencilla para que podamos centrarnos en el objetivo del post.

SELECT INCI_CO_ORIGEN, INCI_IN_ORIGEN,INCI_TS_TIMEST
FROM A0DB22.A0INCIT0
WHERE  SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN
             ('900001','900002','900003',
              '900005','900006','900007','900008')

2º) Lanzamos la ejecución de la query codificada anteriormente. QMF nos mostrará la salida de la extracción realizada sobre la tabla DB2.





Aquí se puede observar el problema del que hemos estado hablando más arriba. La sentencia SQL nos ha extraído registros cuyo primer campo se encuentra en formato encriptado. Tal y como se muestra en estos momentos, la información devuelta es inútil, ya que no seremos capaces de interpretar el contenido de ninguna línea. Esto es lo que tenemos que conseguir decodificar.

 INCI                                         
  CO                                          
ORIGEN                                        
-----------------------------------------------
     *  BE                                    
    -   TH                                    
  a     B2    c                               
   a    BE                                    
  fa    BE                                    
     <  TH                                    
     <  BE                                    
     <  BE                                    
     <  BE                                    
     <  BE                                    
     <  BE                                    
     <  BE                 


Vamos a ver ahora un par de métodos para traducir los caracteres extraños a contenido alfanumérico. Usaremos uno u otro según nos convenga.

El próximo día, en un nuevo post, continuaremos viendo los pasos que hay que seguir para visualizar los campos hexadecimales en QMF mediante la herramienta FORM. Es importante que dominemos esta técnica pues, aunque no es la forma más cómoda de leer hexadecimales, sí que se trata del método de visualización más rápido. Si necesitamos consultar y analizar un dato lo antes posible, entonces os puedo asegurar que lo mejor será recurrir al FORM.

Pues nada, eso es todo por ahora. Ya sabéis que quedáis invitados a la segunda parte del artículo, espero veros por aquí cuando revisemos los pasos que nos quedan pendientes. Que sigáis disfrutando del Cobol hasta entonces...

Saludos.

lunes, 4 de abril de 2016

Query SQL con UNION y con UNION ALL (y 2)

Hace unas semanas comenzamos a ver cómo debían implementarse las queries con las cláusulas UNION ALL y UNION. La ventaja de estos comandos es que nos permiten rebajar drásticamente los tiempos de ejecución de las sentencias SQL que tengamos insertadas en el código de nuestros objetos Cobol. Aunque en principo esto pueda parecer poco relevante, en cuanto vayamos teniendo más experiencia lo normal es que también vaya aumentando la preocupación por el rendimiento de nuestros programas.

En la primera parte del post nos centramos en analizar cómo debía codificarse una query con la cláusula UNION (ver post Query SQL con UNION y con UNION ALL - 1). Hoy, para completar la visión global, vamos a examinar cómo debería implementarse una query con UNION ALL. Y, lo que es más importante, explicaremos cuál es la diferencia entre la instrucción UNION ALL y la instrucción UNION del lenguaje SQL.

Diferencia entre UNION ALL y UNION


Más arriba he hablado de la cláusula UNION ALL y de la cláusula UNION. ¿Cuál es la diferencia entre ambas? En realidad, son dos variantes del mismo concepto. En general, nos será más útil el comando UNION, pero es posible que alguna vez nos venga bien utilizar UNION ALL.

La ejecución de la query con UNION nos va a extraer el listado de datos eliminando todos aquellos registros que estén duplicados. ¿Cuáles se consideran duplicados? Pues aquellos registros que tengan provisionados valores idénticos en todos aquellos campos especificados en la cláusula SELECT (si hemos puesto un * entonces serían todos los campos del registro).

Siguiendo con este razonamiento, la ejecución de la misma query con UNION ALL nos va a extraer el listado de datos incluyendo todos aquellos registros que estén duplicados. Por eso decía que, en general, preferiremos usar el comando UNION. Eso sí, alguna vez puede que necesitemos recuperar el listado completo (con todos sus duplicados) y para eso nos vendrá muy bien el comando UNION ALL.



En el ejemplo anterior, el uso de UNION ALL no cambiaría demasiado el aspecto del código SQL. Quedaría del siguiente modo.

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)

    AND A.JJTU_CO_INTERN   = B.JJTU_CO_INTERN                  
    AND A.JJCA_CO_INTERN   = B.JJCA_CO_INTERN                   
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN  


  UNION ALL

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
                  
    AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1  
    AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1  
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN


Como vemos, se trata prácticamente de la misma query. Simplemente tendremos que decidir previamente si necesitamos los registros duplicados o no.


Conclusiones acerca de UNION ALL y UNION


Tal y como hemos podido comprobar a lo largo del post, la cláusula UNION nos puede resultar muy útil en aquellos casos en los que tengamos que mejorar el rendimiento de una query compleja. Como he podido comprobar en numerosas ocasiones, su uso suele tener mucho éxito a la hora de bajar los tiempos de ejecución por debajo de los 100 milisegundos. Así que tenedlo en cuenta a la hora de implementar los objetos Cobol.

Normalmente, yo suelo utilizar UNION para problemas de rendimiento. Por contra, dejo UNION ALL para casuísticas muy especiales en las que necesito conocer el número de registros que hay en una determinada tabla DB2. Si puedo prescindir de dicho dato, entonces prefiero obtener los listados sin registros duplicados.

En los ejemplos habéis podido comprobar que la implementación de un UNION es muy sencilla. La verdadera dificultad viene a la hora de pensar cómo se puede dividir una query compleja en varias queries más sencillas. Es decir, se trata más de un problema funcional que de una dificultad técnica.



Pero no os preocupéis. Con un poco de experiencia se va haciendo cada vez más fácil la tarea de dividir queries. Como punto de partida, en estos casos en los que preciséis mejorar el rendimiento, podéis echarle un vistazo a las declaraciones en las que se estén empleando operadores OR. Normalmente, no es difícil fraccionar estas sentencias en varias queries más simples.

Pues nada, eso es todo por hoy. Espero que lo comentado a lo largo del artículo os sea útil para entender el funcionamiento de UNION ALL y de UNION. En caso de que os quede alguna duda, ya sabéis que aquí abajo tenéis el apartado de comentarios...

Saludos.

lunes, 21 de marzo de 2016

Query SQL con UNION y con UNION ALL (1)

En muchas ocasiones, tras implementar un determinado código SQL, nos damos cuenta de que su rendimiento a la hora de ejecutarse es bastante deficiente. Una forma de optimizar los tiempos de ejecución es recurrir a la cláusula UNION e incorporarla a nuestras queries siempre que sea posible. En este sentido, disponemos de dos variantes principales para codificar este comando: UNION ALL y UNION.

Rendimiento de Query SQL con UNION


La instrucción UNION nos va a permitir integrar las extracciones realizadas por dos queries distintas. Si prescindimos de la cláusula UNION, lo más normal es que, en vez de unir dos queries sencillas, tengamos que recurrir a una query única de complejidad mucho mayor. Y, lo que es peor, el rendimiento de esta query compleja probablemente será muy inferior a la solución con UNION.

Por lo general (lo he podido comprobar en mi propia experiencia), una declaración SQL mediante UNION suele tener tiempos de ejecución mucho mejores que la misma extracción pero realizada mediante una query única más compleja (que integre la funcionalidad de las queries sencillas empleadas en dicho UNION). Esto lo he verificado con el uso del comando EXPLAIN, así que no merece la pena complicarse la vida.


Para ver cómo funcionaría la instrucción UNION vamos a ver un ejemplo en el que inicialmente no se ha empleado esta instrucción para mejorar el rendimiento del código.

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
    ((A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)

    OR (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1))

    AND A.JJTU_CO_INTERN   = B.JJTU_CO_INTERN                  
    AND A.JJCA_CO_INTERN   = B.JJCA_CO_INTERN                  
    AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1  
    AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1  
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN       


Aparentemente, esta query tiene un aspecto muy compacto y parece bien codificada pero, por desgracia, sus tiempos de ejecución eran superiores a 100 milisegundos. Por tanto, no hubo más remedio que pensar en formas de mejorar su rendimiento. Y aquí es donde entra en juego la cláusula UNION.

¿Cómo codificar una Query SQL con UNION?


Una vez vista la query compleja, vamos a examinar cómo se podría mejorar el rendimiento de la misma mediante UNION. Para ello, lo que tendríamos que determinar es cómo se podría dividir la query inicial en varias subqueries más sencillas, de manera que posteriormente podamos unir estas subextracciones mediante la cláusula UNION.

En el ejemplo que nos ocupa, vemos que se está usando el operador OR en la cláusula WHERE. Por tanto, aquí lo más fácil sería dividir la query total en dos queries más pequeñas, de manera que cada una de ellas extraiga el contenido de cada operando del OR. Obviamente, estas subqueries tendrán tiempos de ejecución muy bajos, ya que su código será mucho más sencillo.


Dicho y hecho. Haciendo la división, estas serían las dos declaraciones que nos quedarían para las nuevas queries. La primera parte del OR sería la siguiente.

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)

    AND A.JJTU_CO_INTERN   = B.JJTU_CO_INTERN                  
    AND A.JJCA_CO_INTERN   = B.JJCA_CO_INTERN                   
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN  
  


Y la segunda parte del OR sería esta.

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
                  
    AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1  
    AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1  
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN  
 
  

Y ahora viene la parte que verdaderamente nos interesa. Una vez que hemos dividido la query padre en queries hijas más pequeñas, llega el momento de dar entrada a UNION. ¿Y cómo se utiliza esta cláusula en una query? Pues muy sencillo, simplemente hay que insertar la instrucción UNION entre las dos queries hijas del siguiente modo.

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)

    AND A.JJTU_CO_INTERN   = B.JJTU_CO_INTERN                  
    AND A.JJCA_CO_INTERN   = B.JJCA_CO_INTERN                   
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN  


  UNION

  SELECT *                                                     
  FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B
  WHERE                                                        
     (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)
                  
    AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1  
    AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1  
    AND A.JJAM_NU_INTERN   = B.JJAM_NU_INTERN  
 
 

El listado extraído por el UNION anterior es idéntico al que hubiésemos obtenido mediante la ejecución de la query inicial más compleja. La única diferencia es que, mediante el uso del UNION, hemos conseguido que su tiempo de ejecución caiga por debajo de los 100 milisegundos y, por tanto, que ya tengamos entre nuestras manos un código adecuado para entregar al cliente.

-------------------------------------------------------------------------------------------------------------------------------
Tip: Aquí te explico cómo almacenar queries en QMF y también cómo recuperar queries en QMF.
-------------------------------------------------------------------------------------------------------------------------------



Hasta aquí todo lo que teníamos que ver sobre la implementación de una query con UNION. El próximo día, en un nuevo post, trataremos de revisar el funcionamiento de la cláusula UNION ALL en una sentencia SQL. Hay ciertas diferencias entre ambas instrucciones y es importante que las tengamos en cuenta a la hora de desarrollar los accesos a DB2 en nuestros programas Cobol.

Pues nada, eso es todo por hoy. Como siempre, quedáis citados a la segunda parte del post, donde completaremos la visión global de UNION y de UNION ALL. Espero (y deseo) que lo comentado os sea de la máxima utilidad...

Saludos.

lunes, 7 de marzo de 2016

EXPLAIN con CA SQL-Ease for DB2 for ZOS (y 2)

Hace algunas semanas estuvimos viendo cómo se podía lanzar un chequeo EXPLAIN sobre una sentencia SQL de un programa Cobol. Esta función nos permitía obtener un informe (ACCESS PATH ANALYSIS) en el que se nos mostraba información acerca de las tablas DB2 utilizadas en nuestro objeto. Lo más importante es que se nos indicaba el coste, en milisegundos, que iba a requerir la ejecución de las instrucciones SQL.

En la primera parte del presente artículo estuvimos viendo cómo lanzar un EXPLAIN desde el editor de nuestro programa Cobol (ver post EXPLAIN con CA SQL-Ease for DB2 for ZOS - 1). Hoy veremos cómo se podría lanzar este mismo chequeo EXPLAIN desde el informe ACCESS PATH ANALYSIS. De esta forma, ahorraremos tiempo a la hora de analizar el rendimiento de nuestro programa, ya que no tendremos que estar cambiando entre el editor del objeto y la herramienta CA SQL-Ease for DB2 for ZOS.

Lanzar EXPLAIN desde ACCESS PATH ANALYSIS


Con lo examinado en el anterior post ya podemos dar por vistos los pasos que tenemos que seguir para ejecutar un EXPLAIN en la herramienta CA SQL-Ease for DB2 for ZOS. Ahora os comentaré otra funcionalidad interesante que podemos encontrar en esta aplicación.

1º) Una vez estamos en el informe ACCESS PATH ANALYSIS, podemos irnos al final del todo escribiendo 'M' en la línea de comandos y pulsando PF8. Así nos aparecerá en pantalla el código de la query para la se ha ejecutado el informe EXPLAIN.




Lo bueno es que en esta misma pantalla podremos proceder a modificar la query como deseemos. Esto nos permitirá probar diversas alternativas para optimizar el código y nos facilitará la realización del trabajo necesario para rebajar el coste por debajo de los 100 milisegundos.

2º) Una vez que hayamos terminado las modificaciones necesarias, podremos obtener de nuevo fácilmente el informe ACCESS PATH ANALYSIS para la query optimizada. Para ello, simplemente tendremos que introducir la instrucción EXPLAIN en la línea de comandos.







Tras pulsar INTRO se nos volverá a mostrar el informe EXPLAIN pero esta vez con los datos de Coste actualizados según las nuevas modificaciones que hayamos introducido en la query. Y lo mejor de todo es que podremos repetir este proceso tantas veces como necesitemos hasta que estemos totalmente seguros de que nuestro código no va a superar los 100 milisegundos de ejecución.

Conclusiones acerca de CA SQL-Ease for DB2 for ZOS


Hay ocasiones en las que implementamos un determinado código SQL y, cuando realizamos las pruebas en ejecución, nos damos cuenta de que el rendimiento del nuevo programa es muy inferior al esperado. Y lo peor es que, en muchos casos, es complicado determinar cuál es la query que está provocando el cuello de botella en la aplicación, sobre todo cuando trabajamos con código que contiene subqueries anidadas.

Para estos casos nos va a venir muy el empleo de la herramienta CA SQL-Ease for DB2 for ZOS. En particular, la opción 2 de la misma (EXPLAIN SQL) nos resultará muy útil para evaluar el rendimiento de las implementaciones SQL. Y, por supuesto, esto repercutirá en el rendimiento global de nuestros programas Cobol.

El lanzamiento del EXPLAIN nos proporcionará un informe ACCESS PATH ANALYSIS correspondiente a la query que hayamos seleccionado. Entre los resultados de dicho informe nos encontraremos el de Coste (en milisegundos), dato que nos resultará muy útil a la hora de verificar que nuestro código tiene un rendimiento aceptable.


Llegados a este punto, ahora ya es decisión vuestra incorporar esta función a vuestro catálogo de herramientas Cobol. Por mi parte, yo hace tiempo que la uso y nunca entregaría un programa al cliente sin comprobar que sus accesos SQL son óptimos. Creedme cuando os digo que esto, a largo plazo, será beneficioso para vosotros.

Pues nada, eso es todo lo que quería comentaros con respecto a CA SQL-Ease for DB2 for ZOS. Si tenéis la suerte de disponer de esta aplicación en vuestra instalación, no dudéis en utilizarla. Cualquier duda, ya sabéis que podéis dejarla aquí debajo.

Saludos.

lunes, 29 de febrero de 2016

EXPLAIN con CA SQL-Ease for DB2 for ZOS (1)

En ocasiones, al ejecutar nuestros programas Cobol nos damos cuenta de que el rendimiento está siendo muy inferior al que estábamos esperando en el momento de su codificación. En estos casos, lo difícil es determinar el punto exacto del código donde se está produciendo el cuello de botella. El comando EXPLAIN de la herramienta CA SQL-Ease for DB2 for ZOS nos va a permitir medir la velocidad de ejecución de cada una de las sentencias SQL que hayamos incluido en nuestro programa.

EXPLAIN con CA SQL-Ease for DB2 for ZOS


Supongo que, al igual que a mi, en ocasiones os habrá ocurrido que, tras terminar la codificación de un Cobol, procedéis a ejecutarlo y descubrís que su rendimiento en máquina está siendo bastante deficiente. En estos casos, ¿cómo podemos determinar el punto del programa que está provocando el retraso de la ejecución? Para ayudarnos a realizar esta búsqueda disponemos de la herramienta CA SQL-Ease for DB2 for ZOS.

El comando EXPLAIN de CA SQL-Ease for DB2 for ZOS nos sirve para medir el tiempo estimado de ejecución de una sentencia SQL. Recordad que no deberíamos poner en producción ninguna sentencia cuyo tiempo de ejecución sea superior a los 100 milisegundos. Teniendo en cuenta esto, EXPLAIN nos va a permitir detectar cuáles son las instrucciones SQL de nuestro programa que van a tener un pobre rendimiento a la hora de ejecutarse.


Hay que tener en cuenta que se trata de una aplicación muy potente. Su uso nos va a permitir que las sentencias SQL de nuestros programas Cobol lleguen al entorno de producción con tiempos de ejecución inferiores a 100 ms. Obviamente, siempre es posible que surja algún error adicional pero no podemos negar que, con EXPLAIN, las posibilidades de que se produzca un problema de rendimiento son muy inferiores.

¿Cómo ejecutar EXPLAIN en un Cobol?


Entrando ya en materia, ahora vamos a ir viendo cuáles son los pasos que tendríamos que seguir para ejecutar el comando EXPLAIN en nuestro programa Cobol. Como veréis, no se trata de algo complicado. Una vez que hayamos realizado el procedimiento por primera vez, el resto de las ejecuciones las podremos realizar casi sin esfuerzo.

Estos son los pasos:

1º) En primer lugar, tendremos que proceder a seleccionar el programa a valorar y entrar en el código del objeto en modo edición.

2º) Nos situamos en la declaración SQL para la que deseamos obtener una evaluación de su rendimiento en ejecución. Os recuerdo que este tipo de declaraciones estarán situadas entre cualquiera de las instrucciones EXEC SQL y END-EXEC de nuestro programa.

3º) A continuación, insertamos una E en alguna de las líneas de la declaración SQL. Esta marca debe introducirse en la columna en la que figura el número de línea del programa.


4º) Introducimos la instrucción SQLEASE en la línea de comandos. Esto hará que se arranque la aplicación CA SQL-Ease for DB2 for ZOS.



5º) Tras pulsar INTRO se nos abrirá el menú principal de la herramienta. Aquí tendremos que seleccionar la opción 2 - EXPLAIN SQL.



6º) A continuación, se nos mostrará un informe en el que podremos ver toda la información asociada a la evaluación del rendimiento de ejecución de la sentencia SQL seleccionada.




7º) Si nos desplazamos una página hacia abajo, podremos ver la información del rendimiento de la ejecución en el apartado ACCESS PATH ANALYSIS. En la línea COST encontraremos el importante dato que hace referencia al tiempo (en milisegundos) que tardará en ejecutarse nuestra sentencia SQL.




En el ejemplo vemos que el coste del SQL sería de 284 milisegundos. Como hemos dicho más arriba, cualquier cosa que pase de los 100 milisegundos no es aceptable y, por tanto, tendríamos que proceder a la optimización de nuestro código antes de entregarlo al cliente.

8º) Adicionalmente, en el análisis del camino de acceso también podremos encontrar información acerca de las tablas a las que se va entrando y el índice por el que se está accediendo a las mismas en la query SQL analizada.


En el ejemplo vemos que se está accediendo a la tabla DB2 denominada SITUTD mediante el índice SITUI2. Este camino de acceso nos puede ayudar y darnos ideas a la hora de optimizar la query analizada (en el caso de que sea necesario proceder a su modificación).

Si seguimos los pasos anteriormente comentados no tendremos problemas para ejecutar un EXPLAIN desde el editor de nuestro programa Cobol. El próximo día, en un nuevo post, os explicaré cómo podemos lanzar un chequeo EXPLAIN desde el propio informe ACCESS PATH ANALYSIS. Esta segunda funcionalidad nos vendrá muy bien para ir haciendo pruebas a la hora de reducir el consumo de una sentencia SQL por debajo de los 100 milisegundos.

Pues nada, eso es todo por ahora. Quedáis invitados a la segunda parte del post, donde completaremos nuestra visión inicial (básica) de la herramienta CA SQL-Ease for DB2 for ZOS. Espero volver a veros por aquí...

Saludos.

lunes, 9 de noviembre de 2015

¿Cómo recuperar queries en QMF?

Hace algunas semanas estuvimos viendo cómo se puede almacenar una query en la base de datos de QMF. Una vez que tenemos dicha información a salvo, hoy vamos a centrarnos en revisar cuáles son los comandos que tenemos disponibles para poder recuperar dichas querys de la base de datos.

En su día ya estuvimos viendo la instrucción SAVE de QMF, que nos permitía guardar cualquier tipo de código que tuviésemos escrito en el menú DRAW. Junto a ella, como veremos a continuación, tenemos otros otros dos comandos que nos van a venir muy bien a la hora de reutilizar nuestras queries de uso más frecuente. Se trata de DISPLAY QUERY y de LIST QUERIES.

¿Cómo recuperar una query en QMF?


Una vez almacenada la información, la siguiente cuestión que se nos plantearía es cómo recuperar la query en el momento en el que lo deseemos. Obviamente, no tendría mucho sentido almacenar el código si no pensamos usarlo nunca más con posterioridad.

En este entorno, para realizar la acción de recuperar la query en QMF disponemos del comando DISPLAY. Para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF, tal y como hicimos a la hora de guardar el código.

Una vez aquí, en la línea COMMAND tendremos que incluir el comando DISPLAY QUERY.

COMMAND ===> DISPLAY QUERY EJEMPLO

Pulsamos INTRO y se nos deplegará la siguiente ventana.


Como se puede apreciar, se trata del mismo código que previamente habíamos almacenado con el comando SAVE. Una vez recuperada, esta declaración ya se podría ejecutar del mismo modo que se haría con cualquier otra query de QMF.

Listar todas las queries almacenadas en QMF


Imaginaos que llega un momento en el que tenéis almacenadas 50 queries en vuestro QMF y, por la razón que sea, un cliente os pide que obtengáis de nuevo un informe cuya query lanzásteis hace más de un año. Lo más probable es que no os acordéis del nombre con el que la guardásteis. Entonces, ¿cómo podríais acceder de nuevo a ella?

Para estos casos vamos a usar el comando LIST, que nos mostrará un listado de todas las queries que nuestro usuario tiene almacenadas en la base de datos de QMF. De nuevo, para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF.

Una vez aquí, en la línea COMMAND tendremos que incluir el comando LIST QUERIES.

COMMAND ===> LIST QUERIES

Pulsamos INTRO y se nos deplegará la siguiente ventana.








Como vemos, en esta pantalla aparecen las queries que previamente he almacenado en QMF con mi usuario.

A continuación, si queremos recuperar el código de alguno de los objetos SQL listados, lo único que tendremos que hacer es usar el comando DISPLAY en la columna ACTION. De este modo, se recuperará el contenido de la query de la misma forma que con el comando DISPLAY QUERY que hemos examinado anteriormente.

                                     --------Dates--------
Action   Name               Owner    Modified   Last Used
                                                         
DISPLAY  EJEMPLO            JJ00917  2015-10-06 2015-10-07


Esta sería el método estándar para recuperar una query de nuestra base de datos de QMF siempre que no recordemos el nombre con el que la almacenamos en su día.

Almacenar y recuperar queries en QMF


En principio, con los comandos revisados, ya podríamos operar de una manera básica con la base de datos de QMF. Las instrucciones SAVE, DISPLAY y LIST nos permitirán almacenar las queries que vayamos creando y recuperarlas siempre que tengamos necesidad de ellas (independientemente de que nos encontremos ante un tratamiento con la instrucción SELECT, con UPDATE, con INSERT o con DELETE).

Por supuesto, existen más comandos QMF que los aquí mencionados, pero con estas 3 instrucciones ya podremos sobrevivir en el entorno. En un futuro, en un nuevo post, intentaré esbozar una visión global de cuáles son todos los comandos disponibles para esta herramienta.

Aunque siempre habrá queries que sólo queramos usar una vez y que puedan ser desechadas tras su uso, lo importante es que tengamos la posibilidad de reutilizar fácilmente las queries que deban ser ejecutadas periódicamente. Esa función podrá ser realizada de forma eficiente con las instrucciones QMF revisadas hoy.



En principio, siguiendo los pasos aquí comentados no deberíais tener problemas a la hora de trabajar en el entorno. De todas formas, cualquier problema o duda que os surja, ya sabéis que podéis dejármela abajo en los comentarios. Intentaré contestaros lo antes posible.

Y eso es todo por hoy. Espero que con lo comentado en el post tengáis suficiente para moveros por QMF y que al menos os sirva para poder almacenar (y recuperar posteriormente) vuestras queries más importantes.

Saludos.

lunes, 2 de noviembre de 2015

¿Cómo almacenar queries en QMF?

En ocasiones, tras utilizar una determinada query en QMF, nos damos cuenta de que vamos a tener que emplearla más veces en el futuro. En condiciones normales, al abandonar la sesión de la herramienta QMF perderíamos el código introducido y, por tanto, la próxima vez que quisiéramos ejecutarla tendríamos que volver a teclear la query completa. Sin embargo, existe una forma de almacenar este código para poder recuperarlo en el futuro.

Ejecución múltiple de queries en QMF


Si necesitamos emplear una determinada query en múltiples ocasiones a lo largo del tiempo, no será necesario que introduzcamos su código cada vez que tengamos que recurrir a ella. La herramienta QMF nos da la opción de almacenar el código de dicha query, de manera que podamos recuperarlo siempre que lo precisemos.

Para explicar esto, prefiero que lo veamos con un ejemplo. Supongamos, por tanto, que hemos creado una determinada query SQL (a petición de nuestro cliente, por supuesto) y que ya la hemos ejecutado y hemos obtenido la información que nos habían solicitado.


La query en cuestión sería la siguiente, donde se realizaría la extracción de todas las poblaciones que pertenezcan a la provincia de Madrid y que hayan sido dadas de alta en el sistema en el año 2014 o en algún ejercicio posterior.

SELECT * FROM JJDB22.JJLOCAT0        
  WHERE JJGE_CO_INTERN = '28'        
    AND JJCA_FX_ALTSIS >= '2014-01-01'


Una vez ejecutada la query, los resultados mostrados serían los siguientes, donde se visualizaría el código y la descripción de cada población (entre otros datos).

    JJTU    JJCA    JJCA    JJCA    JJCA           
     CO      CO      CO      CO      NO            
   INTERN  INTERN  2SCLOC  3SCLOC  PBLSIT          
---------  ------  ------  ------  -----------------
    43277       0                  COLMENAR VIEJO  
    43277       1  CTO     1       COLMENAR VIEJO  
    44590       0                  COLMENAR VIEJO  
    44590       1  DIV2    0       COLMENAR VIEJO  
    44590       2  DV00    2       COLMENAR VIEJO  
    44590       3  CTO     1       COLMENAR VIEJO  
    47909       0                  MADRID          
    57746       0                  MADRID          
    91957       0                  MADRID          
    91966       0                  ALCOBENDAS      
    91966       1  CTO     1       ALCOBENDAS        


Se trata únicamente de la primera página extraída por QMF ya que, obviamente, para este ejemplo no merece la pena mostrar más datos del listado.

¿Cómo almacenar una query en QMF?


Normalmente, ejecutaremos la query sobre la tabla DB2, obtendremos los resultados y desecharemos el código con posterioridad. Sin embargo, en el caso de que concluyamos que este proceso nos puede resultar útil en el futuro o de que sospechemos que el cliente nos puede volver a pedir el mismo informe más adelante, entonces lo óptimo sería almacenarnos la declaración para no tener que volver a teclearla más veces.

Para poder guardarnos una query sobre DB2, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF.





Una vez aquí, en la línea COMMAND tendremos que insertar el comando SAVE.

COMMAND ===> SAVE

Pulsamos INTRO y se nos deplegará la siguiente ventana.



En esta ventana tenemos 3 apartados que tendremos que rellenar antes de confirmar la operación.

1º) NAME: Aquí simplemente tendremos que indicar el nombre con el que deseamos que la query con SELECT (o con cualquier otra instrucción) quede almacenada en QMF.

2º) CONFIRM: Aquí tendremos que indicar YES si queremos que, en el futuro, el sistema nos pida confirmación cada vez que queramos modificar esta query en el almacén de QMF.

3º) SHARE: Si indicamos YES en esta opción, entonces la query que almacenemos en QMF podrá ser recuperada por cualquier otro usuario que conozca el nombre de la misma.

Una vez que rellenemos estos datos y pulsemos INTRO, en QMF nos aparecerá el siguiente mensaje, donde se nos confirma el guardado del objeto con el nombre de nuestro usuario seguido del nombre elegido para la query (en la ventana anterior).

OK, QUERY was saved as JJ00917.EJEMPLO in the database.


En estos momentos, nuestra query ya quedaría almacenada en la base de datos de QMF y ya estaría disponible para ser recuperada fácilmente en el futuro.



Una vez visto el comando con el que podemos salvar queries en QMF, en un futuro post pasaremos a examinar las instrucciones que nos van a permitir recuperar esas queries almacenadas. Tened en cuenta que con todo esto no pretendo hacer una revisión exhaustiva de los comandos QMF, sino simplemente dar un repaso a los conceptos más básicos que nos van a permitir sobrellevar nuestro día a día en el cliente.

Y eso es todo por hoy. Como siempre, espero que con la explicación os haya quedado claro cómo se pueden almacenar queries en QMF. En caso contrario, ya sabéis que podéis dejarme vuestras dudas aquí abajo...

Saludos.

Related Posts Plugin for WordPress, Blogger...