tag:blogger.com,1999:blog-86136007960169883202024-03-13T19:19:59.094+01:00Universo CobolDesarrollando en Cobol y Natural sobre Plataforma MainframeJose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.comBlogger153125tag:blogger.com,1999:blog-8613600796016988320.post-60667153269134021042016-06-13T12:00:00.000+02:002016-06-13T19:31:23.767+02:00Ver 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<br />
<br />
En la primera parte del post ya estuvimos viendo los primeros puntos del procedimiento (acceder al post <a href="http://www.universocobol.com/2016/06/ver-campos-hexadecimales-en-qmf-con-hex_6.html">Ver campos Hexadecimales en QMF con HEX - 1</a>). 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.<br />
<br />
4º) Una vez codificada la query anterior, la <span style="color: magenta;"><b>ejecutamos desde QMF</b></span>. De esta forma obtendremos el informe de la tabla DB2 con el listado de registros extraidos. <br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-rbG93p51mm0/Vkxbh8rGsvI/AAAAAAAAJNw/CWzhk5S3zt4/s1600/Hexadecimal%2BCampo%2BTraducido%2BQMF%2Bv2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-rbG93p51mm0/Vkxbh8rGsvI/AAAAAAAAJNw/CWzhk5S3zt4/s640/Hexadecimal%2BCampo%2BTraducido%2BQMF%2Bv2.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Como vemos en la imagen, ahora el informe ya no muestra datos hexadecimales. Por un lado,<b> la cláusula HEX ha hecho que se nos presente la información en formato alfanumérico</b>. Por otro lado, los comandos SUBSTR que hemos incluido nos han permitido <span style="color: cyan;"><b>dividir el campo hexadecimal</b></span> en cada uno de los subelementos con significación propia.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SITU LOCA<br />ORCI VERSIO TJALON SITU LOCA 1 1 <br />----------- ------ ------ ------ ---- ------ ----<br />00662341105 000 C2 990003 290 900001 002 <br />01458141303 000 C2 990003 839 900001 002 <br />02180781101 002 C2 990003 290 900001 002 <br />03038681303 000 C2 990003 290 900001 002 <br />03422721304 000 E3 990002 031 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03560631304 000 C2 990003 290 900001 002 <br />03723801304 000 D2 990003 788 900001 002 </span></span><br />
<br />
Si nos centramos en un único registro, podremos apreciar con mayor claridad lo cómoda que resulta ahora la<span style="color: orange;"><b> lectura de la información</b></span> del antiguo campo hexadecimal. Parece que ha merecido la pena dedicar algo de tiempo a la codificación.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SITU LOCA<br />ORCI VERSIO TJALON SITU LOCA 1 1 <br />----------- ------ ------ ------ ---- ------ ----<br />03560631304 000 C2 990003 290 900001 002 </span></span><br />
<br />
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.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="background-color: #990000;">03560631304</span> <span style="background-color: #741b47;">000</span> <span style="background-color: #073763;">C2</span> <span style="background-color: #783f04;">990003</span> <span style="background-color: #660000;">290</span> <span style="background-color: #4c1130;">900001</span> <span style="background-color: #073763;">002</span> </span></span><br />
<br />
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 <span style="color: lime;"><b>programadores Cobol</b></span>,
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 <a href="http://www.universocobol.com/search/label/ZOS">mundo Host</a> tarde o temprano tendréis que resolver incidencias...<br />
<br />
<a href="https://4.bp.blogspot.com/-hHhElzfqbHc/Vxh47yk0GiI/AAAAAAAALQA/YHI1D4x5DOkd0wAN2Ot46iryoqahGiRFwCLcB/s1600/Formato%2BHexadecimal%2BDecimal.gif" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="336" src="https://4.bp.blogspot.com/-hHhElzfqbHc/Vxh47yk0GiI/AAAAAAAALQA/YHI1D4x5DOkd0wAN2Ot46iryoqahGiRFwCLcB/s400/Formato%2BHexadecimal%2BDecimal.gif" width="400" /></a> <br />
<br />
<h2>
<span style="font-size: large;">¿Cuál de las dos alternativas es mejor? </span></h2>
<br />
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 <b>no podemos decir que uno de los procedimentos sea mejor que el otro, cada uno tiene su aplicación específica</b>. Va a ser cuestión nuestra decidir cuál de los <span style="color: orange;"><b>dos métodos</b></span> es el adecuado para la situación con la que nos estemos enfrentando.<br />
<br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<i><b>Tip</b>: Aquí podéis ver diversas <a href="http://www.universocobol.com/search/label/Herramientas">herramientas clave del entorno Host</a></i> <br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<br />
Por ejemplo, si únicamente queremos hacer una <span style="color: magenta;"><b>consulta rápida de un dato</b></span>
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.<br />
<br />
En cambio, si lo que nos están pidiendo es algo que vamos a tener que <span style="color: cyan;"><b>consultar una vez cada semana</b></span>
(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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://2.bp.blogspot.com/-EnXE86XQodk/Vxh5yJ9eP0I/AAAAAAAALQI/b9shmsy3fvkmgIYxdX_Gtre0LISBVKJaACLcB/s1600/Campos%2BHexadecimales%2BQMF.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="270" src="https://2.bp.blogspot.com/-EnXE86XQodk/Vxh5yJ9eP0I/AAAAAAAALQI/b9shmsy3fvkmgIYxdX_Gtre0LISBVKJaACLcB/s400/Campos%2BHexadecimales%2BQMF.png" width="400" /></a></div>
<br />
En cualquier caso, <b>la idea del post es que dispongáis de un par de opciones para traducir los campos hexadecimales</b>
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-34833438842028220412016-06-06T12:00:00.000+02:002016-06-06T19:10:18.101+02:00Ver 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.<br />
<br />
En su momento ya estuvimos viendo un método rápido para decodificar información hexadecimal (ver post <a href="http://www.universocobol.com/2016/05/ver-campos-hexadecimales-en-qmf-con_30.html">Ver campos Hexadecimales en QMF con FORM - y 2</a>). 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.<br />
<br />
<h2>
<span style="font-size: large;">Visualizar Hexadecimales mediante SELECT con HEX</span></h2>
<br />
<b>Otra de las alternativas para visualizar campos hexadecimales en QMF es usar una query SELECT con la cláusula HEX</b>. Esta solución es algo más compleja de implementar que la anterior (X en <a href="https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.icha700/icha700_QMF_form.htm">ventana FORM</a>). Pero, a cambio, los resultados mostrados serán mucho más cómodos de leer, lo que nos permitirá <span style="color: lime;"><b>analizar el contenido</b></span> con mucha mayor rapidez.<br />
<br />
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.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">SELECT INCI_CO_ORIGEN, INCI_IN_ORIGEN,INCI_TS_TIMEST</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">FROM A0DB22.A0INCIT0</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">WHERE SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> ('900001','900002','900003',</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> '900005','900006','900007','900008')</span></span> <br />
<br />
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 <span style="color: magenta;"><b>datos sin decodificar</b></span>. Continuamos, pues, con los siguientes puntos.<br />
<br />
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 <span style="color: cyan;"><b>cláusula HEX</b></span> a este campo del registro. Esto se conseguiría fácilmente especificando esta <a href="http://www.universocobol.com/2013/10/sentencia-select-para-una-tabla-db2.html">declaración SELECT</a>.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">SELECT HEX(INCI_CO_ORIGEN)</span></span><br />
<br />
Adicionalmente, en nuestro caso el campo INCI_CO_ORIGEN en realidad está compuesto por varios subcampos. Por ello,<b> vamos a usar el comando SUBSTR para establecer un nombre específico para cada uno de dichos subelementos</b>. De esta forma, conseguiremos que el informe extraído tenga un formato mucho más legible.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">SELECT SUBSTR(HEX(INCI_CO_ORIGEN),1,11) AS ORCI,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),13,3) AS VERSIO,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),17,2) AS TJALON,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),22,6) AS SITU,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),29,3) AS LOCA,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),34,6) AS SITU_1,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),41,3) AS LOCA_1</span></span><br />
<br />
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
<span style="color: lime;"><b>HEX y SUBSTR</b></span>.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-Ie7H9Cm2Ln4/VkxbiLdKIiI/AAAAAAAAJNs/qpo2MSYaepY/s1600/Hexadecimal%2BCampo%2BTraducido%2BQMF.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-Ie7H9Cm2Ln4/VkxbiLdKIiI/AAAAAAAAJNs/qpo2MSYaepY/s640/Hexadecimal%2BCampo%2BTraducido%2BQMF.png" width="640" /></a></div>
<br />
<br />
Como vemos en la imagen anterior, la <a href="http://www.universocobol.com/2015/04/como-crear-una-subquery-db2-con-sql.html">query SQL</a> se corresponde con la original, pero ahora hemos incorporado el traductor hexadecimal HEX y el <span style="color: orange;"><b>comando SUBSTR</b></span>. Con estos cambios ya conseguiríamos el objetivo inicialmente buscado de decodificar los campos hexadecimales.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">SELECT SUBSTR(HEX(INCI_CO_ORIGEN),1,11) AS ORCI,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),13,3) AS VERSIO,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),17,2) AS TJALON,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),22,6) AS SITU,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),29,3) AS LOCA,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),34,6) AS SITU_1,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SUBSTR(HEX(INCI_CO_ORIGEN),41,3) AS LOCA_1,</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> </span></span><span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">INCI_IN_ORIGEN, INCI_TS_TIMEST</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">FROM A0DB22.A0INCIT0</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">WHERE SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> ('900001','900002','900003','900005', </span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> '900006','900007','900008')</span></span><br />
<br />
Es cierto que ahora<b>
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</b>.
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.<br />
<br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<i><b>Tip</b>: Aquí podéis ver <a href="http://www.universocobol.com/2015/11/como-almacenar-queries-en-qmf.html">cómo se pueden almacenar queries en QMF</a></i> <br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<br />
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-57733217400856783282016-05-30T12:00:00.000+02:002016-05-30T15:18:23.707+02:00Ver 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. <br />
<br />
En la primera parte del post estuvimos viendo los primeros pasos de esta técnica (ver post <a href="http://www.universocobol.com/2016/05/ver-campos-hexadecimales-en-qmf-con.html">Ver campos Hexadecimales en QMF con FORM - 1</a>). 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.<br />
<br />
<h2>
<span style="font-size: large;">Visualizar Hexadecimales con X en FORM</span></h2>
<br />
Llegados a este punto, <b>una de las alternativas de que disponemos para visualizar los campos hexadecimales en QMF es el uso de la etiqueta X de FORM</b>. Se trata de una funcionalidad sencilla de ejecutar y que siempre tendremos disponible en la <span style="color: lime;"><b>herramienta QMF</b></span>.
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.<br />
<br />
3º) Desde la <span style="color: orange;"><b>pantalla de REPORT</b></span> que nos muestra el informe extraído por la <a href="http://www.universocobol.com/search/label/SQL">sentencia SQL</a>, pulsamos la tecla PF9 para ir a la ventana FORM.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-XzOoqpZNI-E/VkxbhcS0v_I/AAAAAAAAJNg/Own9pEauefk/s1600/Hexadecimal%2BCampo%2BQMF%2Bv2b.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-XzOoqpZNI-E/VkxbhcS0v_I/AAAAAAAAJNg/Own9pEauefk/s640/Hexadecimal%2BCampo%2BQMF%2Bv2b.png" width="640" /></a></div>
<br />
<br />
<br />
4º) A continuación, nos situamos en la <span style="color: magenta;"><b>columna EDIT</b></span>
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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-E5C_YLdr85k/VkxbhczHqnI/AAAAAAAAJNk/Hb2gq3H1AH8/s1600/Hexadecimal%2BCampo%2BQMF%2Bv3.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-E5C_YLdr85k/VkxbhczHqnI/AAAAAAAAJNk/Hb2gq3H1AH8/s640/Hexadecimal%2BCampo%2BQMF%2Bv3.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
En la imagen anterior podemos ver cómo se mostraría el informe tras realizar la acción anterior. <b>Los registros ya han dejado de mostrar caracteres extraños y ahora nos aparecen en formato alfanumérico</b>. Tal y como he dicho más arriba, la información no es cómoda de visualizar pero, eso sí, al menos son <span style="color: cyan;"><b>datos legibles</b></span>. Aquí ya tendríamos un punto de partida para analizar el problema que tengamos en nuestra aplicación.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> INCI <br /> CO <br />ORIGEN <br />-----------------------------------------------<br />00662341105C000CC2C50990003C290C0900001C002C002<br />01422001600C000CE3C80990002C031C0900001C002C003<br />01458141303C000CC2F20990003C839C0900001C002C001<br />02180781101C002CC2C50990003C290C0900001C002C002<br />03038681303C000CC2C50990003C290C0900001C002C001<br />03422721304C000CE3C80990002C031C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001<br />03560631304C000CC2C50990003C290C0900001C002C001</span></span><br />
<br />
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 <a href="http://www.universocobol.com/search/label/DB2">tabla DB2</a>.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> INCI <br /> CO <br />ORIGEN <br />-----------------------------------------------</span></span></span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">03560631304C000CC2C50990003C290C0900001C002C001</span></span><br />
<br />
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.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"><span style="background-color: #990000;">03560631304</span>C<span style="background-color: #741b47;">000</span>C<span style="background-color: #351c75;">C2</span>C<span style="background-color: #b45f06;">50990003</span>C<span style="background-color: #990000;">290</span>C<span style="background-color: #741b47;">0900001</span>C<span style="background-color: #351c75;">002</span>C<span style="background-color: #b45f06;">001</span></span></span><br />
<br />
En la línea anterior hemos coloreado cada uno de los <span style="color: orange;"><b>subcampos</b></span>
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).<br />
<br />
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-1911990951036633942016-05-27T12:00:00.000+02:002016-05-31T22:40:50.846+02:00Informático con insomnio<div class="separator" style="clear: both; text-align: left;">
<a href="https://1.bp.blogspot.com/-M-PERtqN8z4/V0w-qPm2WEI/AAAAAAAALrs/nrOISHxjBasAcjt2r84D4M5ssDKZHtcqACLcB/s1600/Informatico%2Bcon%2Binsomnio.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="377" src="https://1.bp.blogspot.com/-M-PERtqN8z4/V0w-qPm2WEI/AAAAAAAALrs/nrOISHxjBasAcjt2r84D4M5ssDKZHtcqACLcB/s400/Informatico%2Bcon%2Binsomnio.jpg" width="400" /></a></div>
<br />
<i>Fuente: El Economista</i><br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-89615410612518617572016-05-23T12:00:00.001+02:002016-05-23T12:00:16.199+02:00Ver 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.<br />
<br />
<h2>
<span style="font-size: large;">Campos Hexadecimales en QMF</span></h2>
<br />
Cuando empecé en esto del <a href="http://www.universocobol.com/search/label/Cobol">mundo Cobol</a>, recuerdo que las primeras veces que me encontré con extracciones de <span style="color: cyan;"><b>campos hexadecimales</b></span> me llamó mucho la atención el formato con el que se visualizaban en la <a href="http://www-01.ibm.com/common/ssi/cgi-bin/ssialias?subtype=BR&infotype=PM&htmlfid=IMB14170USEN&attachment=IMB14170USEN.PDF">herramienta QMF</a>. 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 <span style="color: lime;"><b>Base de Datos</b></span> no hay campos hexadecimales, entonces no entenderéis de qué os estoy hablando...<br />
<br />
En la siguiente imagen podéis ver a qué me refiero. <b>Si nos vamos al QMF y extraemos la información de un campo encriptado, veremos que los registros nos muestran caracteres especiales</b>. Si eres un programador novato, entonces probablemente no sabrás qué hacer para solucionar esta situación. Y si, por ejemplo, estás <span style="color: magenta;"><b>analizando una incidencia</b></span>, entonces va a ser complicado llegar a alguna conclusión. <br />
<br />
<div style="text-align: left;">
<a href="http://4.bp.blogspot.com/-4JO9xXhzz58/VkxbhcCrWsI/AAAAAAAAJNc/iGX8zNuaS5M/s1600/Hexadecimal%2BCampo%2BQMF%2Bv2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-4JO9xXhzz58/VkxbhcCrWsI/AAAAAAAAJNc/iGX8zNuaS5M/s640/Hexadecimal%2BCampo%2BQMF%2Bv2.png" width="640" /></a> </div>
<br />
<br />
<br />
<br />
Afortunadamente, en QMF<b> existe una forma muy sencilla de transformar estos campos hexadecimales en un formato interpretabl</b>e. Con ello conseguiremos que la información se muestre en <span style="color: lime;"><b>caracteres alfanuméricos</b></span>, cosa que nos permitirá avanzar en nuestro trabajo. O, al menos, nos servirá para decodificar el contenido de los registros que estamos leyendo.<br />
<br />
<h2>
<span style="font-size: large;">¿Cómo visualizar campos Hexadecimales en QMF?</span></h2>
<br />
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<a href="http://www.universocobol.com/2014/06/tipos-de-registros-de-ficheros.html"> registros en formato alfanumérico</a> 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.<br />
<br />
1º) Una vez que estamos en la <span style="color: orange;"><b>herramienta QMF</b></span>, procedemos a codificar la query. Recordemos que se tratará de un SQL que accederá a una tabla que posea campos en formato hexadecimal.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-yAILQREyiLk/Vkxbh3RsyjI/AAAAAAAAJNQ/2h35DTDl8mU/s1600/Hexadecimal%2BCampo%2BQMF.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-yAILQREyiLk/Vkxbh3RsyjI/AAAAAAAAJNQ/2h35DTDl8mU/s640/Hexadecimal%2BCampo%2BQMF.png" width="640" /></a></div>
<br />
<br />
<br />
En el ejemplo anterior se puede observar que la <a href="http://www.universocobol.com/2015/11/como-recuperar-queries-en-qmf.html">query implementada</a> es la siguiente. He escogido una sentencia sencilla para que podamos centrarnos en el objetivo del post.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">SELECT INCI_CO_ORIGEN, INCI_IN_ORIGEN,INCI_TS_TIMEST</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">FROM A0DB22.A0INCIT0</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">WHERE SUBSTR(HEX(INCI_CO_ORIGEN),34,6) IN</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> ('900001','900002','900003',</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> '900005','900006','900007','900008')</span></span> <br />
<br />
2º) Lanzamos la <span style="color: magenta;"><b>ejecución de la query</b></span> codificada anteriormente. QMF nos mostrará la salida de la extracción realizada sobre la tabla DB2.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-4JO9xXhzz58/VkxbhcCrWsI/AAAAAAAAJNc/iGX8zNuaS5M/s1600/Hexadecimal%2BCampo%2BQMF%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-4JO9xXhzz58/VkxbhcCrWsI/AAAAAAAAJNc/iGX8zNuaS5M/s640/Hexadecimal%2BCampo%2BQMF%2Bv2.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
Aquí se puede observar el problema del que hemos estado hablando más arriba. <b>La sentencia SQL nos ha extraído registros cuyo primer campo se encuentra en formato encriptado</b>. Tal y como se muestra en estos momentos, la información devuelta es inútil, ya que no seremos capaces de <span style="color: cyan;"><b>interpretar el contenido</b></span> de ninguna línea. Esto es lo que tenemos que conseguir decodificar.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> INCI <br /> CO <br />ORIGEN <br />-----------------------------------------------<br /> * BE <br /> - TH <br /> a B2 c <br /> a BE <br /> fa BE <br /> < TH <br /> < BE <br /> < BE <br /> < BE <br /> < BE <br /> < BE <br /> < BE </span></span><br />
<br />
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.<br />
<br />
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-87958804941290559362016-05-16T12:00:00.000+02:002016-05-16T12:23:42.823+02:00Control-M: Gestión de ejecuciones Batch (y 2)Hace algunas semanas comenzamos a ver el funcionamiento de la opción ACTIVE ENV de la herramienta Control-M. Se trata de una opción encaminada a realizar la gestión de las ejecuciones de los procesos batch de nuestra aplicación. Por supuesto, en el mundo Host existen otras alternativas para realizar este trabajo, pero he de deciros que, hoy en día, Control-M es una de las soluciones más extendidas.<br />
<br />
En la primera parte del artículo nos pusimos a examinar los pasos que había que seguir para comenzar a operar con la opción ACTIVE ENV (ver post <a href="http://www.universocobol.com/2016/05/control-m-gestion-de-ejecuciones-batch-1.html">Control-M - Gestión de ejecuciones Batch - 1</a>). Hoy nos centraremos en tratar de completar la revisión iniciada en el post anterior. Si todo va bien, cuando finalicemos ya deberíais tener las nociones básicas para poder empezar a trabajar con Control-M. Por tanto, ahora continuemos viendo los pasos a partir de donde lo dejamos el último día.<br />
<br />
4º) Si introducimos una 'S' en la línea de
comando y pulsamos INTRO, accedemos a una ventana en la que podemos
filtrar las fases mostradas en el listado.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-Lq4sCCoDa3s/VktaLLp_RVI/AAAAAAAAJL8/CEEMg8OhUAo/s1600/Control-M%2BShow%2BScreen%2BFilter.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-Lq4sCCoDa3s/VktaLLp_RVI/AAAAAAAAJL8/CEEMg8OhUAo/s640/Control-M%2BShow%2BScreen%2BFilter.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
Como se aprecia en la imagen, se puede <span style="color: cyan;"><b>filtrar por infinidad de conceptos</b></span>:
por el nombre de la fase, por grupo, por rango de fechas, por estado de
ejecución, por propietario, etc... En el ejemplo procederíamos a
recuperar únicamente las fases batch cuyo nombre empiece por A8.<br />
<br />
5º) Si se selecciona una fase con 'S' y se pulsa INTRO, accederemos a un <b>histórico de las últimas ejecuciones</b>. Se muestra la <b><span style="color: magenta;">fecha de ejecución</span></b>, así como la hora de inicio y la hora de fin del proceso batch.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-P0JgDOlAqC4/Vkw0vMHHF2I/AAAAAAAAJM0/-NHiCixXh_o/s1600/Control-M%2BEstadisticas.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="380" src="https://2.bp.blogspot.com/-P0JgDOlAqC4/Vkw0vMHHF2I/AAAAAAAAJM0/-NHiCixXh_o/s640/Control-M%2BEstadisticas.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
En
el ejemplo anterior podemos ver el registro de las últimas ejecuciones
de una fase batch. Tal y como se observa, para cada ejecución se muestra
su fecha/hora de inicio (STRT DATE/TIME) y su fecha/hora de
finalización (END DATE/TIME). Junto a estas columnas, también se muestra
el número de minutos consumidos por el job lanzado (ELAPSED).<br />
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca del Gestor de Ejecuciones de Control-M</span></h2>
<br />
Como hemos visto, la opción ACTIVE ENVIRONMENT de Control-M no plantea excesivas dificultades para un <span style="color: lime;"><b>empleo estándar</b></span>. En general, esta funcionalidad la usaremos para <b>verificar el estado de los procesos batch en curso y para chequear las salidas de las ejecuciones ya finalizadas</b>. La información mostrada por la aplicación nos será de gran utilidad a la hora de analizar los eventuales <a href="http://www.universocobol.com/2013/09/posibles-errores-rc-de-un-jcl.html">errores que aparezcan en nuestras fases</a>.<br />
<br />
Recordad que en el ejemplo que os he mostrado, Control-M está incluido en el Bloque 4 (Control-M & CTM/Restart) del <span style="color: orange;"><b>POM de la herramienta IOA</b></span> (<a href="https://ismetyaksi.wordpress.com/2013/06/07/bmc-control-m-and-control-o-products-on-zos/">Integrated Operations Arquitecture</a>).
Sin embargo, IOA es una arquitectura abierta y, por tanto, la
organización podría ser distinta en vuestra instalación. De todas
formas, una vez que detectéis la ubicación del bloque, la estructrura
interna de Control-M será la misma que os he indicado en el post.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/-F0sj1PnnISU/VwITam3J5HI/AAAAAAAALKA/XewTZiKWUfgykZy4-iVMcEfY3HZwz_1Kg/s1600/Control-M%2BHerramientas%2BBasicas.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://3.bp.blogspot.com/-F0sj1PnnISU/VwITam3J5HI/AAAAAAAALKA/XewTZiKWUfgykZy4-iVMcEfY3HZwz_1Kg/s400/Control-M%2BHerramientas%2BBasicas.png" width="400" /></a></div>
<br />
Entre esta opción y la funcionalidad de Planificación de fases que vimos el otro día, <b>ya tenemos las herramientas básicas para empezar a trabajar con Control-M</b>.
Os aconsejo que comencéis a emplear esta aplicación lo antes posible
(si no la tenéis, pedid que os la incluyan en vuestra instalación), ya
que os va a permitir resolver los problemas batch con mayor celeridad.
Así ha sido en mi experiencia, y estoy seguro de que así será también en
la vuestra.<br />
<br />
Pues nada, eso es todo lo que quería
indicaros con respecto a la opción ACTIVE ENVIRONMENT de Control-M.
Espero que lo comentado os sea suficiente para moveros por la
herramienta sin problemas. En cualquier caso, ya sabéis que aquí abajo
podéis dejarme las dudas que tengáis. <br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com2tag:blogger.com,1999:blog-8613600796016988320.post-9476127291867747802016-05-09T12:00:00.000+02:002016-05-10T20:01:57.294+02:00Control-M: Gestión de ejecuciones Batch (1)Hace algún tiempo ya estuvimos hablando de la herramienta Control-M y de sus bondades a la hora de realizar la gestión de cadenas batch. En su momento estuvimos examinando la funcionalidad de <a href="http://www.universocobol.com/2016/05/control-m-planificacion-de-ejecuciones.html">JOB SCHEDULE DEF de Control-M</a>, empleada para la planificación de fases batch. Sin embargo, nos quedó pendiente revisar la funcionalidad ACTIVE ENV, la cual nos permite acceder a las ejecuciones de los jobs y obtener el detalle de los errores producidos. Vamos con ello.<br />
<br />
<h2>
<span style="font-size: large;">Control-M: Revisión de ejecución de Fases Batch</span></h2>
<br />
Como vimos en su día, la <a href="http://www.tcpsi.com/vermas/control_m.htm">herramienta Control-M</a> es una aplicación ampliamente extendida entre las instalaciones de la mayoría de los clientes importantes. En general, tiene dos usos principales. Por un lado, se emplea para <span style="color: cyan;"><b>planificar las fases</b></span> y las cadenas batch de una aplicación. Y, por otro lado, también se usa para realizar toda la gestión de ejecuciones de los <a href="http://www.universocobol.com/search/label/JCL">procesos batch</a>.<br />
<br />
Hoy nos vamos a centrar en revisar esta última funcionalidad, que se realiza desde el <span style="color: magenta;"><b>apartado ACTIVE ENV</b></span> de Control-M. Desde esta opción podremos <b>revisar el estado de las ejecuciones batch, ver si una fase está pendiente de lanzamiento o si ya está en curso, examinar el detalle de los errores en aquellos procesos fallidos</b>, etc... Básicamente, tendremos acceso a todas las especificaciones de la parte batch de nuestra aplicación o de nuestro módulo.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-UM5a5YMAG08/VkrhfboqUZI/AAAAAAAAJLY/3NwPBVeivK8/s1600/Control-M%2BMenu%2BPrincipal.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-UM5a5YMAG08/VkrhfboqUZI/AAAAAAAAJLY/3NwPBVeivK8/s640/Control-M%2BMenu%2BPrincipal.png" width="640" /></a></div>
<br />
En la imagen anterior podemos ver el menú principal de Control-M, una de las <a href="http://www.universocobol.com/search/label/Herramientas">herramientas más conocidas del mundo Host</a>. Obviamente, nuestra aplicación está incluida en el bloque cuarto denominado <span style="color: lime;"><b>Control-M & CTM/Restart</b></span>. En su día ya estuvimos viendo la opción 2 - JOB SCHEDULE DEF. La funcionalidad a la que nos vamos a referir hoy es la incluida en la opción 3 - ACTIVE ENV.<br />
<br />
<h2>
<span style="font-size: large;">Control-M: Opción de Active Environment</span></h2>
<br />
A continuación, vamos a ir viendo los pasos que hay que seguir para
navegar por la opción 3 de Control-M, denominada ACTIVE ENV. <b>Esta
funcionalidad nos sirve para consultar el estado o el resultado de la ejecución de una fase de una cadena batch</b>. Además, nos
puede ser de gran ayuda a la hora de determinar las <span style="color: orange;"><b>causas de un error</b></span>
en el procesamiento de un Job.<br />
<br />
<a href="https://2.bp.blogspot.com/-kr_BCbpZmjM/Vv4b5gpTffI/AAAAAAAALGs/1k6Pj2DjONU6tMm6s0ZPod7bkHLd--yBg/s1600/Herramienta%2BMainframe%2BControl-M.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://2.bp.blogspot.com/-kr_BCbpZmjM/Vv4b5gpTffI/AAAAAAAALGs/1k6Pj2DjONU6tMm6s0ZPod7bkHLd--yBg/s400/Herramienta%2BMainframe%2BControl-M.jpg" width="400" /></a> <br />
<br />
Los pasos a seguir para operar correctamente con la facilidad ACTIVE ENV de Control-M son los siguientes.<br />
<br />
1º) Entrar en el <b>menú principal de Control-M</b>. En mi instalación, esto se hace entrando en la aplicación IOA desde <a href="http://www.universocobol.com/search/label/ISPF">ISPF</a> mediante el <span style="color: magenta;"><b>comando IOA</b></span> del <a href="http://www.universocobol.com/search/label/TSO">entorno TSO</a>. Posiblemente en vuestra instalación esté configurado de otra forma.<br />
<br />
2º) Seleccionar la opción <b>3 - ACTIVE ENV</b>. Una vez que estamos dentro de la <span style="color: cyan;"><b>arquitectura IOA</b></span>, dicha opción la encontraremos en el bloque Control-M.<br />
<br />
3º) En el menú principal de ACTIVE ENVIRONMENT se nos muestra el listado de fases correspondientes a las cadenas batch de nuestra aplicación. <br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-zTh9OFimSQg/VkrlJe33K1I/AAAAAAAAJLk/iM1-mBTKj-s/s1600/Control-M%2BActive%2BEnvironment.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-zTh9OFimSQg/VkrlJe33K1I/AAAAAAAAJLk/iM1-mBTKj-s/s640/Control-M%2BActive%2BEnvironment.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Como vemos en la imagen, en el <a href="http://www.universocobol.com/search/label/ZOS">entorno ZOS</a> se muestra el nombre de la fase (NAME), el propietario (OWNER), la fecha de ejecución (ODATE) y el estado de la ejecución (STATUS).<br />
<br />
En el campo estado de la ejecución se pueden mostrar las siguientes variantes (cada una con su propio color asignado).<br />
<br />
- <b><u>Estado <span style="color: cyan;">WAIT SCHEDULE</span></u></b>: En blanco o azul. Son las fases batch que están planificadas pero que aún no han iniciado su ejecución. Están en espera.<br />
<br />
- <b><u>Estado <span style="color: orange;">EXECUTING</span></u></b>: En amarillo. Son las fases que están ejecutándose, tanto aquellas que estaban planificadas como las que hemos relanzado manualmente.<br />
<br />
- <b><u>Estado <span style="color: lime;">ENDED OK</span></u></b>: En verde. Son las fases batch que ya han terminado su ejecución y que han terminado el proceso de manera correcta.<br />
<br />
- <b><u>Estado <span style="color: magenta;">ENDED - NOT OK - ABENDED</span></u></b>: En rojo. Son las fases batch que han terminado su ejecución y que han finalizado el proceso de manera errónea (como era de esperar, por el color rojo).<br />
<br />
El próximo día, en un nuevo post, continuaremos viendo los pasos que hay que seguir para comenzar a operar con la opción ACTIVE ENV de Control-M. Recordemos que este apartado se emplea para la gestión de las ejecuciones batch. Dicha opción y la funcionalidad de planificación de fases batch (opción JOB SCHEDULE DEF) constituyen la columna vertebral de la herramienta Control-M.<br />
<br />
Pues nada, eso es todo por ahora. Quedáis invitados a la segunda parte del artículo, donde completaremos la revisión que hemos iniciado hoy. Sinceramente, espero que no faltéis a la cita...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-58081439161598681762016-05-02T12:00:00.000+02:002016-05-02T13:49:54.943+02:00Control-M: Planificación de ejecuciones Batch (y 2)Hace algunas semanas comenzamos a ver cómo se podía acceder a la Planificación de ejecuciones Batch mediante la herramienta Control-M. Actualmente, esta herramienta es utilizada ampliamente en las instalaciones Mainframe para realizar el tratamiento de la parte batch de las aplicaciones de numerosos grandes clientes. Por tanto, creo que no tengo que hacer mucho más hincapié en la importancia de iniciar el aprendizaje de la misma cuanto antes.<br />
<br />
En la primera parte del artículo estuvimos viendo cuáles eran los pasos a seguir para acceder a la opción JOB SCHEDULE DEF (ver post <a href="http://www.universocobol.com/2016/04/control-m-planificacion-de-ejecuciones.html">Control-M - Planificación de ejecuciones Batch - 1</a>). Dicho apartado nos sirve para consultar los atributos asociados a la ejecución de las fases de una cadena batch. Hoy nos centraremos en otra interesante funcionalidad de Control-M: se trata de una opción que nos permitirá acceder a un esquema gráfico de la cadena batch seleccionada.<br />
<br />
<h2>
<span style="font-size: large;">Control-M: Esquema gráfico del Batch</span></h2>
<br />
Para los que gusten de esquemas visuales, <b>Control-M dispone de una opción para mostrarnos, de un modo gráfico, el orden de ejecución de las fases de una cadena batch</b>.
La verdad es que esta opción se agradece a la hora de examinar cadenas
con un alto número de componentes, ya que nos permite ahorrar gran
cantidad de tiempo. En cualquier caso, también se podría alcanzar el
mismo resultado revisando los<span style="color: magenta;"><b> atributos de los procesos batch</b></span> desde la consulta de Definición de Fases.<br />
<br />
Para poder acceder al esquema gráfico de una cadena batch determinada, bastará con seguir los siguientes pasos.<br />
<br />
1º) Accedemos al <b>menú de Listado de Cadenas</b>, donde se muestran todas las cadenas que tenemos planificadas en nuestra aplicación.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-5L8H4K1OS2s/VkoKFUuMhaI/AAAAAAAAJKE/8sZ7-KmaKIo/s1600/Control-M%2BJSD%2BEsquema%2BGrafico.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-5L8H4K1OS2s/VkoKFUuMhaI/AAAAAAAAJKE/8sZ7-KmaKIo/s640/Control-M%2BJSD%2BEsquema%2BGrafico.png" width="640" /></a></div>
<br />
<br />
<br />
2º) Seleccionamos la <span style="color: cyan;"><b>cadena deseada</b></span> con 'G' y pulsamos INTRO. De este modo accedemos a la pantalla en la que se nos muestra el <b>esquema gráfico</b> de dicha cadena.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-wiWc69fFhxw/VkoK5Tr7eBI/AAAAAAAAJKU/qQa_T1HcVC8/s1600/Control-M%2BJSD%2BGraphic%2BJobflow.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-wiWc69fFhxw/VkoK5Tr7eBI/AAAAAAAAJKU/qQa_T1HcVC8/s640/Control-M%2BJSD%2BGraphic%2BJobflow.png" width="640" /></a></div>
<br />
<br />
Como se aprecia en la imagen anterior, en esta consulta se nos muestran varias <span style="color: orange;"><b>cajas con los nombres</b></span> de las distintas fases incluidas en la cadena batch seleccionada. Adicionalmente, <b>mediante flechas, también se nos muestran las distintas relaciones de precedencia entre dichas fases</b>.
Por ejemplo, en la imagen se puede ver que en primer lugar se ejecutará
la fase A801RBK0 y, una vez finalizada, se lanzará la fase A8ESRAPE
(A801RBK0 ---> A8ESRAPE).<br />
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca de la herramienta Control-M</span></h2>
<br />
La verdad es que la <a href="http://www.tcpsi.com/vermas/control_m.htm">herramienta Control-M</a> y, en particular, la opción de <span style="color: magenta;"><b>Planificación de ejecuciones Batch</b></span> que hemos visto en el post, nos pueden resultar muy útiles a la hora de <b>gestionar las cadenas de fases batch de nuestra aplicación</b>.
Una consulta lanzada a través de esta opción nos va a bastar para tener
una visión global clara de cómo está estructurada la parte batch de un
sistema Host.<br />
<br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<i><b>Tip</b>: Aquí podéis acceder a la <a href="http://www.universocobol.com/2014/09/lista-de-utilidades-zos-basicas-para-jcl.html">lista de utilidades básicas Batch para JCL</a></i> <br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<br />
Es
posible que tengáis mala suerte y en vuestra instalación no se disponga
de ella. Sin embargo, esto es improbable. Os comento que en mi caso,
por ejemplo, me he encontrado con Control-M en todos los clientes con
plataforma Host con los que he trabajado hasta ahora. Así que no os va a
quedar más remedio que aprender a convivir con esta herramienta y,
cuanto antes aprendáis a hacerlo, pues menos problemas tendréis en
vuestro día a día.<br />
<br />
Cuando os incorporéis a un nuevo
sistema, tendréis dos grandes aliados para adquirir conocimientos sobre
su parte batch. Por un lado, el <span style="color: cyan;"><b>Manual de Explotación</b></span>,
que estará más o menos detallado en función del tiempo que le hayan
dedicado los analistas precursores. Por otro lado, la herramienta
Control-M. <b>Accediendo a su apartado de Planificación, podréis ver cuáles son las fases de las que se compone la cadena batch</b> y, lo que es mejor, todas las características asociadas a cada una de ellas.<br />
<br />
En definitiva, creo que Control-M es una herramienta imprescindible para la <span style="color: lime;"><b>plataforma Host</b></span>.
Si es posible, hemos de tratar que se incorpore en nuestra instalación.
De todas formas, si trabajáis en un cliente grande, lo más probable es
que esta aplicación ya esté integrada en su <a href="http://www.universocobol.com/search/label/ZOS">entorno ZOS</a>. De una forma u otra, será muy beneficioso para vosotros que aprendáis a usarla (cuanto antes mejor).<br />
<br />
Y
eso es todo. Por mi parte, ya no me queda nada más que comentaros sobre
la opción de Planificación de Control-M. Ya sabéis, las dudas podéis
dejarlas aquí abajo y yo trataré de contestaros en cuanto tenga un hueco
disponible.<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-46748631405113717082016-04-29T12:00:00.000+02:002016-04-29T12:00:13.085+02:00Programador de vacaciones<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/-sy05xZCmEII/VvFvodL5a8I/AAAAAAAALDs/3IJAPkl6BBExpU4gVRId0plOI9s2RjCpw/s1600/Programador%2Bde%2BVacaciones.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="285" src="https://3.bp.blogspot.com/-sy05xZCmEII/VvFvodL5a8I/AAAAAAAALDs/3IJAPkl6BBExpU4gVRId0plOI9s2RjCpw/s400/Programador%2Bde%2BVacaciones.jpg" width="400" /></a></div>
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-14898379764582337972016-04-25T12:00:00.000+02:002016-04-25T12:00:06.642+02:00Control-M: Planificación de ejecuciones Batch (1)La herramienta Control-M es una de las más utilizadas para la definición y gestión de cadenas de fases batch en el mundo Host. Por supuesto, existen otras alternativas, pero esta aplicación es una de las más extendidas entre los clientes importantes. Dentro de sus diversas opciones, destaca la funcionalidad de Scheduling Definition Facility. Hoy vamos a echarle un vistazo.<br />
<br />
<h2>
<span style="font-size: large;">Control-M para gestión de cadenas Batch </span></h2>
<br />
Los que ya tengan algo de experiencia en Mainframe estarán de acuerdo conmigo en que <span style="color: cyan;"><b>Control-M</b></span> es una <a href="http://www.universocobol.com/search/label/Herramientas">herramienta Host</a> muy útil a la hora de enfrentarse con cadenas batch. Nos permite tanto<b> definir los atributos con los que se va a ejecutar una determinada fase como examinar los resultados de la ejecución de un JCL</b>. Ambas tareas nos van a servir para ahorrar mucho tiempo de análisis.<br />
<br />
La verdad es que ya he trabajado en varias <span style="color: magenta;"><b>aplicaciones Host</b></span> de clientes distintos y, hasta ahora, en todos ellos he tenido disponible el Control-M. Os digo esto para que os hagáis una idea de lo rentable que puede ser aprender a manejar esta herramienta. En cualquier caso, creo que tarde o temprano tendréis que enfrentaros con ella.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-6dCzsLBuRQY/VkmyVWh83_I/AAAAAAAAJII/_TjQ0PmDypk/s1600/Control-M%2BMenu%2BPrincipal.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="380" src="https://4.bp.blogspot.com/-6dCzsLBuRQY/VkmyVWh83_I/AAAAAAAAJII/_TjQ0PmDypk/s640/Control-M%2BMenu%2BPrincipal.png" width="640" /></a></div>
<br />
<br />
<br />
En la imagen anterior podemos ver el aspecto del menú principal (POM) de la <span style="color: orange;"><b>aplicación IOA</b></span> (<a href="https://webapps.bmc.com/DocCenter/index.jsp?topic=/com.bmc.doccenter.bssjobopt.refGuide/GUID-46B50853-D0C6-4335-B172-7EDAEE21CF5D.html">Integrated Operations Architecture</a>). Como podemos ver, en mi instalación actual <b>el POM está dividido en 4 bloques diferenciados: IOA, Control-D, Control-O y Control-M & CTM/Restart</b>. Como no es difícil deducir, nuestra herramienta Control-M es la correspondiente al cuarto bloque mostrado en el menú.<br />
<br />
<h2>
</h2>
<h2>
<span style="font-size: large;">Control-M: Scheduling Definition Facility</span></h2>
<br />
A continuación, vamos a ir viendo los pasos que hay que seguir para navegar por la opción 2 de Control-M, denominada <span style="color: lime;"><b>JOB SCHEDULE DEF</b></span>. Esta funcionalidad nos sirve para definir (o consultar) los atributos asociados a la ejecución de las fases de una cadena batch. Además, nos puede ser de gran ayuda a la hora de determinar las causas de un error en el <a href="http://www.universocobol.com/search/label/JCL">procesamiento de un Job</a>.<br />
<br />
Los pasos a seguir para operar correctamente con la facilidad JOB SCHEDULE DEF son los siguientes.<br />
<br />
1º) Entrar en el <b>menú principal de Control-M</b>. En mi instalación, esto se hace entrando en la aplicación IOA desde <a href="http://www.universocobol.com/search/label/ISPF">ISPF</a> mediante el <span style="color: magenta;"><b>comando TSO IOA</b></span>. Posiblemente en vuestra instalación esté configurado de otra forma.<br />
<br />
2º) Seleccionar la opción <b>2 - JOB SCHEDULE DEF</b>. Una vez que estamos dentro de la arquitectura IOA, dicha opción la encontraremos en el bloque Control-M.<br />
<br />
3º) En la ventana de entrada de <span style="color: cyan;"><b>Scheduling Definition Facility</b></span> debemos provisionar la <b>línea LIBRARY</b>. En ella debemos introducir la <a href="http://www.universocobol.com/2013/09/creacion-de-una-libreria-cobol-en-tso.html">Librería</a> en la que, en nuestra instalación, se estén guardando los atributos de los procesamientos de cadenas batch.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-WzYWwm5iIYo/VknKi_UpGbI/AAAAAAAAJIY/yfwhleDJ2wU/s1600/Control-M%2BJob%2BSchedule%2BDef.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-WzYWwm5iIYo/VknKi_UpGbI/AAAAAAAAJIY/yfwhleDJ2wU/s640/Control-M%2BJob%2BSchedule%2BDef.png" width="640" /></a></div>
<br />
<br />
Como vemos, en el ejemplo anterior hemos introducido la librería ASPR.V7R01.A8.TRAN.SCHED en la línea LIBRARY. A continuación, pulsamos INTRO.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">LIBRARY ===> ASPR.V7R01.A8.TRAN.SCHED</span></span><br />
<br />
4º) Accedemos a la consulta en la que se muestra la <b>Lista de Cadenas Batch</b> que se están ejecutando en nuestra aplicación o en nuestro módulo.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-29ErLjVCJv4/VknO0NwSdQI/AAAAAAAAJIk/2MXWiB35lgQ/s1600/Control-M%2BJob%2BSchedule%2BDef%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-29ErLjVCJv4/VknO0NwSdQI/AAAAAAAAJIk/2MXWiB35lgQ/s640/Control-M%2BJob%2BSchedule%2BDef%2Bv2.png" width="640" /></a></div>
<br />
<br />
5º) Seleccionamos una Cadena con 'S' y pulsamos <span style="color: cyan;"><b>INTRO</b></span>. De este modo, accederemos a la ventana en la que se muestra el <b>desglose de Fases Batch</b> en las que se descompone dicha cadena.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-BL0mE_8lkp8/VknO5O3ZiVI/AAAAAAAAJIw/486JPL4xagY/s1600/Control-M%2BJob%2BSchedule%2BDef%2Bv3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-BL0mE_8lkp8/VknO5O3ZiVI/AAAAAAAAJIw/486JPL4xagY/s640/Control-M%2BJob%2BSchedule%2BDef%2Bv3.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
6º) Aquí podemos<b><span style="color: lime;"> seleccionar una Fase</span></b> con 'S' y pulsar INTRO. Así accedemos a la <b>consulta de definición de atributos</b> del proceso batch elegido. Como veremos a continuación, esta consulta se divide en 4 ventanas.<br />
<br />
* Definición de Fase Batch - <u>Atributos 1</u> <br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-QM3TlCrFgmI/VknRGd5dQNI/AAAAAAAAJJA/vpQgOQVWxvY/s1600/Control-M%2BJSD%2BDefinicion.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-QM3TlCrFgmI/VknRGd5dQNI/AAAAAAAAJJA/vpQgOQVWxvY/s640/Control-M%2BJSD%2BDefinicion.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
* Definición de Fase Batch - <u>Atributos 2</u><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-QPtiiOTcB6U/Vknt5PYnK9I/AAAAAAAAJJg/CllUIhKw6_Q/s1600/Control-M%2BJSD%2BDescripcion%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-QPtiiOTcB6U/Vknt5PYnK9I/AAAAAAAAJJg/CllUIhKw6_Q/s640/Control-M%2BJSD%2BDescripcion%2Bv2.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
* Definición de Fase Batch - <u>Atributos 3</u><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-Xc1Kh20TyUI/VknuxYgS0HI/AAAAAAAAJJo/0HLJToQs_20/s1600/Control-M%2BJSD%2BDefinicion%2Bv3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-Xc1Kh20TyUI/VknuxYgS0HI/AAAAAAAAJJo/0HLJToQs_20/s640/Control-M%2BJSD%2BDefinicion%2Bv3.png" width="640" /></a></div>
<br />
<br />
<br />
* Definición de Fase Batch - <u>Atributos 4</u><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-AiTiCIfrE84/VknvMR1prSI/AAAAAAAAJJw/5lc0O83OF6A/s1600/Control-M%2BJSD%2BDefinicion%2Bv4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-AiTiCIfrE84/VknvMR1prSI/AAAAAAAAJJw/5lc0O83OF6A/s640/Control-M%2BJSD%2BDefinicion%2Bv4.png" width="640" /></a></div>
<br />
<br />
<br />
En todas estas ventanas podremos ir viendo los atributos con los que se ha definido la ejecución de la Fase Batch seleccionada. Si el perfil de nuestro usuario nos lo permite, aquí también tendremos la opción de <span style="color: orange;"><b>modificar los parámetros</b></span> que deseemos. En cualquier caso, esta información nos será de mucha utilidad a la hora de analizar los <a href="http://www.universocobol.com/2013/09/posibles-errores-rc-de-un-jcl.html">errores de ejecución de la fase</a>.<br />
<br />
Una vez vista la opción de planificación de ejecuciones batch (JOB SCHEDULE DEF), ya nos debería quedar bastante clara la forma de consultar los atributos asociados a una determinada fase. Dicho esto, el próximo día (en un nuevo post) examinaremos una función que nos permitirá acceder a un esquema gráfico de la cadena batch seleccionada. Esta funcionalidad será del agrado de los que gusten de esquemas visuales, aunque no debemos olvidar que nos encontramos en plataforma Mainframe y, por tanto, no podemos esperar nada demasiado sofisticado.<br />
<br />
Pues nada, eso es todo por hoy. Como siempre os digo, quedáis invitados a la segunda parte del artículo, donde trataremos de ampliar un poco más nuestro conocimiento de la herramienta Control-M. Espero veros por allí...<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com9tag:blogger.com,1999:blog-8613600796016988320.post-57835114150143180452016-04-18T12:00:00.000+02:002016-04-18T12:00:00.168+02:00Ver fichero VSAM mediante DITTOLa aplicación <a href="http://www-03.ibm.com/software/products/es/ditto">DITTO/ESA for OS/390</a> es una herramienta de IBM muy útil a la hora de tratar con registros de ficheros VSAM. En el blog ya hemos visto muchas otras formas de <span style="color: magenta;"><b>visualizar el contenido de un VSAM</b></span>, pero nunca viene mal disponer de un acceso alternativo. Quizás nos sea útil en el futuro.<br />
<br />
<h2>
<span style="font-size: large;">Ver fichero VSAM mediante DITTO</span></h2>
<br />
Como ya sabemos, <b>el contenido de los ficheros VSAM no se consulta del mismo modo que el de los ficheros secuenciales estándar</b>. En general, para acceder a sus <a href="http://www.universocobol.com/2014/06/tipos-de-registros-de-ficheros.html">registros</a> tenemos que hacer uso de herramientas específicas para dicha tarea. A este respecto, hoy en particular vamos a revisar la aplicación "<span style="color: cyan;"><b>DITTO/ESA for OS/390</b></span>" de IBM.<br />
<br />
Es posible que muchos de vosotros no dispongáis de esta <span style="color: orange;"><b>herramienta</b></span> en vuestro trabajo. Si es así, comentadlo con vuestros responsables o con vuestro cliente. En muchas ocasiones <b>no suelen poner pegas para incluir esta aplicación en la instalación</b> e incluso, si tenéis suerte, puede que ya esté instalada y simplemente no tuviérais constancia de ello.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-WKYwuU7-6TM/VkNVXgfWtDI/AAAAAAAAJD8/_MvA0rtVduA/s1600/DITTO-ESA%2BVSAM%2BMenu%2Bprincipal.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-WKYwuU7-6TM/VkNVXgfWtDI/AAAAAAAAJD8/_MvA0rtVduA/s640/DITTO-ESA%2BVSAM%2BMenu%2Bprincipal.png" width="640" /></a></div>
<br />
La <span style="color: orange;"><b>herramienta DITTO/ESA</b></span> dispone de muchas funcionalidades, pero hoy en el post <b>vamos a centrarnos en la opción que nos permite visualizar el contenido de los ficheros VSAM</b>. Si trabajáis a menudo con <a href="http://www.universocobol.com/2014/05/tipos-de-ficheros-vsam.html">ficheros VSAM</a>, entonces este conocimiento os será muy útil. Si no los usáis demasiado, bueno, entonces es que estáis empezando en esto del mundo Host: pronto os cansaréis de operar con ellos.<br />
<br />
<h2>
<span style="font-size: large;">Opción DITTO para visualizar registros VSAM</span></h2>
<br />
A continuación, sin más demora, vamos ir viendo <b>los pasos que hay que seguir para visualizar registros VSAM mediante DITTO</b>. Intentaré hacerlo con el mayor detalle posible, para intentar evitar que os queden muchas dudas al respecto.<br />
<br />
1º) Accedemos al <span style="color: lime;"><b>menú principal </b></span>de DITTO/ESA for OS/390. Esto se hace de forma diferente en cada instalación, así que tendréis que preguntar a vuestros responsables de soporte.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-O2LCN4Vc9n4/VkNXZHcXd2I/AAAAAAAAJEE/8FvAQENUjMQ/s1600/DITTO-ESA%2BVSAM%2BMenu%2Bprincipal%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-O2LCN4Vc9n4/VkNXZHcXd2I/AAAAAAAAJEE/8FvAQENUjMQ/s640/DITTO-ESA%2BVSAM%2BMenu%2Bprincipal%2Bv2.png" width="640" /></a></div>
<br />
2º) Se selecciona la opción <span style="color: magenta;"><b>1 - BROWSE DATA</b></span> y pulsamos INTRO. De esta forma, accederemos a la ventana de visualización de datos.<br />
<br />
<a href="http://1.bp.blogspot.com/-3qqkKMqcjJc/VkNbN8dlI8I/AAAAAAAAJEQ/VTdSOT3wND0/s1600/DITTO-ESA%2BVSAM%2BBrowse%2BData.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-3qqkKMqcjJc/VkNbN8dlI8I/AAAAAAAAJEQ/VTdSOT3wND0/s640/DITTO-ESA%2BVSAM%2BBrowse%2BData.png" width="640" /></a> <br />
<br />
3º) Se selecciona la opción <span style="color: cyan;"><b>3 - VSAM DATA</b></span> y pulsamos INTRO. Así se accederá al menú de visualización.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-69uB4npm1Q0/VkNcacgBM_I/AAAAAAAAJEY/qXhsRJ9TADo/s1600/DITTO-ESA%2BVSAM%2BData%2BMenu.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-69uB4npm1Q0/VkNcacgBM_I/AAAAAAAAJEY/qXhsRJ9TADo/s640/DITTO-ESA%2BVSAM%2BData%2BMenu.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
4º) Procedemos a introducir el nombre del fichero VSAM buscado en el campo <span style="color: orange;"><b>DATA SET NAME</b></span>. Pulsamos INTRO y pasaremos a la ventana en la que se nos muestra el contenido del <a href="http://www.universocobol.com/2014/06/tipos-de-ficheros-secuenciales-cobol-y-2.html">fichero</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-pqcNFD2IJzk/VkNeZxqyBMI/AAAAAAAAJEk/hYFk3VVVcII/s1600/DITTO-ESA%2BVSAM%2BVisualizar.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-pqcNFD2IJzk/VkNeZxqyBMI/AAAAAAAAJEk/hYFk3VVVcII/s640/DITTO-ESA%2BVSAM%2BVisualizar.png" width="640" /></a></div>
<br />
<br />
Por ejemplo, en la imagen anterior vemos que se ha introducido el fichero VSAM con nombre 'JJLDB2.DSNDBD.JJATL23.JJFRLOTE.I0001.A001'. <br />
<br />
5º) Si ponemos M y pulsamos PF5, nos desplazaremos a la derecha hasta el final del <span style="color: lime;"><b>fichero VSAM</b></span>. De esta forma, los últimos campos de los registros quedarán visibles para nosotros.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-lBK3xaRy5C0/VkNi5RvSfrI/AAAAAAAAJEw/0Y_HMnMhhIQ/s1600/DITTO-ESA%2BVSAM%2BVisualizar%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-lBK3xaRy5C0/VkNi5RvSfrI/AAAAAAAAJEw/0Y_HMnMhhIQ/s640/DITTO-ESA%2BVSAM%2BVisualizar%2Bv2.png" width="640" /></a></div>
<br />
<br />
<br />
Siguiendo con el ejemplo anterior, en la imagen podemos ver los últimos campos del fichero VSAM con nombre 'JJLDB2.DSNDBD.JJATL23.JJFRLOTE.I0001.A001'.<br />
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca del Browse de DITTO</span></h2>
<br />
Siguiendo los pasos comentados anteriormente, <b>no deberíamos tener problema para ver el contenido de los ficheros VSAM mediante DITTO</b>. De todas formas, tal y como os he dicho más arriba, aquí lo más importante es que os digan cómo se puede acceder a la herramienta en vuestra instalación (o, si no disponéis de ella, que negociéis con vuestro cliente y que intentéis que os la proporcione).<br />
<br />
En el post de hoy hemos visto cómo usar la <span style="color: magenta;"><b>opción BROWSE del DITTO</b></span> para visualizar el contenido de los ficheros VSAM. Por supuesto,<b> la aplicación permite realizar funcionalidades adicionales como, por ejemplo, edición de datasets VSAM</b>. En futuros post os iré hablando sobre estas otras opciones.<br />
<br />
En el blog ya hemos ido hablando en repetidas ocasiones sobre diferentes herramientas que nos permiten <a href="http://www.universocobol.com/2014/11/ver-contenido-de-un-fichero-vsam-desde.html">acceder a ficheros VSAM</a>. Aunque normalmente nos bastará con disponer de una de ellas en nuestro trabajo, nunca viene mal conocer el mayor número posible de aplicaciones de <span style="color: cyan;"><b>tratamiento VSAM</b></span>. La razón de esta necesidad es que va a resultar complicado que nos encontremos con la misma herramienta en dos clientes diferentes.<br />
<br />
<a href="https://3.bp.blogspot.com/-3EU2ArzJH80/Vt6F6VDEVbI/AAAAAAAAK-4/up5_YGDLXTU/s1600/DITTO-ESA%2Bfor%2BOS-390.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://3.bp.blogspot.com/-3EU2ArzJH80/Vt6F6VDEVbI/AAAAAAAAK-4/up5_YGDLXTU/s1600/DITTO-ESA%2Bfor%2BOS-390.png" /></a> <br />
<br />
Conforme vayamos teniendo más experiencia en <a href="http://www.universocobol.com/search/label/Cobol">Cobol</a>, nos daremos cuenta de que la aplicación DITTO de IBM es bastante utilizada en el <span style="color: lime;"><b>mundo Host</b></span>. Así que, cuanto antes os pongáis con la tarea de aprender su funcionalidad, pues más fácil os resultará posteriormente empezar a trabajar con ella. Siempre hay que coger el toro por los cuernos...<br />
<br />
Pues nada, eso es lo que quería comentaros hoy con respecto a esta herramienta. Espero que todo haya quedado claro pero, si no es así, dejadme vuestras preguntas en el apartado de comentarios. Intentaré contestaros lo antes posible.<br />
<br />
Saludos.Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-35586419840892787442016-04-11T12:00:00.000+02:002016-04-11T12:00:18.394+02:00READ FILE: Leer fichero VSAM desde CobolUno de los problemas relevantes con los que nos vamos a encontrar a menudo es la necesidad de acceder a un <a href="http://www.universocobol.com/2014/05/tipos-de-ficheros-vsam.html">fichero VSAM</a> para leer su contenido desde un programa Cobol. Este acceso no es tan sencillo como la lectura de una tabla DB2 y, por tanto, para su implementación tendremos que utilizar <a href="http://www-01.ibm.com/support/knowledgecenter/SSAL2T_7.1.0/com.ibm.cics.tx.doc/reference/r_cics_supld_trans.html?lang=es">instrucciones CICS</a>. Pero bueno, no hay que dejarse amedrentar por ello y en este post trataremos de explicar en detalle cómo realizar dicha operativa.<br />
<br />
<h2>
<span style="font-size: large;">Leer fichero VSAM desde programa Cobol</span></h2>
<br />
En muchas ocasiones nos vamos a encontrar con que, desde un programa Cobol, tenemos que proceder a <b>leer información que no está almacenada en ninguna tabla DB2 y que, en cambio, está contenida en un fichero VSAM</b>. Para poder realizar esta función tendremos que recurrir a la instrucción CICS denominada <span style="color: magenta;"><b>READ FILE</b></span> (o, en su codificación antigua, <span style="color: lime;"><b>READ DATASET</b></span>). Se trata de uno de los comandos básicos de acceso a ficheros.<br />
<br />
<a href="http://4.bp.blogspot.com/-d7X_yJBMtk4/VjsOinCMCAI/AAAAAAAAI-E/y1MpoiJZQ6g/s1600/EXEC%2BCICS%2BREAD%2BFILE%2BVSAM.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="https://4.bp.blogspot.com/-d7X_yJBMtk4/VjsOinCMCAI/AAAAAAAAI-E/y1MpoiJZQ6g/s400/EXEC%2BCICS%2BREAD%2BFILE%2BVSAM.jpg" width="400" /></a> <br />
<br />
Para ver cómo se debería implementar esta actuación vamos a revisar un ejemplo con el que me encontré hace algún tiempo. En él se trataba de leer los registros contenidos en un <span style="color: cyan;"><b>fichero VSAM</b></span> denominado JJRPRTAK para luego tratarlos posteriormente en el programa Cobol.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">05 COM2EZ-CLAVE. <br /> 10 COM2EZ-EIBTASK PIC 9(7).<br /> 10 COM2EZ-JJEQ-IN-TIPELE PIC X. <br /> 10 COM2EZ-JJEQ-NU-EXTERN PIC 9(9).</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">05 W-RESP PIC S9(8) COMP VALUE ZEROES.</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">...</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">EXEC CICS <br /> READ FILE('JJRPRTAK') <br /> INTO(COM2EZ) </span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> <span style="font-family: "courier new" , "courier" , monospace;">LENGTH(COM2EZ-LONGITUD)</span> <br /> RIDFLD(COM2EZ-CLAVE<span style="font-family: "courier new" , "courier" , monospace;">)</span> <br /> RESP(W-RESP) <br />END-EXEC. </span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">IF W-RESP NOT = 0 <br /> MOVE W-CD-1 TO COM2JN-W-NMENSA <br /> MOVE W-CD-MENSAJE-E0301 TO COM2JN-W-MENSA(W-CD-1)<br /> PERFORM 9999-ERROR THRU 9999-ERROR-FIN <br />END-IF.</span></span> <br />
<br />
Como vemos, en el código anterior tenemos <span style="color: orange;"><b>dos partes diferenciadas</b></span>. En la primera parte aparece, <b>entre los marcadores EXEC CICS y END-EXEC, el comando READ FILE y las cláusulas de las que se compone</b>. Y en la segunda parte se muestra simplemente una de las formas (habría otras alternativas) en la que se podría implementar el <a href="http://www.universocobol.com/2015/03/tipos-de-error-db2-900-sqlcode.html">control de errores</a> asociado a la instrucción READ FILE.<br />
<br />
<a href="https://3.bp.blogspot.com/-wDTq6PJW7j4/VtagyZBMZ6I/AAAAAAAAK5o/mxYwTlLlF6Y/s1600/Instruccion%2BCICS%2BREAD%2BFILE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="https://3.bp.blogspot.com/-wDTq6PJW7j4/VtagyZBMZ6I/AAAAAAAAK5o/mxYwTlLlF6Y/s400/Instruccion%2BCICS%2BREAD%2BFILE.png" width="400" /></a> <br />
<br />
<h2>
<span style="font-size: large;">Cláusulas de la instrucción CICS READ FILE </span></h2>
<br />
A la hora de implementar un READ FILE, lo más importante es que tengamos claro a qué concepto corresponde cada una de las cláusulas del <a href="http://www.universocobol.com/2014/11/transacciones-basicas-del-entorno-cics.html">comando CICS</a>. A continuación, vamos a ir examinando las sentencias de las que se compone la instrucción READ DATASET del ejemplo anterior.<br />
<br />
1º) <b>Instrucción READ</b>: Este comando se emplea para indicarle al CICS que vamos a proceder con la lectura de un fichero VSAM.<br />
<br />
2º) <b>Cláusula FILE (o DATASET)</b>: En esta cláusula tenemos que indicar el <span style="color: lime;"><b>nombre del fichero</b></span> que queremos leer con la instrucción READ.<br />
<br />
3º) <b>Cláusula INTO</b>: Aquí indicaremos el nombre de la variable del <span style="color: orange;"><b>área de datos</b></span> en la que queremos que se almacenen los campos del registro recuperado del fichero VSAM.<br />
<br />
4º) <b>Cláusula LENGTH</b>: Aquí tendremos que especificar la <span style="color: cyan;"><b>longitud del área de datos</b></span> en la que se va a capturar el registro del fichero VSAM.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://2.bp.blogspot.com/-JHKQBDw5PlM/VtajTwesUuI/AAAAAAAAK6A/8azmTYKJuxA/s1600/CICS%2BREAD%2BFILE%2BVSAM%2BLongitud.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://2.bp.blogspot.com/-JHKQBDw5PlM/VtajTwesUuI/AAAAAAAAK6A/8azmTYKJuxA/s400/CICS%2BREAD%2BFILE%2BVSAM%2BLongitud.png" width="400" /></a></div>
<br />
5º) <b>Cláusula RIDFLD</b>: En esta importante cláusula tendremos que indicar el nombre de la variable de la clave por la que se tiene que <span style="color: magenta;"><b>buscar el registro</b></span> en el fichero VSAM. Esto es, el READ del CICS buscará el registro cuya clave coincida con la que hemos especificado en RIDFLD y, una vez encontrado, nos lo devolverá para que almacenemos sus campos en la variable que habíamos indicado en INTO.<br />
<br />
6º) <b>Cláusula RESP</b>: Aquí indicaremos el nombre de la variable en la que queremos capturar el <span style="color: cyan;"><b>código de retorno</b></span> de la ejecución del comando CICS READ FILE.<br />
<br />
7º) <b>Control de errores</b>: Finalmente, en la última intrucción IF validaremos si el retorno ha sido igual a cero (ejecución correcta) o distinto de cero (ejecución errónea). En este último caso procederemos a ejecutar el control de errores que consideremos necesario.<br />
<br />
Una vez rellenadas las cláusulas anteriores, nuestra declaración EXEC CICS debería ejecutarse sin problema alguno. Como resultado de la misma se accedería al <a href="http://www.universocobol.com/search/label/Ficheros">fichero</a> indicado en FILE mediante la clave especidficada en la<span style="color: magenta;"><b> <span style="color: lime;">cláusula RIDFLD</span></b></span>. Y posteriormente se cargaría el contenido de un registro del fichero VSAM en la variable especificada en la cláusula INTO, siempre y cuando se obtenga un código de retorno nulo en RESP.<br />
<br />
<a href="https://4.bp.blogspot.com/-tPEJNUux9JQ/Vtak9Ejc1YI/AAAAAAAAK6M/WcTiEeJeMK8/s1600/Instruccion%2BCICS%2BREAD%2BFILE%2Bv2.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="206" src="https://4.bp.blogspot.com/-tPEJNUux9JQ/Vtak9Ejc1YI/AAAAAAAAK6M/WcTiEeJeMK8/s400/Instruccion%2BCICS%2BREAD%2BFILE%2Bv2.gif" width="400" /></a> <br />
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca de la instrucción READ FILE</span></h2>
<br />
La instrucción READ FILE nos será muy útil en los casos en los que tengamos necesidad de acceder a los ficheros VSAM de una aplicación. Recordemos que los accesos a las <span style="color: orange;"><b>tablas DB2</b></span> deben hacerse de otra forma diferente, tal y como ya vimos en el blog hace algún tiempo. Pero en el mundo host tan importantes son los VSAM como el DB2.<br />
<br />
Hay que tener en cuenta que, al tratarse de un comando CICS, <b>la instrucción READ FILE también podría ejecutarse directamente desde el entorno CICS</b>. Esto se haría mediante el empleo de la <a href="http://www.universocobol.com/2014/12/transaccion-ceci-para-ejecucion-de_26.html">transacción CECI</a>. Tal y como ya sabemos, CECI nos permite, entre otras cosas, acceder tanto a ficheros VSAM como a <a href="http://www.universocobol.com/2015/02/tipos-de-colas-cics-y-2.html">colas TS y colas TD</a>.<br />
<br />
Si provisionamos las cláusulas tal y como hemos especificado más arriba, no deberíamos tener ningún problema a la hora de ejecutar nuestro <span style="color: lime;"><b>programa Cobol</b></span>. Pero, eso sí, si nunca habéis usado EXEC CICS READ FILE, entonces tendréis que tener un poco de paciencia, ya que a nadie le suelen funcionar los comandos CICS la primera vez que los usa.<br />
<br />
<a href="https://4.bp.blogspot.com/-UzXPbuaohN8/VtaiQPvVfSI/AAAAAAAAK50/p8qoxlrML-0/s1600/CICS%2BREAD%2BFILE%2BVSAM%2BCobol.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://4.bp.blogspot.com/-UzXPbuaohN8/VtaiQPvVfSI/AAAAAAAAK50/p8qoxlrML-0/s400/CICS%2BREAD%2BFILE%2BVSAM%2BCobol.jpg" width="400" /></a> <br />
<br />
En un futuro seguiremos viendo instrucciones CICS adicionales para operar con los ficheros VSAM desde programas Cobol. Aparte de leer, siempre son necesarias las operaciones de actualización, de inserción y de borrado. Pero, como digo, eso lo dejaremos para más adelante.<br />
<br />
Así que eso es todo por hoy. Espero que os haya quedado claro cómo debemos emplear el comando CICS READ FILE. Si seguís teniendo alguna duda, la podéis dejar en el apartado de comentarios.<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-17912445580302509192016-04-04T12:00:00.000+02:002016-04-04T12:25:22.370+02:00Query 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.<br />
<br />
En la primera parte del post nos centramos en analizar cómo debía codificarse una query con la cláusula UNION (ver post <a href="http://www.universocobol.com/2016/03/query-sql-con-union-y-con-union-all-1.html">Query SQL con UNION y con UNION ALL - 1</a>). 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.<br />
<br />
<h2>
<span style="font-size: large;">Diferencia entre UNION ALL y UNION </span></h2>
<br />
Más arriba he hablado de la <a href="http://www-01.ibm.com/support/docview.wss?uid=swg21621258">cláusula UNION ALL</a>
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.<br />
<br />
La ejecución de la query con <b>UNION nos va a extraer el listado de datos eliminando todos aquellos registros que estén duplicados</b>. ¿Cuáles se consideran duplicados? Pues aquellos registros que tengan provisionados <span style="color: magenta;"><b>valores idénticos</b></span> en todos aquellos campos especificados en la <a href="http://www.universocobol.com/2013/10/sentencia-select-para-una-tabla-db2.html">cláusula SELECT</a> (si hemos puesto un * entonces serían todos los campos del registro).<br />
<br />
Siguiendo con este razonamiento, la ejecución de la misma query con <b>UNION ALL nos va a extraer el listado de datos incluyendo todos aquellos registros que estén duplicados</b>. Por eso decía que, en general, preferiremos usar el comando UNION. Eso sí, alguna vez puede que necesitemos recuperar el <span style="color: lime;"><b>listado completo</b></span> (con todos sus duplicados) y para eso nos vendrá muy bien el comando UNION ALL.<br />
<br />
<a href="https://2.bp.blogspot.com/-No5aPyuPQ4s/VswX70WJs0I/AAAAAAAAK2o/219ya2rAEtY/s1600/Rendimiento%2BUNION%2BALL%2Bv2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="https://2.bp.blogspot.com/-No5aPyuPQ4s/VswX70WJs0I/AAAAAAAAK2o/219ya2rAEtY/s400/Rendimiento%2BUNION%2BALL%2Bv2.png" width="400" /></a> <br />
<br />
En el ejemplo anterior, el uso de UNION ALL no cambiaría demasiado el aspecto del <span style="color: orange;"><b>código SQL</b></span>. Quedaría del siguiente modo.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)<br /><br /> AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN <br /> AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"><br /></span></span>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> UNION ALL</span></span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)<br /> <br /> AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1 <br /> AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1 <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span></span><br />
<br />
Como vemos, se trata prácticamente de la misma query. Simplemente tendremos que decidir previamente si necesitamos los <span style="color: cyan;"><b>registros duplicados</b></span> o no. <br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/-lFDJqu08Qvk/VswXSwXawYI/AAAAAAAAK2Y/C_udmkhcJFE/s1600/Queries%2Bcomplejas%2BSQL%2BUNION%2BALL%2Bv2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="166" src="https://3.bp.blogspot.com/-lFDJqu08Qvk/VswXSwXawYI/AAAAAAAAK2Y/C_udmkhcJFE/s400/Queries%2Bcomplejas%2BSQL%2BUNION%2BALL%2Bv2.png" width="400" /></a></div>
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca de UNION ALL y UNION</span></h2>
<br />
Tal y como hemos podido comprobar a lo largo del post, <b>la
cláusula UNION nos puede resultar muy útil en aquellos casos en los que
tengamos que mejorar el rendimiento de una query compleja</b>. 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 <a href="http://www.universocobol.com/search/label/Cobol">objetos Cobol</a>.<br />
<br />
Normalmente, yo suelo utilizar <span style="color: lime;"><b>UNION</b></span> para problemas de rendimiento. Por contra, dejo <span style="color: magenta;"><b>UNION ALL</b></span> para casuísticas muy especiales en las que necesito conocer el número de registros que hay en una determinada <a href="http://www.universocobol.com/search/label/DB2">tabla DB2</a>. Si puedo prescindir de dicho dato, entonces prefiero obtener los listados sin registros duplicados.<br />
<br />
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.<br />
<br />
<a href="https://2.bp.blogspot.com/-Zjk8PaOctdY/VswYa2zAdcI/AAAAAAAAK2k/fvQWTPbpMZQ/s1600/Listado%2Bduplicado%2BUNION%2BALL%2Bv2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="317" src="https://2.bp.blogspot.com/-Zjk8PaOctdY/VswYa2zAdcI/AAAAAAAAK2k/fvQWTPbpMZQ/s320/Listado%2Bduplicado%2BUNION%2BALL%2Bv2.png" width="320" /></a> <br />
<br />
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 <span style="color: lime;"><b>operadores OR</b></span>. Normalmente, no es difícil fraccionar estas sentencias en varias queries más simples.<br />
<br />
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...<br />
<br />
Saludos.Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-71958321087332652482016-03-25T12:00:00.000+01:002016-03-25T12:00:26.791+01:00Computadoras de alto rendimiento<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://1.bp.blogspot.com/-5Wmjt_Zux8E/VsIDfNRtqVI/AAAAAAAAKwg/4Dq3YbfQkAc/s1600/Rendimiento%2Bcomputadora.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="313" src="https://1.bp.blogspot.com/-5Wmjt_Zux8E/VsIDfNRtqVI/AAAAAAAAKwg/4Dq3YbfQkAc/s400/Rendimiento%2Bcomputadora.jpg" width="400" /></a></div>
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-84009064344977819482016-03-21T12:00:00.000+01:002016-03-21T12:00:05.561+01:00Query SQL con UNION y con UNION ALL (1)En muchas ocasiones, tras implementar un determinado <a href="https://en.wikipedia.org/wiki/IBM_SQL/DS">código SQL</a>, 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.<br />
<br />
<h2>
<span style="font-size: large;">Rendimiento de Query SQL con UNION</span></h2>
<br />
La instrucción <b>UNION nos va a permitir integrar las extracciones realizadas por dos queries distintas</b>. 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.<br />
<br />
Por lo general (lo he podido comprobar en mi propia experiencia), una <a href="http://www.universocobol.com/search/label/SQL">declaración SQL</a> mediante UNION suele tener <span style="color: cyan;"><b>tiempos de ejecución</b></span> 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 <span style="color: orange;"><b>comando EXPLAIN</b></span>, así que no merece la pena complicarse la vida.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://2.bp.blogspot.com/-iTVEJdeqzPk/VsbKLpKcPsI/AAAAAAAAK0E/v34w09zTlBA/s1600/Query%2BSQL%2Bcon%2BUNION.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="https://2.bp.blogspot.com/-iTVEJdeqzPk/VsbKLpKcPsI/AAAAAAAAK0E/v34w09zTlBA/s400/Query%2BSQL%2Bcon%2BUNION.jpg" width="400" /></a></div>
<br />
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.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> ((A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> OR (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1))</span></span><br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"><br /> AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN <br /> AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN <br /> AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1 <br /> AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1 <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span></span> <br />
<br />
Aparentemente, esta query tiene un aspecto muy compacto y parece bien codificada pero, por desgracia, sus tiempos de ejecución eran superiores a <span style="color: magenta;"><b>100 milisegundos</b></span>. 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.<br />
<br />
<h2>
<span style="font-size: large;">¿Cómo codificar una Query SQL con UNION?</span></h2>
<br />
Una vez vista la query compleja, vamos a examinar cómo se podría <span style="color: orange;"><b>mejorar el rendimiento</b></span> de la misma mediante UNION. Para ello, lo que <b>tendríamos que determinar es cómo se podría dividir la query inicial en varias subqueries más sencillas</b>, de manera que posteriormente podamos unir estas <a href="http://www.universocobol.com/2015/04/como-crear-una-subquery-db2-con-sql.html">subextracciones</a> mediante la cláusula UNION.<br />
<br />
En el ejemplo que nos ocupa, vemos que se está usando el operador OR en la <span style="color: lime;"><b>cláusula WHERE</b></span>. 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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/-FfkKStVtvXo/VsbMfW8N0ZI/AAAAAAAAK0Q/HsXzHS6W_xM/s1600/Query%2BSQL%2Bcon%2BUNION%2Bv2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-FfkKStVtvXo/VsbMfW8N0ZI/AAAAAAAAK0Q/HsXzHS6W_xM/s400/Query%2BSQL%2Bcon%2BUNION%2Bv2.png" width="370" /></a></div>
<br />
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.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)<br /><br /> AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN <br /> AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span> </span><br />
<br />
Y la segunda parte del OR sería esta.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)<br /> <br /> AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1 <br /> AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1 <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span> </span> <br />
<br />
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 <span style="color: orange;"><b>instrucción UNION</b></span> entre las dos queries hijas del siguiente modo.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> ( A.JJTU_CO_INTERN = 'Z.BR' AND A.JJCA_CO_INTERN = 1)<br /><br /> AND A.JJTU_CO_INTERN = B.JJTU_CO_INTERN <br /> AND A.JJCA_CO_INTERN = B.JJCA_CO_INTERN <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"><br /></span></span>
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> UNION</span></span><br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;"><span style="color: lime;"> SELECT * <br /> FROM JJDB22.JJETRAT0 A, JJDB22.JJTRAMT0 B <br /> WHERE <br /> (A.JJTU_CO_INTERN_1 = 'Z.BR' AND A.JJCA_CO_INTERN_1 = 1)<br /> <br /> AND A.JJTU_CO_INTERN_1 = B.JJTU_CO_INTERN_1 <br /> AND A.JJCA_CO_INTERN_1 = B.JJCA_CO_INTERN_1 <br /> AND A.JJAM_NU_INTERN = B.JJAM_NU_INTERN </span> </span> <br />
<br />
El listado extraído por el UNION anterior <b>es idéntico al que hubiésemos obtenido mediante la ejecución de la query inicial más compleja</b>. La única diferencia es que, mediante el uso del UNION, hemos conseguido que su <span style="color: cyan;"><b>tiempo de ejecución</b></span> caiga por debajo de los 100 milisegundos y, por tanto, que ya tengamos entre nuestras manos un código adecuado para entregar al cliente.<br />
<br />
-------------------------------------------------------------------------------------------------------------------------------<br />
<i><b>Tip</b>: Aquí te explico <a href="http://www.universocobol.com/2015/11/como-almacenar-queries-en-qmf.html">cómo almacenar queries en QMF</a> y también <a href="http://www.universocobol.com/2015/11/como-recuperar-queries-en-qmf.html">cómo recuperar queries en QMF</a>. </i><br />
------------------------------------------------------------------------------------------------------------------------------- <br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/--rKmFmkkX0k/VswUvXG16bI/AAAAAAAAK2E/7PD13g3TZvc/s1600/Listado%2Bduplicado%2BUNION%2BALL%2Bv2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="282" src="https://3.bp.blogspot.com/--rKmFmkkX0k/VswUvXG16bI/AAAAAAAAK2E/7PD13g3TZvc/s400/Listado%2Bduplicado%2BUNION%2BALL%2Bv2.jpg" width="400" /></a></div>
<br />
<br />
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-1639139017880542742016-03-14T12:00:00.000+01:002016-03-14T12:00:12.595+01:00Transacción CMAC: Mensajes de error CICSLa transacción CMAC de CICS es una herramienta muy sencilla, pero que nos va a permitir acceder a una explicación detallada del error CICS que nos esté bloqueando el avance en un momento dado. Aunque su uso no supone complejidad alguna, a mi siempre me gusta incluirla en la lista de<a href="http://www-01.ibm.com/support/knowledgecenter/SSAL2T_7.1.0/com.ibm.cics.tx.doc/reference/r_cics_supld_trans.html?lang=es"> transacciones básicas CICS</a>, fundamentalmente debido a su gran utilidad. Estoy seguro de que a vosotros también os gustará disponer de esta ayuda en vuestra instalación.<br />
<br />
<h2>
<span style="font-size: large;">Transacción CMAC: Mensajes de error</span></h2>
<br />
En líneas generales, podemos decir que la <span style="color: cyan;"><b>transacción CMAC</b></span> nos <b>permite introducir un determinado código de error y, a partir de él, nos va a devolver una explicación del mensaje de error</b>. También nos proporcionará algunas directrices de cómo podríamos proceder para tratar de subsanar el problema con el que nos hemos encontrado. Se trata, por tanto, de una base de datos de <span style="color: orange;"><b>errores CICS</b></span>.<br />
<br />
A continuación, vamos a enumerar los pasos necesarios para poder recuperar la información mencionada. Son los siguientes.<br />
<br />
1º) En primer lugar, procedemos a entrar en la <a href="http://www.universocobol.com/search/label/CICS">sesión CICS</a> y, una vez dentro, introducimos la transacción CMAC.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-3lyQTZntcYE/VjhnM2BDj-I/AAAAAAAAAoQ/rEvvJM8W2FU/s1600/Transaccion%2BCMAC.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-3lyQTZntcYE/VjhnM2BDj-I/AAAAAAAAAoQ/rEvvJM8W2FU/s640/Transaccion%2BCMAC.png" width="640" /></a></div>
<br />
<br />
2º) Tras pulsar INTRO, se nos desplegará la <span style="color: lime;"><b>ventana inicial</b></span> de la herramienta, en donde aparecen dos campos pendientes de provisionar: COMPONENT ID y MESSAGE NUMBER.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-8dHosawGJoQ/VjiDbXImM1I/AAAAAAAAAog/gWa8RYfccOw/s1600/Transaccion%2BCMAC%2Bv3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-8dHosawGJoQ/VjiDbXImM1I/AAAAAAAAAog/gWa8RYfccOw/s640/Transaccion%2BCMAC%2Bv3.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
En el campo <b>COMPONENT ID tendremos que indicar la tipología del error y en MESSAGE NUMBER habrá que especificar el código numérico</b> del mensaje de error o aviso para el que queremos conocer más detalles. Por ejemplo, en la imagen anterior hemos introducido "TC" y "1060" (correspondientes al error CICS DFHTC1060).<br />
<br />
3º) Si insertamos COMPONENT ID y MESSAGE NUMBER y, a continuación, pulsamos INTRO, la aplicación nos llevará a la ventana de <span style="color: magenta;"><b>detalle del mensaje</b></span>.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-o-IT8RFOhvQ/VjiFkx5I-iI/AAAAAAAAAos/7AYhQRXbSds/s1600/Transaccion%2BCMAC%2Bv4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://3.bp.blogspot.com/-o-IT8RFOhvQ/VjiFkx5I-iI/AAAAAAAAAos/7AYhQRXbSds/s640/Transaccion%2BCMAC%2Bv4.png" width="640" /></a></div>
<br />
<br />
En el ejemplo podemos ver que en dicha ventana se muestra el título DFHTC1060 APPLID INSUFFICIENT STORAGE - CODE(X'CODE') IN MODULE DFHTCRP. En el informe nos aparecen varios apartados (EXPLANATION, SYSTEM ACTION, USER RESPONSE, DESTINATION, MODULE y MESSAGE INSERTS) en los que se nos va explicando detalladamente en qué consiste el error y cuáles son las medidas que podemos tomar para tratar de subsanarlo.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-qEGsoG59iRY/VjiHUAm132I/AAAAAAAAAo4/F3ZE7Ln1E4s/s1600/Transaccion%2BCMAC%2Bv5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-qEGsoG59iRY/VjiHUAm132I/AAAAAAAAAo4/F3ZE7Ln1E4s/s640/Transaccion%2BCMAC%2Bv5.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h2>
<span style="font-size: large;">Conclusiones sobre la Transacción CMAC</span></h2>
<br />
Y
no hay mucho más que comentar acerca de esta transacción. Se trata de
una herramienta de uso sencillo y con un objetivo muy definido. Eso sí,
las <span style="color: orange;"><b>explicaciones de los errores</b></span> son detalladas y útiles. En más de una
ocasión os puede dar buenas ideas acerca de cómo superar ese error CICS
que os está impidiendo avanzar tanto con el desarrollo de vuestros <a href="http://www.universocobol.com/search/label/Cobol">módulos Cobol</a> como con la implementación de las <a href="http://www.universocobol.com/search/label/JCL">fases JCL</a>.<br />
<br />
Eso sí, verificad que en vuestra instalación está disponible. He comprobado que algunas empresas se olvidan de instalar CMAC y, entonces, no podréis <span style="color: cyan;"><b>acceder a esta ayuda</b></span> en vuestro día a día. Si tenéis la posibilidad, pedidle a vuestro cliente que lo instale en el entorno.<br />
<br />
Como he dicho al principio, aunque en muchos listados no aparezca,<b> yo siempre incluyo a CMAC entre las transacciones básicas de CICS</b>. Ya sé que es una transacción muy sencilla, pero el hecho de que una herramienta sea simple no significa que no sea importante para nuestro desempeño. Ya lo iréis comprobando con el tiempo.<br />
<br />
Y eso es todo por lo que respecta a CMAC. Supongo que os habrá quedado bastante claro el funcionamiento de la transacción pero, si no es así, no dudéis en dejarme los comentarios que creáis convenientes...<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-24580671175392636592016-03-07T12:00:00.000+01:002016-03-07T15:29:53.423+01:00EXPLAIN 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.<br />
<br />
En la primera parte del presente artículo estuvimos viendo cómo lanzar un EXPLAIN desde el editor de nuestro programa Cobol (ver post <a href="http://www.universocobol.com/2016/02/explain-con-ca-sql-ease-for-db2-for-zos.html">EXPLAIN con CA SQL-Ease for DB2 for ZOS - 1</a>). 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. <br />
<br />
<h2>
<span style="font-size: large;">Lanzar EXPLAIN desde ACCESS PATH ANALYSIS</span></h2>
<br />
Con lo examinado en el anterior post ya podemos dar por vistos los pasos que tenemos que seguir para ejecutar un <a href="https://support.ca.com/cadocs/0/k044743e.pdf?intcmp=searchresultclick&resultnum=5">EXPLAIN en la herramienta CA SQL-Ease for DB2 for ZOS</a>. Ahora os comentaré otra funcionalidad interesante que podemos encontrar en esta aplicación.<br />
<br />
1º) Una vez estamos en el informe <span style="color: lime;"><b>ACCESS PATH ANALYSIS</b></span>, podemos irnos al final del todo escribiendo 'M' en la línea de comandos y pulsando PF8. Así nos aparecerá en pantalla el <a href="http://www.universocobol.com/2015/11/como-almacenar-queries-en-qmf.html">código de la query</a> para la se ha ejecutado el informe EXPLAIN.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-IhobsxivT8w/Vjd5gUV9i_I/AAAAAAAAAnw/S5AGOXzPBN0/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv8.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://1.bp.blogspot.com/-IhobsxivT8w/Vjd5gUV9i_I/AAAAAAAAAnw/S5AGOXzPBN0/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv8.png" width="640" /></a></div>
<br />
<br />
<br />
Lo bueno es que en esta misma pantalla podremos proceder a modificar la query como deseemos. <b>Esto nos permitirá probar diversas alternativas para optimizar el código</b> y nos facilitará la realización del trabajo necesario para rebajar el coste por debajo de los <span style="color: orange;"><b>100 milisegundos</b></span>.<br />
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-7Rv72z_dVs8/Vjd7UV5WgRI/AAAAAAAAAn8/ZY50qg3X5G4/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv9.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="400" src="https://3.bp.blogspot.com/-7Rv72z_dVs8/Vjd7UV5WgRI/AAAAAAAAAn8/ZY50qg3X5G4/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv9.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
Tras pulsar INTRO se nos volverá a mostrar <b>el informe EXPLAIN pero esta vez con los datos de Coste actualizados según las nuevas modificaciones</b> que hayamos introducido en la query. Y lo mejor de todo es que podremos <span style="color: magenta;"><b>repetir este proceso</b></span>
tantas veces como necesitemos hasta que estemos totalmente seguros de
que nuestro código no va a superar los 100 milisegundos de ejecución.<br />
<br />
<h2>
<span style="font-size: large;">Conclusiones acerca de CA SQL-Ease for DB2 for ZOS</span></h2>
<br />
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 <span style="color: cyan;"><b>rendimiento</b></span>
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 <a href="http://www.universocobol.com/2015/04/como-crear-una-subquery-db2-con-sql.html">subqueries</a> anidadas.<br />
<br />
Para estos casos nos va a venir muy el empleo de la herramienta <span style="color: lime;"><b>CA SQL-Ease for DB2 for ZOS</b></span>. En particular, <b>la opción 2 de la misma (EXPLAIN SQL) nos resultará muy útil para evaluar el rendimiento de las implementaciones SQL</b>. Y, por supuesto, esto repercutirá en el rendimiento global de nuestros programas Cobol.<br />
<br />
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 <span style="color: orange;"><b>Coste (en milisegundos)</b></span>, dato que nos resultará muy útil a la hora de verificar que nuestro código tiene un rendimiento aceptable.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://3.bp.blogspot.com/--mMLSwgGnt0/VsIDI_JMs1I/AAAAAAAAKwc/S8hnDaJbxTo/s1600/EXPLAIN%2Bcon%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="225" src="https://3.bp.blogspot.com/--mMLSwgGnt0/VsIDI_JMs1I/AAAAAAAAKwc/S8hnDaJbxTo/s400/EXPLAIN%2Bcon%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS.png" width="400" /></a></div>
<br />
Llegados a este punto, ahora ya es decisión vuestra incorporar esta función a vuestro <a href="http://www.universocobol.com/2014/11/transacciones-basicas-del-entorno-cics.html">catálogo de herramientas Cobol</a>.
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.<br />
<br />
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.<br />
<br />
Saludos.<br />
<br />Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-21478960333427679182016-02-29T12:00:00.000+01:002016-02-29T12:00:00.266+01:00EXPLAIN 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.<br />
<br />
<h2>
<span style="font-size: large;">EXPLAIN con CA SQL-Ease for DB2 for ZOS</span></h2>
<br />
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 <span style="color: lime;"><b>rendimiento en máquina</b></span> 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 <a href="http://www.ca.com/us/~/media/Files/DataSheets/ca-sql-ease-for-db2-for-zos.PDF">CA SQL-Ease for DB2 for ZOS</a>.<br />
<br />
El comando <b>EXPLAIN de CA SQL-Ease for DB2 for ZOS nos sirve para medir el tiempo estimado de ejecución de una sentencia SQL</b>. Recordad que no deberíamos poner en producción ninguna sentencia cuyo tiempo de ejecución sea superior a los <span style="color: orange;"><b>100 milisegundos</b></span>. Teniendo en cuenta esto, EXPLAIN nos va a permitir detectar cuáles son las <a href="http://www.universocobol.com/search/label/SQL">instrucciones SQL</a> de nuestro programa que van a tener un pobre rendimiento a la hora de ejecutarse.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://1.bp.blogspot.com/-fVeIqke4BvE/VsIDI44zguI/AAAAAAAAKwY/9ZzCHE1tZ6c/s1600/EXPLAIN%2Bcon%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="315" src="https://1.bp.blogspot.com/-fVeIqke4BvE/VsIDI44zguI/AAAAAAAAKwY/9ZzCHE1tZ6c/s400/EXPLAIN%2Bcon%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv2.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
<br />
Hay que tener en cuenta que se trata de una aplicación muy potente. Su uso nos va a permitir que<b> las sentencias SQL de nuestros programas Cobol lleguen al entorno de producción con tiempos de ejecución inferiores a 100 ms</b>. Obviamente, siempre es posible que surja algún error adicional pero no podemos negar que, con EXPLAIN, las posibilidades de que se produzca un <span style="color: cyan;"><b>problema de rendimiento</b></span> son muy inferiores.<br />
<br />
<h2>
<span style="font-size: large;">¿Cómo ejecutar EXPLAIN en un Cobol?</span></h2>
<br />
Entrando ya en materia, ahora vamos a ir viendo cuáles son los pasos que tendríamos que seguir para ejecutar el comando <span style="color: magenta;"><b>EXPLAIN</b></span> en nuestro <a href="http://www.universocobol.com/search/label/Cobol">programa Cobol</a>. 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.<br />
<br />
Estos son los pasos: <br />
<br />
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.<br />
<br />
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 <span style="color: lime;"><b>EXEC SQL y END-EXEC</b></span> de nuestro programa.<br />
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-qCu4w5mYTo8/VjcWk5clBOI/AAAAAAAAAmU/xVGZNP-z2-U/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-qCu4w5mYTo8/VjcWk5clBOI/AAAAAAAAAmU/xVGZNP-z2-U/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv2.png" width="640" /></a></div>
<br />
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.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-Zd_9nrBvSRA/VjcXIbib5XI/AAAAAAAAAmc/Hb4HlwqrqMQ/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-Zd_9nrBvSRA/VjcXIbib5XI/AAAAAAAAAmc/Hb4HlwqrqMQ/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv3.png" width="640" /></a></div>
<br />
<br />
5º) Tras pulsar INTRO se nos abrirá el menú principal de la herramienta. Aquí tendremos que seleccionar la opción 2 - EXPLAIN SQL.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-BvNG48O545A/VjcXvOA4P8I/AAAAAAAAAmo/YQicDKPCqJs/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv4.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://2.bp.blogspot.com/-BvNG48O545A/VjcXvOA4P8I/AAAAAAAAAmo/YQicDKPCqJs/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv4.png" width="640" /></a></div>
<br />
<br />
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.<br />
<br />
<a href="http://1.bp.blogspot.com/-UPRfLg9HtkU/VjdTJyFdYuI/AAAAAAAAAnE/vPZaigicBmw/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv5.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://1.bp.blogspot.com/-UPRfLg9HtkU/VjdTJyFdYuI/AAAAAAAAAnE/vPZaigicBmw/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv5.png" width="640" /></a> <br />
<br />
<br />
7º) Si nos desplazamos una página hacia abajo, <b>podremos ver la información del rendimiento de la ejecución en el apartado ACCESS PATH ANALYSIS</b>. En la <span style="color: orange;"><b>línea COST</b></span> encontraremos el importante dato que hace referencia al tiempo (en milisegundos) que tardará en ejecutarse nuestra sentencia SQL.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-7k6__stsimQ/VjdUmrrpilI/AAAAAAAAAnQ/cVJG5Cp9m2c/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv6.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-7k6__stsimQ/VjdUmrrpilI/AAAAAAAAAnQ/cVJG5Cp9m2c/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv6.png" width="640" /></a></div>
<br />
<br />
<br />
En el ejemplo vemos que el <span style="color: magenta;"><b>coste del SQL</b></span> sería de 284 milisegundos. Como hemos dicho más arriba, <b>cualquier cosa que pase de los 100 milisegundos no es aceptable</b> y, por tanto, tendríamos que proceder a la optimización de nuestro código antes de entregarlo al cliente.<br />
<br />
8º) Adicionalmente, en el análisis del <span style="color: cyan;"><b>camino de acceso</b></span> 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 <a href="http://www.universocobol.com/2015/11/como-recuperar-queries-en-qmf.html">query SQL</a> analizada.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-s04b5Wm-FUE/VjdV7ZNLXkI/AAAAAAAAAnc/3y0n86KvCJY/s1600/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv7.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="https://4.bp.blogspot.com/-s04b5Wm-FUE/VjdV7ZNLXkI/AAAAAAAAAnc/3y0n86KvCJY/s640/EXPLAIN%2B-%2BCA%2BSQL-Ease%2Bfor%2BDB2%2Bfor%2BZOS%2Bv7.png" width="640" /></a></div>
<br />
En el ejemplo vemos que se está accediendo a la <a href="http://www.universocobol.com/search/label/DB2">tabla DB2</a> 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).<br />
<br />
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.<br />
<br />
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í...<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com2tag:blogger.com,1999:blog-8613600796016988320.post-47799910996615094672016-01-01T12:00:00.000+01:002016-01-01T12:00:00.188+01:00Feliz Año Nuevo 2016Ya sé que hoy estamos todos un poco cansados y con pocas ganas de
hacer nada, así que no voy a demorarme demasiado. Simplemente quería
daros un saludo rápido y desearos una feliz entrada de año nuevo. Espero
que en 2016 tengáis éxito en todos los objetivos que os marquéis en el mundo de la informática y, por qué no, en el resto de objetivos también
(por cierto, ¿os comísteis todas las uvas ayer?). Ahora, a descansar y a
disfrutar de la comida con vuestra familia. El lunes nos vemos de nuevo programando código al pie del cañón.<br />
<br />
<span style="color: cyan;"><b>¡Feliz Año Nuevo 2016!</b></span><br />
<br />
Saludos.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-UzrU5gILdh8/VnRyVTKe1CI/AAAAAAAAJsk/k9z2skvxys0/s1600/Feliz%2BA%25C3%25B1o%2BNuevo%2B2016.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="250" src="http://4.bp.blogspot.com/-UzrU5gILdh8/VnRyVTKe1CI/AAAAAAAAJsk/k9z2skvxys0/s400/Feliz%2BA%25C3%25B1o%2BNuevo%2B2016.jpg" width="400" /></a></div>
Jose Tamborerohttp://www.blogger.com/profile/02583588994513190075noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-68483881266865695022015-11-09T12:00:00.000+01:002015-11-09T12:36:45.806+01:00¿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.<br />
<br />
En su día ya estuvimos viendo la <a href="http://www.universocobol.com/2015/11/como-almacenar-queries-en-qmf.html">instrucción SAVE de QMF</a>, 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.<br />
<br />
<h2>
<span style="font-size: large;">¿Cómo recuperar una query en QMF?</span></h2>
<br />
Una vez almacenada la información, la siguiente cuestión que se nos plantearía es <b>cómo recuperar la query en el momento en el que lo deseemos</b>. Obviamente, no tendría mucho sentido <b><span style="color: lime;">almacenar el código</span></b> si no pensamos usarlo nunca más con posterioridad.<br />
<br />
En este entorno, <b>para realizar la acción de recuperar la query en QMF disponemos del comando DISPLAY</b>. Para poder usarlo, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la <a href="https://en.wikipedia.org/wiki/IBM_Query_Management_Facility">herramienta QMF</a>, tal y como hicimos a la hora de guardar el código.<br />
<br />
Una vez aquí, en la línea COMMAND tendremos que incluir el <b><span style="color: magenta;">comando DISPLAY QUERY</span></b>.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">COMMAND ===> DISPLAY QUERY EJEMPLO</span></span><br />
<br />
Pulsamos INTRO y se nos deplegará la siguiente ventana.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-DqDciLJqHcA/VhVAtA5iOhI/AAAAAAAAAkk/7gVfZiNAmjg/s1600/QMF%2BRecuperar%2BQuery.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://1.bp.blogspot.com/-DqDciLJqHcA/VhVAtA5iOhI/AAAAAAAAAkk/7gVfZiNAmjg/s640/QMF%2BRecuperar%2BQuery.png" width="640" /></a></div>
<br />
Como se puede apreciar, se trata del mismo código que previamente <span style="color: cyan;"><b>habíamos almacenado</b></span>
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.<br />
<br />
<h2>
<span style="font-size: large;">Listar todas las queries almacenadas en QMF</span></h2>
<br />
Imaginaos que llega un momento en el que tenéis <span style="color: orange;"><b>almacenadas 50 queries</b></span>
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?<br />
<br />
Para estos casos vamos a usar el <b>comando LIST, que nos mostrará un listado de todas las queries</b>
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.<br />
<br />
Una vez aquí, en la línea COMMAND tendremos que incluir el <span style="color: magenta;"><b>comando LIST QUERIES</b></span>.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;">COMMAND ===> LIST QUERIES</span></span><br />
<br />
Pulsamos INTRO y se nos deplegará la siguiente ventana.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-LnNTMQrOdK8/VhVFndynurI/AAAAAAAAAk0/KvRyu0QU1pU/s1600/QMF%2BListar%2BQueries.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://4.bp.blogspot.com/-LnNTMQrOdK8/VhVFndynurI/AAAAAAAAAk0/KvRyu0QU1pU/s640/QMF%2BListar%2BQueries.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Como vemos, en esta pantalla aparecen las queries que previamente he almacenado en QMF con mi usuario.<br />
<br />
A continuación, si queremos recuperar el código de alguno de los <a href="http://www.universocobol.com/search/label/SQL">objetos SQL listados</a>, <b>lo único que tendremos que hacer es usar el comando DISPLAY en la columna ACTION</b>. De este modo, se recuperará el <span style="color: cyan;"><b>contenido de la query</b></span> de la misma forma que con el comando DISPLAY QUERY que hemos examinado anteriormente.<br />
<br />
<span style="color: lime;"><span style="font-family: "courier new" , "courier" , monospace;"> --------Dates--------<br />Action Name Owner Modified Last Used <br /> <br />DISPLAY EJEMPLO JJ00917 2015-10-06 2015-10-07</span></span><br />
<br />
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.<br />
<br />
<h2>
<span style="font-size: large;">Almacenar y recuperar queries en QMF</span></h2>
<br />
En
principio, con los comandos revisados, ya podríamos operar de una
manera básica con la base de datos de QMF. Las instrucciones <span style="color: magenta;"><b>SAVE, DISPLAY y LIST</b></span>
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 <a href="http://www.universocobol.com/2013/11/sentencia-update-en-una-tabla-db2.html">UPDATE</a>, con <a href="http://www.universocobol.com/2013/07/insertar-registro-en-tabla-db2.html">INSERT</a> o con <a href="http://www.universocobol.com/2013/11/sentencia-delete-para-una-tabla-db2.html">DELETE</a>).<br />
<br />
Por supuesto, <b>existen más comandos QMF que los aquí mencionados, pero con estas 3 instrucciones ya podremos sobrevivir en el entorno</b>. En un futuro, en un nuevo post, intentaré esbozar una visión global de cuáles son todos los <span style="color: orange;"><b>comandos disponibles</b></span> para esta herramienta.<br />
<br />
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 <span style="color: lime;"><b>posibilidad de reutilizar</b></span>
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.<br />
<br />
<a href="http://4.bp.blogspot.com/-5tsvM4G0qyg/VhaSuCE1YjI/AAAAAAAAAlM/er0swyXNN3g/s1600/Almacenar%2BRecuperar%2BQueries%2BQMF.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-5tsvM4G0qyg/VhaSuCE1YjI/AAAAAAAAAlM/er0swyXNN3g/s1600/Almacenar%2BRecuperar%2BQueries%2BQMF.jpg" /></a> <br />
<br />
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.<br />
<br />
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.<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com2tag:blogger.com,1999:blog-8613600796016988320.post-57898869373520329652015-11-02T12:00:00.000+01:002015-11-02T12:00:05.375+01:00¿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 <a href="https://www-01.ibm.com/support/knowledgecenter/SSEPEK_10.0.0/com.ibm.db2z10.doc.intro/src/tpc/db2z_tut_querydata.dita">herramienta QMF</a> 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.<br />
<br />
<h2>
<span style="font-size: large;">Ejecución múltiple de queries en QMF</span></h2>
<br />
Si necesitamos emplear una determinada query en <span style="color: lime;"><b>múltiples ocasiones</b></span> a lo largo del tiempo, no será necesario que introduzcamos su código cada vez que tengamos que recurrir a ella. <b>La herramienta QMF nos da la opción de almacenar el código de dicha query</b>, de manera que podamos recuperarlo siempre que lo precisemos.<br />
<br />
Para explicar esto, prefiero que lo veamos con un ejemplo. Supongamos, por tanto, que hemos creado una determinada <a href="http://www.universocobol.com/2015/04/como-crear-una-subquery-db2-con-sql.html">query SQL</a> (a petición de nuestro cliente, por supuesto) y que ya la hemos ejecutado y hemos obtenido la <span style="color: magenta;"><b>información</b></span> que nos habían solicitado.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-1CX68xVQHIk/VhaS4lag_CI/AAAAAAAAAlY/QOmwt9mwB_o/s1600/Almacenar%2BRecuperar%2BQueries%2BQMF%2Bv3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://2.bp.blogspot.com/-1CX68xVQHIk/VhaS4lag_CI/AAAAAAAAAlY/QOmwt9mwB_o/s1600/Almacenar%2BRecuperar%2BQueries%2BQMF%2Bv3.jpg" /></a></div>
<br />
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. <br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">SELECT * FROM JJDB22.JJLOCAT0 <br /> WHERE JJGE_CO_INTERN = '28' <br /> AND JJCA_FX_ALTSIS >= '2014-01-01'</span></span><br />
<br />
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). <br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: lime;"> JJTU JJCA JJCA JJCA JJCA <br /> CO CO CO CO NO <br /> INTERN INTERN 2SCLOC 3SCLOC PBLSIT <br />--------- ------ ------ ------ -----------------<br /> 43277 0 COLMENAR VIEJO <br /> 43277 1 CTO 1 COLMENAR VIEJO <br /> 44590 0 COLMENAR VIEJO <br /> 44590 1 DIV2 0 COLMENAR VIEJO <br /> 44590 2 DV00 2 COLMENAR VIEJO <br /> 44590 3 CTO 1 COLMENAR VIEJO <br /> 47909 0 MADRID <br /> 57746 0 MADRID <br /> 91957 0 MADRID <br /> 91966 0 ALCOBENDAS <br /> 91966 1 CTO 1 ALCOBENDAS </span></span><br />
<br />
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.<br />
<br />
<h2>
<span style="font-size: large;">¿Cómo almacenar una query en QMF?</span></h2>
<br />
Normalmente, ejecutaremos la query sobre la <a href="http://www.universocobol.com/search/label/DB2">tabla DB2</a>, obtendremos los resultados y <span style="color: orange;"><b>desecharemos el código</b></span> 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 <span style="color: cyan;"><b>informe</b></span> más adelante, entonces <b>lo óptimo sería almacenarnos la declaración para no tener que volver a teclearla</b> más veces.<br />
<br />
Para poder guardarnos una query sobre DB2, en primer lugar tendremos que posicionarnos en la ventana 6=DRAW de la herramienta QMF.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-MMOYG1LLFS0/VhP0uJoJiDI/AAAAAAAAAkA/4RJhMq4WF3o/s1600/QMF%2BAlmacenar%2BQuery%2Bv2.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://1.bp.blogspot.com/-MMOYG1LLFS0/VhP0uJoJiDI/AAAAAAAAAkA/4RJhMq4WF3o/s640/QMF%2BAlmacenar%2BQuery%2Bv2.png" width="640" /></a></div>
<br />
<br />
<br />
<br />
Una vez aquí, en la línea COMMAND tendremos que insertar el <span style="color: magenta;"><b>comando SAVE</b></span>.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMMAND ===> SAVE</span></span><br />
<br />
Pulsamos INTRO y se nos deplegará la siguiente ventana.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-05fPiS1WwaU/VhP1oCpB_yI/AAAAAAAAAkI/ElKUUXdn7oQ/s1600/QMF%2BAlmacenar%2BQuery%2Bv3.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="424" src="http://3.bp.blogspot.com/-05fPiS1WwaU/VhP1oCpB_yI/AAAAAAAAAkI/ElKUUXdn7oQ/s640/QMF%2BAlmacenar%2BQuery%2Bv3.png" width="640" /></a></div>
<br />
<br />
En esta ventana tenemos 3 apartados que tendremos que rellenar antes de confirmar la operación.<br />
<br />
1º) <b>NAME</b>: Aquí simplemente tendremos que indicar el nombre con el que deseamos que la <a href="http://www.universocobol.com/2013/10/sentencia-select-para-una-tabla-db2.html">query con SELECT</a> (o con cualquier otra instrucción) quede almacenada en QMF.<br />
<br />
2º) <b>CONFIRM</b>: 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.<br />
<br />
3º) <b>SHARE</b>: 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.<br />
<br />
Una vez que rellenemos estos datos y pulsemos INTRO, en QMF nos aparecerá el siguiente mensaje, donde se nos confirma el <span style="color: orange;"><b>guardado del objeto</b></span> con el nombre de nuestro usuario seguido del nombre elegido para la query (en la ventana anterior).<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">OK, QUERY was saved as JJ00917.EJEMPLO in the database.</span></span><br />
<br />
<br />
En estos momentos, nuestra query ya quedaría almacenada en la base de datos de QMF y ya estaría disponible para ser <span style="color: cyan;"><b>recuperada fácilmente</b></span> en el futuro.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-lRx4Dgx7_h4/VhdhqLpQTKI/AAAAAAAAAlw/tsh8eEL2Js0/s1600/Almacenar%2BRecuperar%2BQueries%2BQMF%2Bv4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="http://1.bp.blogspot.com/-lRx4Dgx7_h4/VhdhqLpQTKI/AAAAAAAAAlw/tsh8eEL2Js0/s320/Almacenar%2BRecuperar%2BQueries%2BQMF%2Bv4.jpg" width="320" /></a></div>
<br />
<br />
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.<br />
<br />
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...<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-42747030912405477282015-10-26T12:00:00.000+01:002015-10-26T12:00:00.724+01:00Comando COMPUTE para CobolComo en todos los lenguajes, en Cobol también disponemos de un comando específico que nos permite realizar operaciones matemáticas entre operandos. Eso sí, debido a que nuestro lenguaje no está pensado para su utilización en entornos científicos, en las rutinas que elaboremos sólo podremos incluir operaciones aritméticas sencillas.<br />
<br />
<h2>
<span style="font-size: large;"><b>Ejecución de operaciones matemáticas en Cobol</b></span></h2>
<h2>
<b><span style="font-weight: normal;"></span></b></h2>
<br />
Seguro que, en más de una ocasión, os habéis encontrado con una situación en la que el <a href="https://es.wikipedia.org/wiki/Algoritmo">algoritmo</a> de una determinada funcionalidad os ha obligado a implementar alguna <span style="color: cyan;"><b>operación matemática</b></span>. Para acometer tareas de este tipo, en <a href="http://www.universocobol.com/search/label/Cobol">lenguaje Cobol</a> disponemos de los comandos ADD, SUBTRACT, MULTIPLY y DIVIDE (sumar, restar, multiplicar y dividir).<br />
<br />
Pero, si queremos implementar fórmulas algo más complejas, podemos recurrir al comando <span style="color: orange;"><b>COMPUTE</b></span>. Esta función <b>nos permitiría incluir, en una misma declaración, la ejecución de múltiples operaciones sobre operandos diversos</b>. De este modo, podremos realizar sumas, restas, multiplicaciones y divisiones en la misma sentencia.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-SYmzXdEoWXU/VgwBMmYK-0I/AAAAAAAAAhg/cD01q3GKHzE/s1600/Compute%2BCobol%2BOperaciones%2BMatematicas.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="390" src="http://3.bp.blogspot.com/-SYmzXdEoWXU/VgwBMmYK-0I/AAAAAAAAAhg/cD01q3GKHzE/s400/Compute%2BCobol%2BOperaciones%2BMatematicas.jpg" width="400" /></a></div>
<br />
Como vemos, se trata de un comando bastante estándar. De hecho, hay varios <span style="color: lime;"><b>lenguajes de programación</b></span> en los que esta función se denomina del mismo modo: COMPUTE. Sin ir más lejos, así ocurre en <a href="http://www.universocobol.com/search/label/Natural">Natural ADABAS</a>, otro de los lenguajes de los que solemos hablar de vez en cuando en el blog.<br />
<br />
<h2>
<span style="font-size: large;"><b>¿Cómo se implementa una sentencia COMPUTE?</b></span></h2>
<br />
A continuación vamos a ver un ejemplo de <b>cómo se debería implementar la sentencia COMPUTE dentro de un párrafo de Cobol</b>. Obviamente, el número de combinaciones para esta función es muy elevado pero, para facilitar su explicación, centrémonos en la siguiente fórmula modelo que se compone de 3 operadores y de 8 variables.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">DATA DIVISION.</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">WORKING-STORAGE SECTION.</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">01 W-PTOS-CALCULADOS PIC 9(5).<br /><br />01 W-DISTANCIAS-ABS. <br /> 05 W-REGL-NU-COORDX-DESDE PIC 9(5) VALUE ZEROES.<br /> 05 W-REGL-NU-COORDY-DESDE PIC 9(5) VALUE ZEROES.<br /> 05 W-PTCO-NU-COORDX-DESDE PIC 9(5) VALUE ZEROES.<br /> 05 W-PTCO-NU-COORDY-DESDE PIC 9(5) VALUE ZEROES.</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"> 05 W-REGL-NU-COORDX-HASTA PIC 9(5) VALUE ZEROES.<br /> 05 W-REGL-NU-COORDY-HASTA PIC 9(5) VALUE ZEROES.<br /> 05 W-PTCO-NU-COORDX-HASTA PIC 9(5) VALUE ZEROES.<br /> 05 W-PTCO-NU-COORDY-HASTA PIC 9(5) VALUE ZEROES.</span></span> </span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">...</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">PROCEDURE DIVISION.</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-PTOS-CALCULADOS = <br /> (W-REGL-NU-COORDX-HASTA - <br /> W-REGL-NU-COORDX-DESDE + 1 ) *<br /> (W-REGL-NU-COORDY-HASTA - <br /> W-REGL-NU-COORDY-DESDE + 1 ) *<br /> (W-PTCO-NU-COORDX-HASTA - <br /> W-PTCO-NU-COORDX-DESDE + 1 ) *<br /> (W-PTCO-NU-COORDY-HASTA - <br /> W-PTCO-NU-COORDY-DESDE + 1 ). </span></span><br />
<br />
Como se aprecia, en la declaración anterior se están usando 8 variables y 3 <span style="color: magenta;"><b>operadores aritméticos</b></span>: suma, resta y multiplicación. De este modo nos evitamos tener que emplear 3 sentencias distintas con los comandos ADD, SUBTRACT y MULTIPLY y, al mismo tiempo, nos ahorramos la definición de algunas variables auxiliares que hubiésemos tenido que utilizar en el caso de no recurrir al comando COMPUTE.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-Pikdu00Snww/VgwC6jp_oLI/AAAAAAAAAhw/r4WNUzjyO-0/s1600/Compute%2BCobol%2BVariables%2Bauxiliares.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="391" src="http://3.bp.blogspot.com/-Pikdu00Snww/VgwC6jp_oLI/AAAAAAAAAhw/r4WNUzjyO-0/s400/Compute%2BCobol%2BVariables%2Bauxiliares.jpg" width="400" /></a></div>
<br />
Por lo que respecta a la fórmula en sí misma, entiendo que es muy sencilla y que no hace falta recurrir a ninguna explicación adicional de la misma. Básicamente, se están calculando las diferencias entre varias coordenadas y multiplicando dichas distancias entre sí para obtener un valor denominado "Puntos Calculados" (variable que, una vez visto el ejemplo, ya no tiene interés para nosotros y que se usará posteriormente en el algoritmo del programa <a href="http://www.universocobol.com/search/label/CICS">Cobol CICS</a>).<br />
<br />
<h2>
<span style="font-size: large;"><b>Aprendiendo a utilizar el comando COMPUTE</b></span></h2>
<br />
Una vez visto cómo hemos realizado la declaración en nuestro ejemplo, <b>no deberíais tener problemas a la hora de extrapolar su empleo a vuestros propios programas</b>. Se trata de un <span style="color: cyan;"><b>comando estándar</b></span> cuya utilización es bastante intuitiva y, según mi experiencia, no suele causar demasiadas dificultades a los programadores principiantes.<br />
<br />
Por si acaso, y teniendo en cuenta que un ejemplo práctico vale más que 1.000 palabras de teoría, a continuación paso a incluir algunas sentencias más con posibles usos del comando. A partir de ellos, se pueden elaborar otras 1.000 variantes diferentes, de manera que no vamos a tener problemas para encontrar la opción que encaje con el que requiera nuestro <span style="color: magenta;"><b>algoritmo</b></span>.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-1 = W-OPERANDOS-1 + W-OPERANDOS-2</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-2 = W-OPERANDOR-1 - W-OPERANDOR-2</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-3 = W-OPERANDOM-1 * W-OPERANDOM-2</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-4 = W-OPERANDOD-1 / W-OPERANDOD-2</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-5 = (W-OPERANDOSD-1 + W-OPERANDOSD-2) / (W-OPERANDOSD-3 - W-OPERANDOSD-4)</span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><br /></span></span>
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-6 = (W-OPERANDODM-1 / W-OPERANDODM-2) * (W-OPERANDODM-3 / W-OPERANDODM-4)</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-7 = (W-OPERANDORD-1 - W-OPERANDORD-2) / W-OPERANDORD-3</span></span><br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">COMPUTE W-TOTAL-8 = (W-OPERANDOSM-1 + 1) * (W-OPERANDOSM-2 / W-OPERANDOSM-3) * ((W-OPERANDOSM-4 - W-OPERANDOSM-5) / W-OPERANDOSM-6)</span></span><br />
<br />
Como vemos, las <span style="color: magenta;"><b>construcciones</b></span> con COMPUTE se pueden ir incrementando de dificultad de forma indefinida. Esto nos va a facilitar la incorporación de la <b>complejidad requerida a nuestras fórmulas, siempre y cuando no nos salgamos del catálogo de operaciones aritméticas básicas</b>. En mi propia experiencia, el comando COMPUTE es más que suficiente para implementar la mayoría de las fórmulas requeridas en los algoritmos de los programas <a href="http://www.universocobol.com/search/label/DB2">Cobol CICS DB2</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-e9tLxN4mvmI/VgwCE66AzgI/AAAAAAAAAho/ytd1teHCg5Q/s1600/Compute%2BCobol%2BFormulas%2BAritmeticas.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://2.bp.blogspot.com/-e9tLxN4mvmI/VgwCE66AzgI/AAAAAAAAAho/ytd1teHCg5Q/s400/Compute%2BCobol%2BFormulas%2BAritmeticas.jpg" width="400" /></a></div>
<br />
En definitiva, tenemos que considerar al COMPUTE como una sentencia de elaboración de fórmulas aritméticas que nos va a permitir <span style="color: orange;"><b>ahorrar tiempo y código</b></span> a la hora de desarrollar. Por un lado, su uso nos permitirá sustituir a los comandos ADD, SUBTRAC, MULTIPLY y DIVIDE; por otro lado, reduciremos el número de variables auxiliares precisadas para operar.<br />
<br />
Y eso es todo por hoy. Espero que lo comentado os sirva para resolver todas las dudas que tengáis acerca del comando COMPUTE y que os facilite vuestra labor con el cliente. De todas formas, ya sabéis que podéis dejarme cualquier comentario aquí abajo y os lo responderé lo antes posible...<br />
<br />
Saludos.<br />
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com1tag:blogger.com,1999:blog-8613600796016988320.post-49127738813263017452015-10-23T18:11:00.000+02:002015-10-23T18:11:00.307+02:00¿A qué se dedica un Programador?<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-FekkfY9MuCA/VgF9cSF2gfI/AAAAAAAAAhI/bMr3WTfMvB8/s1600/Profesion%2Bde%2BProgramador.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://4.bp.blogspot.com/-FekkfY9MuCA/VgF9cSF2gfI/AAAAAAAAAhI/bMr3WTfMvB8/s400/Profesion%2Bde%2BProgramador.jpg" width="400" /></a></div>
<br />Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com2tag:blogger.com,1999:blog-8613600796016988320.post-19899232448108358942015-10-19T12:00:00.000+02:002015-10-19T12:00:06.980+02:00Visualizar Fichero comprimido en ISPFEn general, la visualización del contenido de un fichero
secuencial con formato estándar no suele tener ninguna complejidad asociada.
Sin embargo, se requiere algo más de esfuerzo para poder observar los ficheros cuyos
registros contienen campos comprimidos. A continuación, vamos a ver cómo
hacerlo.<br />
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<h2>
<span style="font-size: large;"><b style="mso-bidi-font-weight: normal;">Ficheros secuenciales
con datos empaquetados</b></span></h2>
</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Cuando trabajamos con <a href="http://www.universocobol.com/2014/06/tipos-de-ficheros-secuenciales-cobol-y-2.html">ficheros secuenciales</a>, lo normal es
que los registros de los mismos vayan con formato numérico o alfanumérico no
comprimido, ya que es el tipo que suele ser más fácil de manejar. Sin embargo,
en ocasiones, <b>la necesidad de ahorro de espacio nos puede obligar a trabajar
con ficheros con datos en formato empaquetado</b> (COMP-3). La visualización de la
información no se realizará del mismo modo en un caso o en otro.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Para tener clara esta diferencia podemos mostrar unos
ejemplos. Vamos a acceder al contenido de los ficheros JJPR.UNLOAD.X0005X.POBL
y JJPR.UNLOAD.X0005X.POBL2. El primero de ellos está en <span style="color: cyan;"><b>formato alfanumérico</b></span> y
el segundo contiene algunos campos con <span style="color: magenta;"><b>formato comprimido</b></span> COMP-3.<br />
<br />
<a href="http://2.bp.blogspot.com/-5EmqLK-ftEA/VgAtvCR-4nI/AAAAAAAAAgU/jMDRNUiiUKQ/s1600/Fichero%2BComprimido%2BISPF%2Bv2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="283" src="http://2.bp.blogspot.com/-5EmqLK-ftEA/VgAtvCR-4nI/AAAAAAAAAgU/jMDRNUiiUKQ/s400/Fichero%2BComprimido%2BISPF%2Bv2.jpg" width="400" /></a> <br />
<br />
Los registros del fichero alfanumérico son los siguientes
(JJPR.UNLOAD.X0005X.POBL).</div>
<div class="MsoNormal">
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">=COLS> ----+----1----+----2----+----3----+----4 <br />****** ***************************** Top of Data ***<br />000001 A-000020-MADRID.................MAD00100 <br />000002 B-000019-CIUDAD REAL............CRE00200 <br />000003 A-000018-BARCELONA..............BAR00300 <br />000004 A-000017-VALENCIA...............VAL00400 <br />000005 A-000015-ZARAGOZA...............ZAR00600 <br />000006 B-000014-CASTELLON..............CAS00700 <br />000007 B-000012-GRANADA................GRA00900 <br />000008 B-000011-TOLEDO.................TOL01000 <br />000009 B-000010-SEGOVIA................SEG01100 <br />000010 B-000002-ALMERIA................ALM01300 <br />000011 B-000004-SANTANDER..............SAN01500 <br />000012 B-000005-TARRAGONA..............TAR01600 <br />000013 B-000006-BADAJOZ................BAD01700 <br />000014 B-000007-SALAMANCA..............SAL01800 <br />000015 B-000008-BURGOS.................BUR01900 <br />=COLS> ----+----1----+----2----+----3----+----4 <br />****** **************************** Bottom of Data ***</span></span> <br />
<br />
En cambio, el contenido del fichero empaquetado tiene el
siguiente aspecto (JJPR.UNLOAD.X0005X.POBL2).<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">=COLS> ----+----1----+----2----+----3----+-- <br />****** ***************************** Top of Data ***<br />000001 A- -MADRID.................MAD<br />000002 B- æ-CIUDAD REAL............CRE<br />000003 A- ð-BARCELONA..............BAR<br />000004 A- @-VALENCIA...............VAL <br />000005 A- *-ZARAGOZA...............ZAR -<br />000006 B- <-CASTELLON..............CAS ø<br />000007 B- -GRANADA................GRA °<br />000008 B- -TOLEDO.................TOL<br />000009 B- -SEGOVIA................SEG<br />000010 B- -ALMERIA................ALM<br />000011 B- <-SANTANDER..............SAN &<br />000012 B- *-TARRAGONA..............TAR -<br />000013 B- %-BADAJOZ................BAD ø<br />000014 B- @-SALAMANCA..............SAL Ø<br />000015 B- ð-BURGOS.................BUR ° <br />=COLS> ----+----1----+----2----+----3----+-- <br />****** **************************** Bottom of Data *** </span></span><br />
<br />
Como vemos, los registros del primer <a href="http://www.universocobol.com/search/label/Ficheros">fichero</a> son
perfectamente legibles sin ninguna acción adicional. Sin embargo, el contenido
del segundo fichero aparece con caracteres extraños (formato empaquetado), haciendo
imposible identificar los códigos almacenados en sus registros.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-96V-u-3aPFk/VgAvT1_ckrI/AAAAAAAAAgg/fuhSYhA7YUc/s1600/Visualizar%2BFichero%2Bempaquetado.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://2.bp.blogspot.com/-96V-u-3aPFk/VgAvT1_ckrI/AAAAAAAAAgg/fuhSYhA7YUc/s400/Visualizar%2BFichero%2Bempaquetado.jpg" width="400" /></a></div>
</div>
<div class="MsoNormal">
<br />
<h2>
<span style="font-size: large;"><b style="mso-bidi-font-weight: normal;">¿Cómo visualizar un fichero comprimido?</b></span></h2>
<br />
A continuación, vamos a ver <b>qué es lo que debería hacerse para visualizar el contenido de un fichero comprimido</b>. Se trata de algo muy sencillo pero que, si no conocemos, nos provocará bastantes quebraderos de cabeza al enfrentarnos con <a href="http://www.consultoriocobol.com/2011/01/working-storage-definiendo-variables.html">campos COMP-3</a>.<br />
<br />
Lo que debemos hacer es lo siguiente. En primer lugar, realizamos la <span style="color: orange;"><b>apertura del fichero</b></span> desde la <a href="http://www.universocobol.com/search/label/ISPF">herramienta ISPF</a>. Posteriormente, nos situamos en la línea de comandos COMMAND e introducimos la sentencia <span style="color: cyan;"><b>HEX ON</b></span> (activar hexadecimal).<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">EDIT JJPR.UNLOAD.X0005X.POBL2 <br />Command ===> <span style="color: cyan;">HEX ON</span> <br />=COLS> ----+----1----+----2----+----3----+-- </span></span><br />
<br />
A continuación, pulsamos INTRO y la utilidad pasará a mostrarnos el contenido de los campos comprimidos en COMP-3.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">=COLS> ----+----1----+----2----+----3----+-- <br />****** ***************************** Top of Data ***<br />000001 A- -MADRID.................MAD <br /> C600006DCCDCC44444444444444444DCC0010 <br /> 10002C0414994BBBBBBBBBBBBBBBBB414000C <br />---------------------------------------------------<br />000002 B- æ-CIUDAD REAL............CRE <br /> C600096CCECCC4DCCD444444444444CDC0020 <br /> 20001C039441409513BBBBBBBBBBBB395000C <br />---------------------------------------------------<br />000003 A- ð-BARCELONA..............BAR <br /> C600086CCDCCDDDC44444444444444CCD0030 <br /> 10001C0219353651BBBBBBBBBBBBBB219000C <br />---------------------------------------------------<br />000004 A- @-VALENCIA...............VAL <br /> C600076ECDCDCCC444444444444444ECD0040 <br /> 10001C051355391BBBBBBBBBBBBBBB513000C <br />000005 A- *-ZARAGOZA...............ZAR - <br /> C600056ECDCCDEC444444444444444ECD0060 <br /> 10001C091917691BBBBBBBBBBBBBBB919000C <br />----------------------------------------------------<br />000006 B- <-CASTELLON..............CAS ø <br /> C600046CCEECDDDD44444444444444CCE0070 <br /> 20001C0312353365BBBBBBBBBBBBBB312000C <br />----------------------------------------------------<br />000007 B- -GRANADA................GRA ° <br /> C600026CDCDCCC4444444444444444CDC0090 <br /> 20001C07915141BBBBBBBBBBBBBBBB791000C <br />----------------------------------------------------<br />000008 B- -TOLEDO.................TOL <br /> C600016EDDCCD44444444444444444EDD0000 <br /> 20001C0363546BBBBBBBBBBBBBBBBB363010C <br />----------------------------------------------------<br />000009 B- -SEGOVIA................SEG <br /> C600006ECCDECC4444444444444444ECC0010 <br /> 20001C02576591BBBBBBBBBBBBBBBB257010C <br />----------------------------------------------------<br />000010 B- -ALMERIA................ALM <br /> C600026CDDCDCC4444444444444444CDD0030 <br /> 20000C01345991BBBBBBBBBBBBBBBB134010C <br />----------------------------------------------------<br />000011 B- <-SANTANDER..............SAN & <br /> C600046ECDECDCCD44444444444444ECD0050 <br /> 20000C0215315459BBBBBBBBBBBBBB215010C <br />----------------------------------------------------<br />000012 B- *-TARRAGONA..............TAR - <br /> C600056ECDDCCDDC44444444444444ECD0060 <br /> 20000C0319917651BBBBBBBBBBBBBB319010C <br />----------------------------------------------------<br />000013 B- %-BADAJOZ................BAD ø <br /> C600066CCCCDDE4444444444444444CCC0070 <br /> 20000C02141169BBBBBBBBBBBBBBBB214010C <br />----------------------------------------------------<br />000014 B- @-SALAMANCA..............SAL Ø <br /> C600076ECDCDCDCC44444444444444ECD0080 <br /> 20000C0213141531BBBBBBBBBBBBBB213010C <br />----------------------------------------------------<br />000015 B- ð-BURGOS.................BUR ° <br /> C600086CEDCDE44444444444444444CED0090 <br /> 20000C0249762BBBBBBBBBBBBBBBBB249010C <br />----------------------------------------------------<br />****** **************************** Bottom of Data ***<br />=COLS> ----+----1----+----2----+----3----+--</span></span><br />
<br />
Como vemos, ahora <b>bajo cada registro comprimido original se muestran otros dos registros adicionales</b>. En ellos aparece decodificada la información correspondiente a los <span style="color: magenta;"><b>campos hexadecimales</b></span>.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://1.bp.blogspot.com/-ZJMc_tiC1uE/VgF4CAHQq2I/AAAAAAAAAg0/s62nYLpTUKc/s1600/Decodificacion%2Bregistros%2Bcomprimidos%2BHost.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://1.bp.blogspot.com/-ZJMc_tiC1uE/VgF4CAHQq2I/AAAAAAAAAg0/s62nYLpTUKc/s400/Decodificacion%2Bregistros%2Bcomprimidos%2BHost.jpg" width="400" /></a></div>
<br />
<h2>
<span style="font-size: large;"><b style="mso-bidi-font-weight: normal;">Decodificación de campos hexadecimales</b></span></h2>
<br />
Por ejemplo, este es el registro original (no comprimido) correspondiente a MADRID.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">000001 A-000020-MADRID.................MAD00100 </span></span><br />
<br />
Ahora se corresponde con estos 3 registros.<br />
<br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">----------------------------------------------------</span></span></span></span><br />
<span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;"><span style="color: lime;"><span style="font-family: "Courier New",Courier,monospace;">000001 A- -MADRID.................MAD <br /> C6<span style="color: red;">0000</span>6DCCDCC44444444444444444DCC<span style="color: red;">0010</span> <br /> 10<span style="color: red;">002C</span>0414994BBBBBBBBBBBBBBBBB414<span style="color: red;">000C</span> </span></span><br />----------------------------------------------------</span></span><br />
<br />
He marcado en rojo la <span style="color: magenta;"><b>decodificación realizada</b></span> de los dos campos hexadecimales que contienen los <a href="http://www.universocobol.com/2014/06/tipos-de-registros-de-ficheros.html">registros de este fichero</a>. El primero es el código interno, 000020, y el segundo es el código externo, 00100. El código interno aparece decodificado como:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;">0<span style="background-color: #93c47d;">000</span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;"><span style="background-color: #f6b26b;">002</span>C</span></span><br />
<br />
Si leemos las líneas anteriores ordenadas de arriba a abajo y de izquierda a derecha, entonces el campo se correspondería con el siguiente número:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">0<span style="color: red;"><span style="background-color: #f6b26b;">0</span><span style="background-color: #93c47d;">0</span><span style="background-color: #f6b26b;">0</span><span style="background-color: #93c47d;">0</span><span style="background-color: #f6b26b;">2</span><span style="background-color: #6aa84f;">0</span></span>C</span><br />
<br />
Donde los 6 dígitos marcados se corresponden con el código interno original, en formato no comprimido 000020.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-guf3I2DEd50/VgF5nhPLxbI/AAAAAAAAAhA/ljaFDzkNuwM/s1600/Formato%2Bregistros%2Bno%2Bcomprimidos%2BHost.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="http://2.bp.blogspot.com/-guf3I2DEd50/VgF5nhPLxbI/AAAAAAAAAhA/ljaFDzkNuwM/s320/Formato%2Bregistros%2Bno%2Bcomprimidos%2BHost.jpg" width="320" /></a></div>
<br />
Del mismo modo, el código externo aparece decodificado como:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;">0<span style="background-color: #93c47d;">010</span></span></span><br />
<span style="font-family: "Courier New",Courier,monospace;"><span style="color: red;">0<span style="background-color: #f6b26b;">00</span>C</span></span><br />
<br />
Si los leemos ordenados de arriba a abajo y de izquierda a derecha se corresponderían con el siguiente número:<br />
<br />
<span style="font-family: "Courier New",Courier,monospace;">00<span style="color: red;"><span style="background-color: #93c47d;">0</span><span style="background-color: #f6b26b;">0</span><span style="background-color: #93c47d;">1</span><span style="background-color: #f6b26b;">0</span><span style="background-color: #93c47d;">0</span></span>C</span><br />
<br />
Al igual que en el caso anterior, los 5 dígitos marcados se corresponden con el código externo original, en formato no comprimido 00100.<br />
<br />
<h2>
<span style="font-size: large;">Visualización de ficheros comprimidos en ISPF </span></h2>
<br />
Por tanto, podemos ver como el uso del <b>comando HEX ON nos permite acceder a la decodificación numérica de los campos comprimidos de los registros afectados</b>. Con esta <b><span style="color: orange;">sencilla operación</span></b> evitaremos perder mucho tiempo tratando de descifrar el contenido de los campos hexadecimales.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/-1ck40setulE/VgAs6lkqx4I/AAAAAAAAAgQ/JCt9akbtjP0/s1600/Fichero%2BComprimido%2BISPF.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://3.bp.blogspot.com/-1ck40setulE/VgAs6lkqx4I/AAAAAAAAAgQ/JCt9akbtjP0/s400/Fichero%2BComprimido%2BISPF.jpeg" width="400" /></a></div>
<br />
Si ya conocíais esta forma de visualizar los ficheros comprimidos desde ISPF, entonces este post os habrá parecido superfluo. Sin embargo, debéis tener en cuenta que hay muchos programadores principiantes que, un buen día, se enfrentan con su <span style="color: lime;"><b>primer fichero comprimido</b></span> y en ese momento no saben cómo proceder para leer los datos de los registros. A ellos está dedicado este texto.<br />
<br />
Pues nada, eso es todo por hoy. Espero que lo comentado os haya servido para aprender algo nuevo y, lo más importante, que os valga para agilizar vuestro trabajo cotidiano.<br />
<br />
Saludos.<br />
<br /></div>
Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0tag:blogger.com,1999:blog-8613600796016988320.post-71316182329440293572015-10-12T12:00:00.000+02:002015-10-16T14:16:08.429+02:00Buscar varios Ficheros a la vez en ISPF (y 2)<div class="MsoNormal">
Hace algunas semanas comenzamos a ver cómo se podían buscar (y editar) varios ficheros a la vez desde la herramienta ISPF. Se trata de una opción que nos puede facilitar mucho las cosas en el día a día, ya que no es lo mismo poder realizar una búsqueda múltiple que tener que ir accediendo a todos los ficheros uno a uno.<br />
<br />
En la primera parte del post vimos un ejemplo de búsqueda simple y, además, hicimos un esbozo de qué es lo que se entiende por editar varios ficheros a la vez (ver post <a href="http://www.universocobol.com/2015/10/buscar-varios-ficheros-la-vez-en-ispf.html">Buscar varios ficheros a la vez en ISPF - 1</a>). Hoy vamos a entrar en detalle y procederemos a examinar los dos casos modelo que cubrirán el 90% de nuestras necesidades a este respecto.<br />
<br />
<h2>
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;"><span style="font-size: large;"><b>¿Cómo podemos editar varios ficheros a la vez en ISPF?</b></span> </span></h2>
</div>
<div class="MsoNormal">
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">El caso de búsqueda simple que mostramos anteriormente <b>nos sirve si
queremos acceder a un único fichero y si, además, conocemos el nombre del
mismo</b>. Pero, ¿qué pasaría si quisiéramos visualizar el contenido de varios
ficheros (cuyos nombres tengan alguna <b><span style="color: orange;">cadena de caracteres</span></b> en común)? ¿Y qué
pasaría si no conociésemos el nombre completo del fichero buscado?</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoSubtitle">
<h3>
<span style="color: cyan;"><i><span style="font-size: large;">Caso 1: Editar varios ficheros a la vez en ISPF</span></i></span></h3>
</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Imaginemos, en primer lugar, que en nuestra
aplicación queremos ir viendo el contenido de varios ficheros generados por un
<span style="color: lime;"><b>determinado proceso</b></span> que realiza la tramitación de Tarjetas (TARJ). Esta <a href="http://www.universocobol.com/search/label/JCL">fase JCL</a> genera múltiples datasets con distintos nombres y sabemos que en todos ellos va
a figurar la cadena de texto TARJ. </span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Entonces, en vez de ir poniendo el nombre de cada
uno de los ficheros y accediendo a su contenido uno a uno, <b>lo óptimo sería
introducir la cadena de texto común</b> en el campo DSNAME LEVEL de la <a href="https://es.wikipedia.org/wiki/ISPF">herramienta ISPF</a>. En
nuestro caso, podríamos incluir el texto ASTR.A801.*.**.*TARJ*.</span><br />
<br />
<a href="http://2.bp.blogspot.com/-nkX3xsL1RuI/VfEnefKqXYI/AAAAAAAAAfk/3aP_W_PbkCs/s1600/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv3.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://2.bp.blogspot.com/-nkX3xsL1RuI/VfEnefKqXYI/AAAAAAAAAfk/3aP_W_PbkCs/s640/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv3.png" width="640" /></a><span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;"> </span><br />
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Al pulsar INTRO se nos van a mostrar todos los
ficheros cuyo nombre cumpla con las condiciones introducidas anteriormente.</span><br />
<br />
<a href="http://3.bp.blogspot.com/-42Y0JgRAEMU/VfEneSDbKBI/AAAAAAAAAfg/jmI-UgY_ma8/s1600/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv4.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://3.bp.blogspot.com/-42Y0JgRAEMU/VfEneSDbKBI/AAAAAAAAAfg/jmI-UgY_ma8/s640/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv4.png" width="640" /></a><span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;"> </span><br />
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Como vemos, se han obtenido todos los datasets que
comienzan por “ASTR.A801”<span style="mso-spacerun: yes;"> </span>y que tienen
la <span style="color: magenta;"><b>cadena de texto</b></span> “TARJ” en alguna posición de su denominación. En total,
tenemos 7 ficheros y nos hemos ahorrado el trabajo de tener que ir editando
cada uno de ellos por separado.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoSubtitle">
<h3>
<span style="color: cyan;"><i><span style="font-size: large;">Caso 2: Editar un fichero sin conocer el nombre exacto</span></i></span></h3>
</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Imaginemos ahora, en segundo lugar, que queremos
<b>editar un fichero del que no recordamos su nombre exacto</b>. Sabemos que se trata
de un fichero de Incidencias y que en el sexto <span style="color: orange;"><b>bloque</b></span> de su denominación figura
la cadena de texto “INCI”. De manera análoga al primer caso, aquí podríamos
incluir en el campo DSNAME LEVEL del ISPF el texto ASTR.A801*.*.*.*.INCI*.</span><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://2.bp.blogspot.com/-0_SsxZvzpJ0/VfEne8bw-5I/AAAAAAAAAfs/N7guWnxHNvU/s1600/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv5.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://2.bp.blogspot.com/-0_SsxZvzpJ0/VfEne8bw-5I/AAAAAAAAAfs/N7guWnxHNvU/s640/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv5.png" width="640" /></a></div>
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Al pulsar INTRO se nos va a mostrar el <a href="http://www.universocobol.com/search/label/Ficheros">fichero</a> (o ficheros)
cuyo nombre cumple con las condiciones introducidas anteriormente.</span><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://4.bp.blogspot.com/-TJ0Tux5X-3M/VfEnfKPWpqI/AAAAAAAAAf4/mG3cBrDWJro/s1600/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv6.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="382" src="http://4.bp.blogspot.com/-TJ0Tux5X-3M/VfEnfKPWpqI/AAAAAAAAAf4/mG3cBrDWJro/s640/Edicion%2BMultiple%2BFicheros%2BISPF%2Bv6.png" width="640" /></a></div>
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Como se observa, en la <span style="color: magenta;"><b>pantalla</b></span> han aparecido todos
los datasets que comienzan por “ASTR.A801”<span style="mso-spacerun: yes;">
</span>y que tienen la cadena de texto “INCI” en el sexto bloque de su
denominación. En total, tenemos 7 ficheros. Sin lugar a dudas, el fichero de
Incidencias que buscamos será uno de ellos y lo hemos encontrado sin necesidad
de recordar su nombre completo.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Una vez visto estos dos ejemplos, creo que no hace
falta hacer mucho más hincapié en el considerable ahorro de tiempo que supondrá
el uso de las <span style="color: lime;"><b>búsquedas múltiples</b></span>. Y lo mejor de todo es que el procedimiento es
bastante fácil de recordar, siempre y cuando no hayan transcurrido más de 5
años desde la última vez que lo pusimos en práctica (como le pasó a mi
compañero)…</span><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://3.bp.blogspot.com/--XNkdrEWCDw/Ve7rz73alLI/AAAAAAAAAeo/cF9g7HqIAQU/s1600/Busqueda%2BMultiple%2BFicheros%2BISPF%2Bv3.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="266" src="http://3.bp.blogspot.com/--XNkdrEWCDw/Ve7rz73alLI/AAAAAAAAAeo/cF9g7HqIAQU/s400/Busqueda%2BMultiple%2BFicheros%2BISPF%2Bv3.jpg" width="400" /></a></div>
<br />
<h2>
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;"><span style="font-size: large;"><b>Conclusiones acerca de la edición múltiple de ficheros del ISPF</b></span> </span></h2>
</div>
<div class="MsoNormal">
<br />
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Si estamos buscando un fichero determinado y nos
sabemos su denominación exacta, en general haremos uso de la edición simple del <span style="color: cyan;"><b>Data Set List Utility</b></span> de la <a href="http://www.universocobol.com/search/label/ISPF">utilidad ISPF</a>. En este caso, bastará con introducir
el nombre completo en el campo DSNAME LEVEL y la herramienta nos mostrará el
fichero indicado.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Sin embargo, en los casos en que queramos editar
varios ficheros a la vez (o si simplemente no recordamos el nombre completo de
nuestro dataset) <b>no nos quedará más remedio que hacer uso de la edición
múltiple de la utilidad</b>. Esto se conseguirá introduciendo el carácter “*”
(asterisco) en las <span style="color: magenta;"><b>posiciones requeridas</b></span> del texto introducido en el campo
DSNAME LEVEL, tal y como se ha explicado en los ejemplos comentados a lo largo
del artículo.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Obviamente, <b>se trata de una funcionalidad muy simple
y con la que se obtiene un considerable ahorro de tiempo a largo plazo</b>. Si no
sabíais hacer la <span style="color: orange;"><b>edición múltiple</b></span>, lo más probable es que, una vez leído este
post, probéis a lanzar la búsqueda en ISPF por primera vez y ya nunca más tengáis
necesidad de volver a consultar cómo se hace. Las cosas sencillas no suelen
olvidarse con facilidad…</span><br />
<br />
<a href="http://1.bp.blogspot.com/-dOqkx6SjEIA/Ve7q4TByt4I/AAAAAAAAAeg/iKWEgTKvUDQ/s1600/Busqueda%2BMultiple%2BFicheros%2BISPF%2Bv2.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="303" src="http://1.bp.blogspot.com/-dOqkx6SjEIA/Ve7q4TByt4I/AAAAAAAAAeg/iKWEgTKvUDQ/s400/Busqueda%2BMultiple%2BFicheros%2BISPF%2Bv2.png" width="400" /></a><span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;"> </span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Os comento esto porque fue precisamente lo que me
sucedió a mí. Al principio, cuando empecé a programar en Cobol y a trabajar en
el entorno ISPF, no sabía cómo hacer una búsqueda múltiple de ficheros y tuve
que pedir ayuda a un compañero. Desde entonces, ya no he tenido que volver a
preguntarlo nunca más (y ahora incluso ya está escrito en el blog).</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Pues nada, no queda mucho más que contar con
respecto a la utilidad Data Set List Utility de ISPF. Si tenéis alguna duda al
respecto, ya sabéis que podéis dejarla en el apartado de comentarios y trataré
de responderos lo antes posible.</span></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="font-family: "Times New Roman","serif"; font-size: 12.0pt; line-height: 115%;">Saludos.</span></div>
Jose Sanchezhttp://www.blogger.com/profile/07329899684971024824noreply@blogger.com0