Manual SQR
Manual Técnico de Aprendizaje Elaborado por Business & Solutions Consulting, S. A.
Todos los derechos de propiedad intelectual del sistema Bancario “COBIS” son de la empresa Macosa de Ecuador.
Tabla de Contenido Un programa SQR simple .............................................................................................................................. 1 Programa ex1a.sqr ................................................................................................................................ 1 Procedimiento para crear y correr un programa SQR .............................................................................. 1 Salida del SQR ........................................................................................................................................... 1 Resumen ................................................................................................................................................... 2 Los encabezados y pies de página ................................................................................................................ 3 Program ex2a.sqr .................................................................................................................................. 4 Salida del programa ex2a.sqr ................................................................................................................ 4 Resumen ................................................................................................................................................... 5 Obteniendo datos de una base de datos ...................................................................................................... 6 Program ex3a.sqr .................................................................................................................................. 6 Salida del programa ex3a.sqr ................................................................................................................ 7 La sentencia SELECT de SQR ..................................................................................................................... 8 Sintaxis de la instrucción SELECT .............................................................................................................. 8 Posicionamiento de datos ......................................................................................................................... 9 Resumen ................................................................................................................................................... 9 Variables de Columnas ................................................................................................................................ 10 Resumen ................................................................................................................................................. 11 Lógica de rupturas....................................................................................................................................... 13 Program ex5a.sqr .................................................................................................................................... 13 Salida del programa ex5a.sqr .................................................................................................................. 14 Utilizando ON-BREAK .............................................................................................................................. 14 Program ex5b.sqr .................................................................................................................................... 15 Salida del programa ex5a.sqr .................................................................................................................. 15 Saltar líneas entre grupos ....................................................................................................................... 15 La organización de múltiples columnas de ruptura ................................................................................ 16 Program ex5c.sqr .................................................................................................................................... 17 Salida del programa ex5c.sqr .................................................................................................................. 17 Mejoras al procesamiento de rupturas. ........................................... ......................... ................................... ................................... .................................... .................. 18 Program ex5d.sqr .................................................................................................................................... 18 Salida del programa ex5d.sqr ................................................................................................................. 20
Tabla de Contenido Un programa SQR simple .............................................................................................................................. 1 Programa ex1a.sqr ................................................................................................................................ 1 Procedimiento para crear y correr un programa SQR .............................................................................. 1 Salida del SQR ........................................................................................................................................... 1 Resumen ................................................................................................................................................... 2 Los encabezados y pies de página ................................................................................................................ 3 Program ex2a.sqr .................................................................................................................................. 4 Salida del programa ex2a.sqr ................................................................................................................ 4 Resumen ................................................................................................................................................... 5 Obteniendo datos de una base de datos ...................................................................................................... 6 Program ex3a.sqr .................................................................................................................................. 6 Salida del programa ex3a.sqr ................................................................................................................ 7 La sentencia SELECT de SQR ..................................................................................................................... 8 Sintaxis de la instrucción SELECT .............................................................................................................. 8 Posicionamiento de datos ......................................................................................................................... 9 Resumen ................................................................................................................................................... 9 Variables de Columnas ................................................................................................................................ 10 Resumen ................................................................................................................................................. 11 Lógica de rupturas....................................................................................................................................... 13 Program ex5a.sqr .................................................................................................................................... 13 Salida del programa ex5a.sqr .................................................................................................................. 14 Utilizando ON-BREAK .............................................................................................................................. 14 Program ex5b.sqr .................................................................................................................................... 15 Salida del programa ex5a.sqr .................................................................................................................. 15 Saltar líneas entre grupos ....................................................................................................................... 15 La organización de múltiples columnas de ruptura ................................................................................ 16 Program ex5c.sqr .................................................................................................................................... 17 Salida del programa ex5c.sqr .................................................................................................................. 17 Mejoras al procesamiento de rupturas. ........................................... ......................... ................................... ................................... .................................... .................. 18 Program ex5d.sqr .................................................................................................................................... 18 Salida del programa ex5d.sqr ................................................................................................................. 20
Manejo de saltos de página .................................................................................................................... 22 Impresión de la Fecha ............................................................................................................................. 22 La obtención de los totales ..................................................................................................................... 22 Guiones y guiones bajos ......................................................................................................................... 23 Procedimientos de ruptura con BEFORE y AFTER. .................................................................................. 24 Comprensión de la Orden de Eventos .................................................................................................... 24 Program ex5e.sqr .................................................................................................................................... 25 Salida del programa ex5e.sqr .................................................................................................................. 27 Controlar los saltos de página en columnas con múltiples columnas ON-BREAK .................................. 29 Guardar un valor cuando ocurre una ruptura ........................................................................................ 30 Restricciones y limitaciones de ON-BREAK ............................................................................................. 30 Resumen ................................................................................................................................................. 30 Anexos ......................................................................................................................................................... 31 Funciones ................................................................................................................................................ 31 Relacionadas con archivos .................................................................................................................. 31 Funciones numéricas .......................................................................................................................... 31 Funciones misceláneas........................................................................................................................ 31 Variables reservadas ............................................................................................................................... 31 Definic.sqr ............................................................................................................................................... 32 Log.sqr ..................................................................................................................................................... 33 Begin-Procedure Inicializar_Programa................................................................................................ 33 Begin-Procedure Fecha_Proceso_Hoy ................................................................................................ 34 Begin-Procedure Validar_Dependencia .............................................................................................. 34 Begin-Procedure Verificar_Tiene_Padre............................................................................................. 35 Begin-Procedure Validar_Estatus_Padre ............................................................................................ 35 Begin-Procedure Analizar_Repeticion ................................................................................................ 36 Begin-Procedure Analizar_Una_Repeticion ........................................................................................ 36 Begin-Procedure Validar_Fecha ($fecha,:#flag) ................................................................................. 36 Begin-Procedure Error_Fecha ............................................................................................................. 37 Begin-Procedure Inicializar_Corrida ................................................................................................... 37 Begin-Procedure Clave_Duplicada ...................................................................................................... 38 Begin-Procedure Obtener_Parametros .............................................................................................. 38
Begin-Procedure Asignar_Parametros ................................................................................................ 38 Begin-Procedure Finalizar_Corrida ..................................................................................................... 39 Begin-Procedure Abortar .................................................................................................................... 40 Begin-Procedure Actualizar_Reg_Proc ............................................................................................... 40 Begin-Procedure Ejecutar_Actualizacion ............................................................................................ 41 Begin-Procedure ParamN (#indice,:#variable,$tabla,$cond,$mensaje) ............................................. 41 Begin-Procedure ParamS (#indice,:$variable,$tabla,$cond,$mensaje) ............................................. 41 Begin-Procedure Verificar_Existencia ($tablas,$condicion,$mensaje) .............................................. 41 Begin-Procedure Comparar_Fechas ($fecha_i,$fecha_f,:#flag) ......................................................... 42 Begin-Procedure Centrar_Show ($mensaje,#fila) .............................................................................. 42 Begin-Procedure Finalizar_Programa ................................................................................................. 42 Begin-Procedure Nombre_Programa_Fuente (:$nombre) ................................................................. 42 Begin-Procedure Generar_Listado (#oficina)...................................................................................... (#oficina)...................................................................................... 43 Begin-Procedure Generar_Listado2 (#oficina,#producto) .................................................................. 43 Begin-Procedure Before_Pagina ......................................................................................................... 44 Begin-Procedure Begin-Proced ure After_Pagina .................................. ................. ................................... ................................... ................................... ................................... ..................... .... 44
Un programa SQR simple En este capítulo aprenderá tres comandos de SQR:
Begin-Program
End-Program
Print
El primer ejemplo es el programa SQR más simple posible. Solamente imprime una cadena de caracteres.
Programa ex1a.sqr begin-program print ’Hola Mundo.’ (1,1) end-program
Procedimiento para crear y correr un programa SQR Debe abrir un editor de texto y escribir el código del programa tal cual aparece. Luego guarde el programa con el nombre deseado y la extensión “.sqr” Para este ejemplo, grabe el archivo como “ex1a.sqr”.
Para correr el programa, si está ingresando la información de la línea de comandos, incluya "sqr" o "sqrw", el nombre del programa SQR y la cadena de conexión, todo en una sola línea. El SQR para sistemas Windows, SQR es invocada desde la línea de comandos con "sqrw". En los sistemas UNIX, SQR es invocada desde la línea de comandos con "sqr". La sintaxis siguiente se muestra cómo ejecutar SQR de la línea de comandos:
[sqr o sqrw] [] programa [conectividad] [banderas ...] [args ...] [@ archivo ...]
Salida del SQR SQR normalmente coloca a la salida de los archivos de programa SQR en el directorio de la el que se ejecute el programa. El archivo de salida tendrá el mismo nombre de archivo SQR que el archivo que lo creó, pero la extensión del archivo será diferente. Los archivos de salida deben aparecer tan pronto como ha terminado su programa de funcionamiento. Normalmente la salida del programa tendrá el mismo nombre que el programa fuente, pero su extensión será “.lis” en lugar de “.sqr”.
Eche una mirada al programa de ejemplo “ex1a.sqr”. Este programa consiste en
tres líneas de código, empezando por BEGIN-PROGRAM y termina con
1
END-PROGRAM. Estos dos comandos y el código entre ellos componen la sección de programas, que se utiliza para controlar el orden del procesamiento. La sección PROGRAM es necesaria, y usted puede tener sólo una por programa. Normalmente se coloca en o cerca de la parte superior del programa. La sección del programa contiene un comando de impresión, que en este caso, imprime el texto "Hola, Mundo". Este texto se encierra en comillas simples marcas ( '), que se utilizan en SQR para distinguir el texto literal de otros elementos del programa. El último elemento del comando Imprimir da la posición en la salida página. Una página de salida puede ser pensada como una cuadrícula de líneas y columnas. El "(1,1)" indica la línea uno, una columna, que es la esquina superior izquierda de la la página. En SQR, usted debe colocar cada comando en una línea nueva. Puede indentar los comandos SQR
Resumen
La sección de programas es que la ejecución del programa comienza.
El comando de impresión se puede utilizar para imprimir una cadena de texto.
La posición de impresión puede ser expresado por un par de números encerrados en paréntesis.
Introduzca cada comando en una línea nueva.
El siguiente capítulo explica la forma de ampliar su programa mediante la impresión de un título en la parte superior de la página y el número de página en la parte inferior de la página.
2
Los encabezados y pies de página Este capítulo explica cómo crear encabezados y pies de página. Usted aprenderá a usar el BEGINHEADING y BEGIN-FOOTING. Por lo general, cada página de un informe tiene alguna información sobre el informe de en sí, tales como el título, la fecha y el número de página. En SQR, la página se puede dividir en tres áreas lógicas. El área superior de la página es la cabecera. Aquí es donde normalmente se imprime el título del informe y la fecha. La zona inferior de la página es el pie de página. Aquí se suele imprimir el número de página. La parte central de la página se llama el cuerpo. Esta es donde se imprimen los datos del informe. El siguiente diagrama muestra la estructura de una página con el encabezado, el cuerpo y de pie de página:
El gráfico muestra también que la cabecera, el cuerpo y el pie de página tienen números de línea independientes. Usted puede imprimir en cada una de estas áreas página utilizando los números de línea que son relativos a la esquina superior de esa zona sin preocuparse por el tamaño de las otras áreas. En otras palabras, usted puede de impresión a la primera línea del cuerpo utilizando el número de la línea 1, independiente del tamaño de la cabecera. El programa que usted escribió en el capítulo anterior se puede ampliar añadiendo un encabezamiento y pie de página. Aquí está el código:
3
Program ex2a.sqr begin-program print ’Hello, World.’ (1,1) end-program begin-heading 1 print ’Tutorial Report’ (1) center end-heading begin-footing 1 !print "Page n of m" in the footing page-number (1,1) ’Page ’ last-page () ’ of ’ end-footing
Salida del programa ex2a.sqr
La cabecera se define en la sección HEADING. La sección comienza con BEGIN-HEADING y termina con END-HEADING. El comando BEGIN-HEADING es seguido por un número, que es el número de líneas reservadas para el título. En nuestro ejemplo, el título tendrá exactamente una línea y consistirá en el texto "Tutorial Report". El argumento CENTER asegura que el texto se centra en la línea. El pie de página se define en la sección FOOTING, que comienza con la instrucción BEGIN-FOOTING y termina con END-FOOTING. El comando BEGIN-FOOTING es seguido por el número 1, lo que significa que el pie de página será de solo una línea. Esta línea estará compuesta por el texto "Page 1 of 1." Tenga en cuenta que cualquier espacio reservado para el título y pie se le quita del cuerpo. Con una línea cada uno en el encabezamiento y pie, el máximo tamaño posible del cuerpo de nuestro informe se reduce en dos líneas.
4
Nótese también que la línea 1 del cuerpo es en realidad la primera línea después de la partida. La primera línea en la sección de PIE es un comentario. Los comentarios se preceden por un signo de exclamación, y se extienden desde el signo de exclamación hasta el final de la línea. Si desea imprimir un signo de exclamación, se debe escribir dos veces para decirle que no SQR a tomar como el comienzo de un comentario. Por ejemplo: print ’Hello, World!!’ (1,1) La instrucción PAGE-NUMBER imprime el texto "Page" y el número de página actual. El comando LASTPAGE imprime el número de la última página, precedido por la palabra "of", que está entre espacios. En nuestro ejemplo, SQR imprime "Page 1 of 1" porque hay una sola página. Note los paréntesis en los comandos PRINT, PAGE-NUMBER y LAST-PAGE. Los números entre estos paréntesis dar la posición de impresión. Una posición en SQR se expresa en tres números en paréntesis - (línea, columna, ancho)-donde la línea es el número de línea, columna es la columna (posición de caracteres) y el ancho es el ancho del texto. En muchos casos, consiste únicamente en una posición de la línea y columna de números. La anchura suele omitirse, ya que por defecto es la anchura del texto se está imprimiendo. Si también se omite la línea y columna de números, la impresión de defecto de posición a la posición actual, la posición siguiente a lo último que se imprimió. En el ejemplo, el último comando de página tiene la posición de "()" Para que la situación actual aquí es la siguiente posición en el número de página. La posición de impresión es un punto dentro de la zona de la página, o más precisamente, dentro del cuerpo de la partida, o de pie. La posición (1,1) en el título es no la misma que la posición (1,1) en el cuerpo. Línea 1 del cuerpo es la primera por debajo de la línea de la cabecera. En el programa, el título sólo tiene una línea, de modo la línea 1 del cuerpo es en realidad la segunda línea de la página. Del mismo modo, la línea 1 del pie de página está en la parte inferior de la página. Es la primera línea después del cuerpo. ¿Cuál es el orden de ejecución? El comando PRINT realmente coloca el texto en la memoria, no en papel. SQR siempre prepara una página en la memoria antes de de impresión al papel, realizando el primer cuerpo, a continuación, el título y Secciones de base. En este caso, "Hello, World" se ejecuta en primer lugar, a continuación, "Tutorial Report" y finalmente "Page 1 of 1."
Resumen
Un programa SQR puede tener secciones HEADING y FOOTING que crean el encabezado y pie de página de cada página del reporte.
La opción CENTER del comando PRINT centrea el texto en una línea.
Los números de página pueden imprimirse en el formato “Page n of m” con los comandos PAGE -
NUMBER y LAST-PAGE
Las posiciones de impresión se expresan por números entre paréntesis
5
Obteniendo datos de una base de datos En este capítulo se describe cómo escribir un programa que muestra los datos de la base de datos y lo imprime en las columnas. Usted aprenderá el comando BEGIN-SELECT que es el principal medio de recuperación de datos de la base de datos e impresión en un informe. Debido a que el comando BEGIN SELECT debe usarse dentro de en un procedimiento, también aprenderá a utilizar los procedimientos. Aquí está el código.
Program ex3a.sqr begin-program do list_customers end-program begin-heading 4 print ’Customer Listing’ (1) center print ’Name’ (3,1) print ’City’ (,32) print ’State’ (,49) print ’Phone’ (,55) end-heading begin-footing 1 !Print "Page n of m" in the footing page-number (1,1) ’Page ’ last-page () ’ of ’ end-footing begin-procedure list_customers begin-select name (,1) city (,32) state (,49) phone (,55) position (+1) !Advance to the next line from customers end-select end-procedure !list_customers
6
Salida del programa ex3a.sqr
La sección de programa consta de un comando DO único, que invoca al procedimiento list_customers. En SQR, un procedimiento es un grupo de comandos que se ejecutan, uno tras el otro, como un procedimiento (o subrutina) en la programación de otros idiomas. Un procedimiento se invoca con un comando DO. Le recomendamos que divida la lógica del programa en procedimientos y mantenga pequeña la sección PROGRAM. Normalmente, debería consistir en unos cuantos comandos DO para los componentes principales de su informe. La sección HEADING (que se muestra más abajo) crea las títulos de las columnas del informe. Cuatro líneas están reservadas para el título.
7
begin-heading 4 print ’Customer Listing’ (1) center print ’Name’ (3,1) print ’City’ (,32) print ’State’ (,49) print ’Phone’ (,55) end-heading
El título de "Customer Listing" está impreso en la línea 1. La línea 2 se deja en blanco. El título de la primera columna , "Name", se coloca en la línea 3 de la cabecera, posición de carácter 1. El resto de los comandos de la sección HEADING omiten los números de línea en sus posiciones y por defecto utilizan la línea actual. La línea 4 del el título se deja en blanco.
La sentencia SELECT de SQR Veamos de nuevo el procedimiento list_customers, que comienza con BEGIN-PROCEDURE y termina con END-PROCEDURE. Tenga en cuenta el comentario siguiente a la instrucción END-PROCEDURE. Le dice cuál procedimiento se está terminado, lo cual es útil cuando se tiene un programa con muchos procedimientos. (También se puede omitir el signo de exclamación: END-PROCEDURE main.) El procedimiento en sí contiene un párrafo SELECT, que comienza con BEGIN-SELECT y termina con END-SELECT. El párrafo SELECT es único. Se combina una instrucción SQL SELECT con el procesamiento de SQR en una forma perfecta. La instrucción SQL real es:
SELECT NAME, CITY, STATE, PHONE FROM CUSTOMERS
Sintaxis de la instrucción SELECT En el párrafo SQR SELECT, el SELECT palabra se omite, y no hay comas entre los nombres de columna. En su lugar, cada columna está en su propia línea. También puede colocar los comandos SQR entre los nombres de columna, y estos comandos se ejecutan para cada registro que el SELECT obtiene. Nota: Se deben nombrar cada columna de la tabla. La instrucción “select * from” no está permitida en SQR.
SQR distingue los nombres de columna de los comandos SQR en un SELECT párrafo por su sangría. Los nombres de columna debe ser colocado en el principio de una línea. Los comandos SQR comandos deben tener una sangría de al menos un espacio. En el siguiente ejemplo, el comando POSITION es indentado para evitar ser tomado como un nombre de columna. La palabra FROM debe ser la primera palabra en una línea. El resto de la instrucción SELECT de SQR se escribe libremente, siguiendo la sintaxis SQL.
8
Usted puede pensar en el párrafo SELECT como un bucle. Los comandos SQR, incluida la impresión de las columnas, se ejecutan en un bucle, una vez para cada registro que es devuelto por el SELECT. El ciclo termina después que el último registro es devuelto.
Posicionamiento de datos En la instrucción SELECT (repite a continuación), se ve la posición después de cada nombre de la columna. Este posicionamiento implica un comando de impresión para esa columna. Como antes, omitiendo el número de línea en la posición usa por defecto a la línea actual.
begin-select name (,1) city (,32) state (,49) phone (,55) position (+1) !Advance to the next line from customers end-select
El comando PRINT implícito de SQR es una característica especial diseñada para ahorrar el tiempo de codificación. Sólo funciona dentro de un párrafo SELECT. Después de la última columna, hay un comando Position: (+1). El signo más (o un signo menos) indica la posición relativa en SQR. Un signo más que la posición de impresión se mueve hacia adelante desde la posición actual, y un signo menos se mueve hacia atrás. El "1" en nuestro programa significa una línea de por debajo de la línea actual. Este comando hará avanzar la impresión actual la posición a la línea siguiente. Cuando se indican las posiciones de impresión mediante signos más o menos, asegúrese de que su número no especifica una posición fuera de los límites de página.
Resumen
El comando DO es utilizado para invocar un procedimiento.
Un procedimiento comienza con BEGIN-PROCEDURE y termina con END-PROCEDURE
Un párrafo SELECT comienza con BEGIN-SELECT y termina con END-SELECT.
Los comandos de SQR en un párrafo SELECT deben estar indentados por lo menos un espacio para evitar que se tomen como nombres de columna.
En una instrucción SELECT, puede imprimir una columna colocando su nombre en el principio de la línea con un calificador de posición. Esto se llama un comando de impresión implícito. El comando de posición se utiliza para indicar la posición.
El siguiente capítulo se describe un tipo especial de variable SQR llama variable de columna. Estas variables tienen los resultados de un párrafo SELECT.
9
Variables de Columnas Este capítulo explica cómo nombrar las columnas de base de datos con las variables y de cómo utilizar sus valores en las condiciones y los comandos. Al seleccionar las columnas de la base de datos en un párrafo SELECT, inmediatamente puede imprimir utilizando una posición. Por ejemplo:
begin-select phone (,1) position (+1) from customers end-select
Pero si lo que desea es utilizar el valor del teléfono para otro propósito, por ejemplo, en una condición? El siguiente ejemplo muestra cómo hacerlo
begin-program do list_customers end-program begin-procedure list_customers begin-select phone if &phone = ’’ print ’No phone’ (,1) else print &phone (,1) end-if position (+1) from customers end-select end-procedure !list_customers
La columna de teléfono se considera una variable de columna SQR. Variables de columna están precedidos por un ampersand (&). A diferencia de las variables de otro programa, las variables de columna son de sólo lectura. Puede utilizar su valor existente, pero no se puede asignar un nuevo valor a una variable de columna.
10
En el programa de ejemplo, &phone es una variable de columna que se puede utilizar en sentencias SQR como si se tratara de una cadena, fecha o variable numérica en función de su contenido. En la condición &phone se compara con ‘’, una cadena vacía. Si el &phone es una cadena vacía, el programa imprime "No hay teléfono". Tenga en cuenta que la variable de la columna &phone ha heredado su nombre de la columna phone. Este es el comportamiento por defecto, pero usted puede cambiarlo, como los siguientes ejemplos lo demuestran.
begin-select phone &cust_phone if &cust_phone = ’’ print ’No phone’ (,1) else print &cust_phone (,1) end-if position (+1) from customers end-select
¿Por qué quieres cambiar el nombre de la variable de columna? Una razón es que usted quisiera utilizar una columna que no tiene nombre. Por ejemplo:
begin-select count(name) &cust_cnt (,1) if &cust_cnt < 100 print ’Less than 100 customers’ end-if position (+1) from customers group by city, state end-select
En este ejemplo, se selecciona la expresión count(name). En el programa, se almacena esta expresión en la variable de columna &cust_cnt y se refiere a ella después con ese nombre.
Resumen
En SQR, podemos hacer referencia a las columnas de base de datos como variables. Las variables de columnas están precedidas por un ampersand (&). Las variables de columna se pueden utilizar en los comandos y condiciones. Podemos cambiar el nombre de las variables de columna para recibir el valor de las expresiones.
El siguiente capítulo se introduce el concepto de una ruptura informe. Será también se explica cómo imprimir los registros de base de datos a través de varias líneas en un informe.
11
12
Lógica de rupturas Este capítulo describe las técnicas para el uso de la lógica de rupturas en sus programas SQR. También se presentan algunas técnicas adicionales para mejorar la apariencia de los informes que utilizan la lógica de rupturas. Una ruptura es un cambio en el valor de una columna o variable. Registros con el mismo valor, por ejemplo, los registros con el mismo valor para el Estado, lógicamente pertenecen a un grupo. Cuando se produce una ruptura, un nuevo grupo comienza. Hay una serie de razones para utilizar la lógica de ruptura en un informe. Le permite: •
Añadir un espacio en blanco a sus informes
• •
Evitar los datos redundantes de impresión Realizar el procesamiento condicional de variables que cambian
•
Imprimir subtotales
Por ejemplo, usted puede querer preparar un informe de ventas con los registros agrupados por producto, región, o vendedor (o los tres). La lógica de rupturas le permite hacer todo eso y más. Usted puede imprimir los encabezados de columna, el recuento de registros, subtotal de una columna, y realizar un procesamiento adicional en el contar o subtotal. Para ver cómo funciona una ruptura, puede escribir un programa similar al del Capítulo 3, y luego agregarle la lógica de la ruptura. La lógica de rupturas hará que el agrupamiento sea más evidente. Aquí está el programa, sin lógica de ruptura:
Program ex5a.sqr begin-program do list_customers end-program begin-heading 2 print ’State’ (1,1) print ’City’ (1,7) print ’Name’ (1,24) print ’Phone’ (1,55) end-heading begin-procedure list_customers begin-select state (,1) city (,7) name (,24) phone (,55) position (+1) !Advance to the next line from customers order by state, city, name end-select end-procedure !list_customers 13
Salida del programa ex5a.sqr
Cuando la salida está ordenada por estado, ciudad, y el nombre (note la cláusula ORDER BY en el BEGINSELECT), los registros se agrupan por el estado. Para hacer la agrupación más evidente, se puede agregar un salto.
Utilizando ON-BREAK 1. En el programa siguiente, la opción ON-BREAK del comando PRINT lleva a cabo dos tareas relacionadas Inicia un grupo nuevo cada vez que el valor de “state” cambia.
2. Imprime “state” solamente una vez cuando su valor cambia. Tenga en cuenta que ON-BREAK funciona tanto con los comandos PRINT implícitos como con los explícitos como en el ejemplo siguiente, donde el estado, ciudad, nombre y teléfono son implícitamente impresos como parte del párrafo SELECT. El programa siguiente es idéntico al ex5a.sqr con la excepción de la línea de que imprime la columna de estado. Esta línea se muestra en negrita.
14
Program ex5b.sqr begin-program do list_customers end-program begin-heading 2 print ’State’ (1,1) print ’City’ (1,7) print ’Name’ (1,24) print ’Phone’ (1,55) end-heading begin-procedure list_customers begin-select state (,1) on-break
city (,7) name (,24) phone (,55) position (+1) !Advance to the next line from customers order by state, city, name end-select end-procedure !list_customers
Salida del programa ex5a.sqr
Con el procesamiento de rupturas, la abreviatura del estado se ha impreso una sola vez para cada grupo.
Saltar líneas entre grupos Usted puede mejorar aún más el efecto visual de procesamiento de rupturas mediante la inserción de una o más líneas entre los grupos. Para ello, utiliza el calificador SKIPLINES con ON-BREAK. Aquí está el procedimiento list_customers de ex5b.sqr, con la línea modificada en negrita:
15
begin-select state (,1) on-break skiplines=1
city (,7) name (,24) phone (,55) position (+1) !Advance to the next line from customers order by state, city, name end-select
La salida se muestra a continuación:
La organización de múltiples columnas de ruptura Como se puede ver en el ejemplo anterior, usted también puede tener múltiples clientes dentro de una ciudad. Puede aplicar el mismo concepto de ruptura a la columna ciudad para que este grupo de clientes sea más evidente. Añada otro ON-BREAK en el programa para que la ciudad también se imprima sólo cuando cambie de valor. Cuando usted tiene múltiples rupturas, es necesario organizarlos en una jerarquía. En el programa de ejemplo, las rupturas son unidades geográficas, por lo que es lógico para ponerlas en función del tamaño de cada una asi: estado primero, luego la ciudad. Este tipo de sistema se denomina de anidación, y las rupturas se dice que están anidadas. Para asegurarse de que las rupturas estén debidamente anidadas, utilice la palabra clave LEVEL. Este argumento numera las ruptruas por nivel y especifica que las columnas sean impresas en orden
16
incremental del nivel de ruptura de izquierda a derecha. Numere sus rupturas en el mismo orden en el que están ordenados los registros de acuerdo a la cláusula “ORDER BY”.
El calificador LEVEL le permite controlar el orden en que usted llama los procedimientos de ruptura. El siguiente ejemplo es idéntico al ex5a.sqr con la excepción de dos líneas que imprimen el Estado y las columnas de la ciudad. Estas dos líneas se muestran en la negrita.
Program ex5c.sqr begin-program do list_customers end-program begin-heading 2 print ’State’ (1,1) print ’City’ (1,7) print ’Name’ (1,24) print ’Phone’ (1,55) end-heading begin-procedure list_customers begin-select state (,1) on-break level=1 city (,7) on-break level=2
name (,24) phone (,55) position (+1) !Advance to the next line from customers order by state, city, name end-select
Salida del programa ex5c.sqr
17
Mejoras al procesamiento de rupturas. Cuando se utiliza la lógica de ruptura, es posible que desee mejorar su informe controlando los saltos de página o calculado contadores y totales para la columna del ON-BREAK. El siguiente ejemplo ilustra estas técnicas. El programa selecciona el nombre del cliente, dirección y número de teléfono de la base de datos. El procesamiento de ruptura se realiza sobre la columna de estado. Aquí está el código:
Program ex5d.sqr begin-program do list_customers end-program begin-heading 4 print ’Customers Listed by State’ (1) center print $current-date (1,1) Edit ’DD -Mon-YYYY’ print ’State’ (3,1) print ’Customer Name, Address and Phone Number’ (,11) print ’-’ (4,1,9) fill print ’-’ (4,11,40) fill end-heading begin-footing 2 !print "Page n of m" page-number (1,1) ’Page ’ last-page () ’ of ’ end-footing begin-procedure state_tot print ’ Total Customers for State: ’ (+1,1) print #state_total () edit 999,999 position (+3,1) !Leave 2 blank lines. let #cust_total = #cust_total + #state_total let #state_total = 0 end-procedure !state_tot
18
begin-procedure list_customers let #state_total = 0 let #cust_total = 0 begin-select !The ’state’ field will only be printed when it !changes. The procedure ’state_tot’ will also be !executed only when the value of ’state’ changes. state (,1) on-break print=change/top-page after=state_tot name (,11) addr1 (+1,11) !continue on second line addr2 (+1,11) !continue on third line city (+1,11) !continue on fourth line phone (,+2) edit (xxx)bxxx-xxxx !Edit for easy reading. !Skip 1 line between listings. !Since each listing takes 4 lines, we specify ’need=4’ to !prevent a customer’s data from being broken across two pages. next-listing skiplines=1 need=4 let #state_total = #state_total + 1 from customers order by state, name end-select if #cust_total > 0 print ’ Total Customers: ’ (+3,1) print #cust_total () edit 999,999 !Total customers printed. else print ’No customers.’ (1,1) end-if end-procedure !list_customers
19
Salida del programa ex5d.sqr
20
Echa un vistazo al código. La información se imprime utilizando un párrafo SELECT en el procedimiento list_customers. El estado y el nombre del cliente se imprimen en la primera línea. La dirección del cliente
y el teléfono están impresos en las siguientes tres líneas. El programa también utiliza el argumento AFTER= STATE_TOT. Este argumento llama al procedimiento state_tot después de cada cambio en el valor de estado. El orden de procesamiento se explica en la sección "Configuración de Quiebre Procedimientos de antes y después ".
21
Manejo de saltos de página Si se produce un salto de página dentro de un grupo, puede que desee volver a imprimir los encabezados y el valor de la columna que ocasionó el salto en la parte superior de la nueva página. Para controlar la impresión del valor, use PRINT = CHANGE / TOP-PAGE. Con este parámetro, el valor de la columna ON-BREAK se imprimirá cuando la columna cambie y después de cada salto de página. En este ejemplo, el valor de estado será impreso no sólo cuando cambie, sino que también cada vez que el inicie una nueva página. Para formatear los registros utilice el comando NEXT-LISTING. Este comando sirve a dos propósitos. El argumento SKIPLINES = 1 se salta una línea entre los registros, a continuación, reenumera la línea actual como línea 1. El argumento NEED = 4 impide que un LISTING quede dividido dos páginas, especificando el número mínimo de líneas necesarias para escribir un nuevo LISTING en la página actual. En este caso, si hay menos de cuatro líneas al final de la página, SQR iniciará una nueva página.
Impresión de la Fecha En la sección HEADING, la variable reservada $current-date se utiliza para imprimir la fecha y la hora. Esta variable se inicializa con la fecha y la hora de la máquina cliente en el inicio de la ejecución del programa. SQR proporciona variables predefinidas o reservadas para una variedad de usos. En este ejemplo, el comando completo es PRINT $current-date (1,1) EDIT ‘DD / MM / AAAA’ Se imprime la fecha y la hora en la posición 1,1 de la cabecera. El argumento EDIT especifica una máscara de edición, o formato, para la impresión de la fecha. SQR proporciona una gran variedad de máscaras de formato para su uso en números, fechas y cadenas. Tenga en cuenta que el comando de impresión para el título del informe precede a la orden para la fecha actual $current-date , aunque la fecha está a la izquierda y el título está a la derecha. SQR siempre arma la página en la memoria antes de imprimir, de modo que el orden de estos comandos no importa siempre que utilice la posición correcta impresión. Los dos últimos comandos en la sección de encabezado de impresión de una serie de guiones bajo los encabezados de columna. Observe el uso de la opción de FILL del comando PRINT. Esta opción le dice al SQR que rellene el ancho especificado con este patrón. Es una buena manera de imprimir una línea. En la sección FOOTING, vamos a imprimir la "Página n de m" como hicimos en ejemplos anteriores.
La obtención de los totales El programa ex5d.sqr también imprime dos totales: un subtotal de los clientes en de cada estado y un gran total de todos los clientes. Estos cálculos se realizan con dos variables numéricas, una para los subtotales y otro para los totales generales. Sus nombres son #state_total y #cust_total, respectivamente.
22
SQR tiene un pequeño conjunto de tipos de variables. Los tipos más comunes son las variables numéricas y las variables de cadena. Todas las variables numéricas en SQR están precedidas por un signo de numeral (#) y todas las variables de cadena son precedidos con un signo de dólar ($). Un tipo adicional de variable es la variable de fecha. En SQR, las variables numéricas y de cadena no se declaran explícitamente. En lugar de eso se definen implícitamente por su primer uso. Todas las variables numéricas inician con valor cero, y todas las variables de cadena comienzan como NULL, por lo que normalmente no es necesario inicializarlas. Las variables de cadena son de longitud variable y pueden tener largas cadenas de caracteres, así como cadenas cortas. Cuando un nuevo valor es asignado a una variable de cadena, su longitud se ajusta automáticamente. En el procedimiento list_customers, #state_total y # cust_total se ponen a cero en el inicio del procedimiento. Esta inicialización es opcional y se hace para mayor claridad solamente. La variable #state_total se incrementa en 1 para cada fila seleccionada. Cuando el valor del estado cambia, el programa llama al procedimiento state_tot e imprime el valor de #state_total. Observe el uso de la máscara de edición 999.999, que le da formato al número.
Este procedimiento también emplea el comando LET. LET es el comando de asignación en SQR, y le permite crear expresiones complejas. Aquí, LET se utiliza para agregar el valor de #state_total a #cust_total. Al final del procedimiento, #state_total se pone a cero. El procedimiento de list_customers contiene un ejemplo de la instrucción SQR if-then-else. La condición comienza con IF es seguido por una expresión. Si la expresión se evalúa como verdadero o un número distinto de cero, los comandos posteriores se ejecutan. De lo contrario, hay una parte de ELSE. Los comandos IF siempre terminan con un END-IF. En este caso, se examina el valor de #cust_total. Si es mayor que cero, la consulta ha regresado filas de datos, y el programa imprimirá la cadena "Total Customers:" y el valor de #cust_total. Si #cust_total es igual a cero, la consulta no ha devuelto ningún dato. En ese caso, el programa imprime la cadena "No Customers".
Guiones y subrayados (guiones bajos) Usted puede haber notado que muchos de los comandos SQR, tales como BEGIN-PROGRAM y BEGINSELECT, usan un guión, mientras que los nombres de procedimiento y los nombres de las variables usan un subrayado. Los nombres de procedimiento y los nombres de variable pueden contener un guión o un subrayado, pero le recomendamos que utilice un guión bajo. Usar subrayado en los nombres de procedimientos y los nombres de variable le ayudará a distinguirlos de los comandos SQR. Asimismo, evitará la confusión
23
cuando se mezclan nombres de variables y los números en una expresión, donde los guiones podría confundirse con signo negativo.
Procedimientos de ruptura con BEFORE y AFTER. Al imprimir variables con ON-BREAK, usted puede llamar de forma automática los procedimientos BEFORE y AFTER de cada interrupción en una columna. Los calificadores BEFORE y AFTER le dan esta capacidad. Por ejemplo:
begin-select state (,1) on-break before=state_heading after=state_tot
El calificador BEFORE llama automáticamente al procedimiento state_heading para imprimir los encabezados de de impresión antes de cada grupo de registros de un mismo Estado. Del mismo modo, el calificativo AFTER llama automáticamente al procedimiento de state_tot para imprimir totales después de cada grupo de registros. Todos los procedimientos BEFORE se invocan automáticamente antes de cada ruptura, incluida la primera, en otras palabras, antes de que la instrucción SELECT se haya procesado. Del mismo modo, todos los procedimientos AFTER se invocan después de cada ruptura, incluidos los del último grupo, en otras palabras, una vez finalizada la instrucción SELECT.
Comprensión de la Orden de Eventos Se puede definir una jerarquía de las columnas de ruptura utilizando el calificativo LEVEL en el ONBREAK. En ex5c.sqr, por ejemplo, el estado se define como LEVEL = 1 y la ciudad como LEVEL = 2. Cuando se produce una ruptura en un nivel, se fuerza la ruptura en las columnas con niveles más altos. En el programa de ejemplo, una ruptura en el estado también significa una ruptura en la ciudad. Una ruptura en una variable puede desencadenar otros muchos acontecimientos. El valor puede ser impreso, se pueden saltar líneas, llamar automáticamente los procedimientos o guardar el valor anterior. Es importante saber el orden de los acontecimientos, en particular cuando hay múltiples columnas con el calificador ON-BREAK. La siguiente instrucción SELECT se rompe en tres niveles:
begin-select state (,1) on-break level=1 after=state_tot skiplines=2 city (,7) on-break level=2 after=city_tot skiplines=1 zip (,45) on-break level=3 after=zip_tot from customers order by state, city, zip end-select
24
Las roturas son tratadas como sigue: 1. Cuando rompe zip, se ejecuta el procedimiento zip _tot. 2. Cuando se rompe la ciudad, en primer lugar se ejecuta el procedimiento de zip_tot , entonces el procedimiento city_tot es ejecutado, y una línea se salta (SKIPLINES = 1).
Tanto city como la zip se imprimen en el siguiente registro.
3. Cuando se rompe por el estado, los procedimientos zip_tot, city_tot y state_tot son procesados en ese orden. Una línea se omite después que el procedimiento city_tot es ejecutado y dos líneas se omiten después que el procedimiento state_tot es ejecutado. Las tres columnas: estado, ciudad, y zip se imprimen en el siguiente registro. El siguiente programa (ex5e.sqr) demuestra el orden de los acontecimientos en el procesamiento de rupturas. Tiene tres columnas con ON-BREAK, cada una con un argumento LEVEL y un procedimiento BEFORE y un AFTER. Los procedimientos BEFORE y AFTER imprimen cadenas para indicar el orden del procesamiento.
Program ex5e.sqr begin-setup declare-Layout default end-declare end-setup begin-program do main end-program begin-procedure a print ’AFTER Procedure for state LEVEL 1’ (+1,40) end-procedure begin-procedure b print ’AFTER Procedure city LEVEL 2’ (+1,40) end-procedure begin-procedure c print ’AFTER Procedure zip LEVEL 3’ (+ 1,40) end-procedure begin-procedure aa print ’BEFORE Procedure state LEVEL 1’ (+1,40) end-procedure begin-procedure bb print ’BEFORE Procedure city LEVEL 2’ (+1,40) end-procedure begin-procedure cc print ’BEFORE Procedure zip LEVEL 3’ (+1,40) end-procedure
25
begin-procedure main local begin-select add 1 to #count print ’Retrieved row #’ (+1,40) print #count (,+10)Edit 9999 position (+1) state (3,1) On-Break Level=1 after=a before=aa city (3,10) On-Break Level=2 after=b before=bb zip (3,25) On-Break Level=3 after=c before=cc Edit xxxxx next-listing Need=10 from customers order by state,city,zip end-select end-procedure begin-heading 3 print $current-date (1,1) edit ’DD -MM-YYYY’ page-number (1,60) ’Page ’ last-page () ’ of ’ print ’STATE’ (3,1) print ’CITY’ (3,10) print ’ZIP’ (3,25) print ’Break Processing sequence’ (3,40) end-heading
26
Salida del programa ex5e.sqr
27
28
Los siguientes pasos explican el orden de procesamiento en detalle: Paso 1. Procesar los procedimientos ANTES (BEFORE) Los procedimientos ANTES(BEFORE) se procesan en orden ascendente por LEVEL antes que la primera fila del select sea obtenida. SI no se seleccionan datos, los procedimientos ANTES (BEFORE) no se ejecutan. Paso 2. Procesar la primera fila de datos La primera fila de datos es seleccionada Paso 3. Seleccionar las siguientes filas de datos. El procesamiento del SELECT continúa. Cuando ocurre una ruptura en cualquier columna también se disparan las rupturas en las columnas con el mismo o mayor nivel (LEVEL). Los eventos ocurren en el siguiente orden: 1. Los procedimientos DESPUES (AFTER) se procesan en orden descendente desde el mayor nivel hasta el nivel de la columna con el ON-BREAK actual. 2. Las variables SAVE se inicializan con el valor de la columna anterior al ON-BREAK. 3. Los procedimientos ANTES (BEFORE) se procesan en orden ascendente desde el nivel actual hasta el más alto. 4. Si SKIPLINES se ha especificado, la posición actual de la línea se avanza. 5. El valor del nuevo grupo se imprime (a menos que se haya especificado PRINT=NEVER) Paso 4. Procesar los procedimientos DESPUES (AFTER) Después que el SELECT ha completado, si se seleccionó alguna fila, entonces los procedimientos DESPUES (AFTER) se procesan en orden descendente de nivel (LEVEL).
Controlar los saltos de página en columnas con múltiples columnas ON-BREAK Cuando hay múltiples columnas con ON-BREAK, los saltos de página deben planearse con cuidado. Mientras que puede ser aceptable tener un salto de página dentro de un grupo, probablemente usted no querrá tener uno dentro de un registro. Usted puede prevenir los saltos de página dentro de un registro siguiendo cuatro simples reglas: 1. Coloque las columnas ON-BREAK delante de las otras columnas en su instrucción SELECT 2. Coloque las columnas con menor LEVEL en el ON-BREAK delante de las que tienen mayor LEVEL 3. Use las mismas posiciones de línea para todas las columnas ON-BREAK 4. Evite el uso de WRAP y ON-BREAK juntos en la misma columna.
29
Guardar un valor cuando ocurre una ruptura En el programa ex5d.sqr, el procedimiento state_tot imprime el número total de clientes por estado. Debido a que se llama con el argumento AFTER, este procedimiento se ejecuta solamente después que el valor de la columna con el ON-BREAK ha cambiado. Algunas veces, usted podría desear imprimir en el procedimiento AFTER el valor previo de la columna antes del ON-BREAK. Por ejemplo: usted podría querer imprimir el nombre del estado junto con los totales de cada estado. Simplemente imprimir el valor de state no servirá porque su valor habrá cambiado para el momento en que el procedimiento AFTER sea llamado. La respuesta es guardar el valor previo a la ruptura en una variable de cadena. Para hacer esto use el calificador SAVE de ON-BREAK. Por ejemplo:
begin-select state (,1) on-break after=state_tot save=$old_state Usted puede imprimir el valor de $old_state en el procedimiento state_tot.
Restricciones y limitaciones de ON-BREAK ON-BREAK no puede utilizarse en SQR con variables numéricas. Si requiere ejecutar procesamiento de rupturas con una variable numérica, primero debe mover su valor a una variable de cadena y ponerle la instrucción ON-BREAK a esa variable. Por ejemplo:
begin-select amount_received &amount move &amount to $amount $$9,999.99 print $amount (+1,1) on-break from cash_receipts order by amount_received end-select Por defecto el número máximo de niveles ON-BREAK es 30.
Resumen
PRINT ON-BREAK realiza procesamiento especial cuando un valor cambia.
ON-BREAK SKIPLINES inserta espacios entre grupos de registros.
ON-BREAK LEVEL acomoda las rupturas jerárquicamente
PRINT=CHANGE/TOP-PAGE imprime una columna después del salto de página o después del cambio del valor de una columna
NEXT-LISTING mantiene un grupo de líneas en la misma página
LET es el comando de asignación de SQR.
Los argumentos BEFORE y AFTER establecen procedimientos para las rupturas
Los calificadores SET y LEVEL en conjunto con BEFORE y AFTER determinan el orden de los eventos El calificador SAVE guarda el valor del grupo anterior en una variable
30
Anexos Funciones Relacionadas con archivos delete rename exists Funciones numéricas abs acos asin atan ceil cos cosh deg
e10 exp floor log log10 mod power rad
round sign sin sinh sqrt tan tanh trunc
Funciones misceláneas array getenv ascii instr chr isblank cond isnull dateadd length datediff lower datenow lpad datetostr ltrim edit nvl
range rpad rtrim strtodate substr to_char to_number translate upper
Variables reservadas #current-column $current-date #current-line #end-file #page-count #return-status #sql-count #sql-error #sql-status $sqr-database
{sqr-database} $sqr-locale #sqr-pid $sqr-platform {sqr-platform} $sqr-program $sqr-report $sqr-ver $username
31
Definic.sqr #define TRUE 1 !Valor verdadero #define FALSE 0 !Valor falso !XEROX #define COD_IMP_COND <27><15> !Codigos de impresion condensada !#define COD_IMP_COND <27>&l2A<27>&l1O<27>(19U<27>&l12D<27>(s20H #define COD_IMP_COND =UDK=&<10>&+x<10>=UDK=&<10>&+K6<10> #define COD_IMP_LAND =UDK=&<10>&+x<10>=UDK=&<10>&+K6<10> #define COD_IMP_COMP =UDK=&<10>&+x<10>=UDK=&<10>&+K9<10>&cA4<10> #define COD_IMP_NORM <18> !Codigo de impresion normal #define CHR_HOR 45 !codigo ASCII de la barra horizontal #define CHR_VER 179 !codigo ASCII de la barra vertical #define CHR_TAB 9 !codigo ASCII de TAB #define ANCHO_PAG 210 !Temporal para SUN IAPY30/May/98 #define LARGO_PAG 75 !Temporal para el SUN #define EXTRA_PAG 132 !Ancho de la pagina deafult #define FOR_FECHA YY/MM/DD !Formato de fecha por defecto #define FOR_HORA HH:MM:SS !Formato de fecha por defecto #define FOR_DINO 999,999,999,990.00mi !Formato de dinero con - al final #define FOR_DIN 999,999,999,999.99 !Formato de dinero por defecto #define FOR_DINA B99,999,999,999,999.99 !Formato de dinero,imprime signo (-) #define FOR_DIN_MILESA B99,999,999,999,999 !Form.dinero en miles signo (-) #define FOR_DIN_MILES B99,999,999,999,999PS !Formato de dinero para miles #define FOR_MILES_SUP 999999999999999 !Formato miles archivo ASCII #define FOR_EXT_SUP 999999999999.99 !Formato mon ext archivo ascci #define FOR_EXT_MILES B99,999,999,999PS !Formato extranjer para miles #define FOR_EXT_MILESA B99,999,999,999PS !Formato extranj.para miles signo(-) #define FOR_EXTA B99,999,999,999.99 !Frm.de dinero extr.en cent,signo(-) #define FOR_DINN B999,999,999,999.99MI !Formato de dinero con - al final #define AREA_CONS 255 !Nivel del area consolidada #define OFI_CONS 255 !Nivel de la oficina consolidada #define OFI_SUC 3 !Nivel de oficinas tipo sucursales #define OF_ORIG 1002 !Nivel de oficinas tipo sucursales #define AREA_ORIG 300802 !Nivel de oficinas tipo sucursales #define DOLAR 1 !Moneda Dolar #define UVC 32 !Moneda UVC #define FOR_DIN_COR B999,999.99 !Formato de dinero corto #define FOR_ENTEROS 999,999,999 !Formato de numeros enteros #define FOR_MON 9,999,999.99 !Formato de dinero #define FOR_INT 9,999.99 !Formato de interes #define FOR_MENS 999,999.99 !Formato de mesnualidad #define FOR_FECI 999.99 !Formato de FECI #define FOR_SAL 999,999,999,999,999.99 !Formato cantidad grande #define FOR_CTA XXX-XXXXXX-X !Formato de la cuenta externa #define FOR_CARTA XX-XXX-XXX !Formato de carta de remesas #define FOR_CHQ 00000000000 !Formato de cheque #define FOR_OFI 99999 !Formato de oficial #define FOR_OFIN 99999 !Formato de oficina #define FOR_CED XXXXXXXXX-X !Formato de cedula #define NRO_ENTES 300000 !Numero maximo de entes #define NRO_FUNCIONARIOS 10000 !Numero maximo de funcionarios #define NRO_TELEFONOS 1000000 !Numero maximo de telefonos #define SERVIDOR BOLIVSRV !Nombre del servidor a conectarse #define FOR_TOTAL 99999999 !Formato de numero para totales #define SECUENCIA 999,999 !Formato para secuencia de prestamos #define FOR_COTIZ 99,999.99 ! Formato de valor de Cotizacion #define CUENTA XXXXXXXXXXXXXXXX !Numero de cuenta #define CUENTA1 XXXXXXXXXXXXXXXXXXXX !numero de cuenta 2 #define MONEDA_NACIONAL 0 !Moneda Nacional #define FOR_DINC 9,999,999,999,999.99 !Formato de dinero por defecto #define FOR_EXT 999,999,999,999.99 !Formato de dinero por defecto #define CHR_BLA 32 !Caracter en blanco
32
Log.sqr !************************************************************************! !* Archivo: log.sqr *! !* Base de datos: cob_conta *! !* Producto: Contabilidad *! !* Disenado por: Rodrigo Garces S. *! !* Fecha de escritura: 01/MArzo/1994 *! !************************************************************************! !* IMPORTANTE *! !* Este programa es parte de los paquetes bancarios propiedad de *! !* "MACOSA", representantes exclusivos para el Ecuador de la *! !* "NCR CORPORATION". *! !* Su uso no autorizado queda expresamente prohibido asi como *! !* cualquier alteracion o agregado hecho por alguno de sus *! !* usuarios sin el debido consentimiento por escrito de la *! !* Presidencia Ejecutiva de MACOSA o su representante. *! !************************************************************************! !* PROPOSITO *! !* Este programa posee procedimientos que manejan el log de procesos *! !************************************************************************! !* MODIFICACIONES *! !* FECHA AUTOR RAZON *! !* 01/Mar/1994 Rodrigo Garces S. *! !************************************************************************! #define ANCHO_PAN
70
!Largo de la pantalla del terminal
Begin-Procedure Inicializar_Programa !* Resume las llamadas iniciales de todo programa en uno solo *! create-array name=Parametros_Programa size=20 field=Valor:Char let $modo_debug = '' #debug let $modo_debug = 'S' !Se esta trabajando en modo debug if $modo_debug = 'S' !No genere las llamadas del log !Le permite al usuario ingresar 7 parametros de prueba show '(Ejecucion en modo debug)' input $parametro_debug1 'Parametro Prueba #1 ' if $parametro_debug1 <> '' input $parametro_debug2 'Parametro Prueba #2 ' if $parametro_debug2 <> '' input $parametro_debug3 'Parametro Prueba #3 ' if $parametro_debug3 <> '' input $parametro_debug4 'Parametro Prueba #4 ' if $parametro_debug4 <> '' input $parametro_debug5 'Parametro Prueba #5 ' if $parametro_debug5 <> '' input $parametro_debug6 'Parametro Prueba #6 ' if $parametro_debug6 <> '' input $parametro_debug7 'Parametro Prueba #7 ' if $parametro_debug7 <> '' input $parametro_debug8 'Parametro Prueba #8 ' end-if end-if end-if end-if end-if end-if end-if put $parametro_debug1 into Parametros_Programa (1) put $parametro_debug2 into Parametros_Programa (2)
33
put $parametro_debug3 into Parametros_Programa (3) put $parametro_debug4 into Parametros_Programa (4) put $parametro_debug5 into Parametros_Programa (5) put $parametro_debug6 into Parametros_Programa (6) put $parametro_debug7 into Parametros_Programa (7) put $parametro_debug8 into Parametros_Programa (8) else let #return-status = 1 ! Para el sistema operativo input $w_lote 'Ingrese el codigo de lote input $w_programa 'Ingrese el codigo del programa input $w_secuencial 'Ingrese el secuencial input $w_corrida 'Ingrese la corrida input $w_dependencia 'Dependencia (S/N) input $w_parametros 'Parametros (A/C) input $w_usuario 'Usuario input $w_password 'Password let #w_lote = to_number ($w_lote) let #w_programa = to_number ($w_programa) let #w_secuencial = to_number ($w_secuencial) let #w_corrida = to_number ($w_corrida) do Fecha_Proceso_Hoy do Validar_Dependencia do Inicializar_Corrida do Obtener_Parametros end-if End-Procedure
' ' ' ' ' ' ' '
Begin-Procedure Fecha_Proceso_Hoy Begin-Select getdate () &fecha_inicio_log convert(char(8),getdate(),1) &fecha_hoy End-Select Begin-Select convert(char(10),fc_fecha_cierre,101) &fecha_proceso_batch convert(char(10),fc_fecha_cierre,111) &fecha_proceso_batch2 from cobis..ba_fecha_cierre,cobis..ba_sarta where sa_sarta = #w_lote and sa_producto = fc_producto End-Select let $t1_fecha_proceso = &fecha_proceso_batch let $t11_fecha_proceso = &fecha_proceso_batch2 End-Procedure
Begin-Procedure Validar_Dependencia !* Valida que la dependencia de ejecucion del programa se haya cumplido *! Begin-Select sb_repeticion from cobis..ba_sarta_batch where sb_sarta = #w_lote and sb_secuencial = #w_secuencial End-Select if &sb_repeticion = 'N' do Analizar_Repeticion else if &sb_repeticion = 'U' do Analizar_Una_Repeticion end-if end-if if $w_dependencia = 'S' and #w_secuencial <> 1
34
do Verificar_Tiene_Padre end-if End-Procedure
Begin-Procedure Verificar_Tiene_Padre Begin-Select on-error=Abortar sb_dependencia &existe_dependencia from cobis..ba_sarta_batch where sb_sarta = #w_lote and sb_batch = #w_programa and sb_secuencial = #w_secuencial End-Select let #existe_dependencia = &existe_dependencia Begin-Select on-error=Abortar ba_nombre &nombre_padre from cobis..ba_batch,cobis..ba_sarta_batch where sb_sarta = #w_lote and sb_secuencial = #existe_dependencia and sb_batch = ba_batch End-Select if #existe_dependencia <> 0 do Validar_Estatus_Padre end-if End-Procedure
Begin-Procedure Validar_Estatus_Padre Begin-Select on-error=Abortar lo_estatus &estatus_padre lo_fecha_inicio &fecha_inicio_padre lo_fecha_terminacion &fecha_final_padre from cobis..ba_log,cobis..ba_fecha_cierre,cobis..ba_sarta where lo_sarta = #w_lote and sa_sarta = #w_lote and sa_producto = fc_producto and lo_secuencial = &existe_dependencia and convert(char(10),lo_fecha_proceso,101) = convert(char(10),fc_fecha_cierre,101) End-Select if &estatus_padre = 'E' show 'Este programa depende de: ' &nombre_padre show 'el cual se esta ejecutando desde la fecha ' &fecha_inicio_padre let $mensaje_error = 'El programa del cual se depende aun no ha terminado' do Abortar end-if if &estatus_padre = 'A' show 'Este programa depende de: ' &nombre_padre show 'el cual aborto en la fecha ' &fecha_final_padre let $mensaje_error = 'El programa del cual se depende aborto' do Abortar end-if if &estatus_padre = '' show 'Este programa depende de: ' &nombre_padre show 'el cual aun no se ha ejecutado' let $mensaje_error = 'El programa del cual se depende aun no se ha ejecutado' do Abortar end-if if &estatus_padre = 'F' show 'Este programa depende de: ' &nombre_padre show 'el cual finalizo correctamente en la fecha ' &fecha_final_padre end-if End-Procedure
35
Begin-Procedure Analizar_Repeticion Begin-Select lo_estatus &repeticion_unica from cobis..ba_log,cobis..ba_fecha_cierre,cobis..ba_sarta where lo_sarta = #w_lote and sa_sarta = #w_lote and sa_producto = fc_producto and lo_secuencial = #w_secuencial and lo_corrida <> #w_corrida and convert(char(10),lo_fecha_proceso,101) = convert(char(10),fc_fecha_cierre,101) End-Select if not isnull(&repeticion_unica) show 'Este programa ya ha sido ejecutado ' show 'y solo se puede ejecutar una vez en el dia' let $mensaje_error = 'Se trato de ejecutar el programa de nuevo en el mismo dia' do Abortar end-if End-Procedure
Begin-Procedure Analizar_Una_Repeticion Begin-Select lo_estatus &una_repeticion from cobis..ba_log,cobis..ba_fecha_cierre,cobis..ba_sarta where lo_sarta = #w_lote and sa_sarta = #w_lote and sa_producto = fc_producto and lo_secuencial = #w_secuencial and convert(char(10),lo_fecha_proceso,101) = convert(char(10),fc_fecha_cierre,101) and lo_estatus = 'F' ! (F)inalizo correctamente End-Select if not isnull(&una_repeticion) show 'Este programa ya ha sido ejecutado exitosamente' show 'y solo se puede ejecutar con este resultado una vez en el dia' let $mensaje_error = 'Se trato de ejecutar el programa de nuevo en el mismo dia a pesar de haber terminado bien' do Abortar end-if End-Procedure
Begin-Procedure Validar_Fecha ($fecha,:#flag) !* Valida que el string $fecha sea una fecha de formato MM-DD-YY
*!
let #flag = 0 Begin-Select on-error=Error_Fecha dateadd(dd,1,$fecha) let #flag=1 End-Select let #long_anio = length ($fecha) - 6 let $sep = substr ($fecha,3,1) || substr ($fecha,6,1) if $sep <> '--' and $sep <> '//' let #flag = 0 end-if !JJLAM EL LARGO DEL ANIO DEBE SER $ POR EL ANIO 2000 if #long_anio <> 4 let #flag = 0 end-if End-Procedure
36
Begin-Procedure Error_Fecha ! Es um manejador de error, no ejecuta ninguna accion End-Procedure
Begin-Procedure Inicializar_Corrida let #w_num_reg_proc = 0 let $mensaje_error = 'N' !El mensaje de error seria igual a $sql-error Begin-Select count(*) &existe_prog from cobis..ba_sarta_batch where sb_sarta = #w_lote and sb_batch = #w_programa and sb_secuencial = #w_secuencial End-Select let #existe_prog = &existe_prog if #existe_prog = 0 ! No existe entrada en el lote-programa, el secuencial asignado puede ! ! estar incorrecto ! do Centrar_Show ('Error, es posible que el secuencial este mal asignado',0) stop end-if Begin-Select ba_nombre ba_tipo_batch isnull(ba_frec_reg_proc,100) &ba_frec_reg_proc ba_ente_procesado from cobis..ba_batch where ba_batch = #w_programa End-Select Begin-Select count(*) &nro_est sum(lo_num_reg_proc) &ult_reg_proc from cobis..ba_log where lo_sarta = #w_lote and lo_batch = #w_programa and lo_secuencial = #w_secuencial and lo_estatus = 'F' !Finalizo correctamente End-Select if &nro_est <> 0 let #nro_reg_prom = &ult_reg_proc / &nro_est else let #nro_reg_prom = 0 end-if Begin-SQL on-error=Clave_Duplicada insert into cobis..ba_log (lo_sarta,lo_batch,lo_secuencial,lo_corrida,lo_operador, lo_fecha_inicio,lo_fecha_terminacion,lo_num_reg_proc, lo_estatus,lo_razon,lo_fecha_proceso) select #w_lote,#w_programa,#w_secuencial,#w_corrida,$username, &fecha_inicio_log, NULL,NULL,'E','',fc_fecha_cierre from cobis..ba_sarta,cobis..ba_fecha_cierre where sa_sarta = #w_lote and sa_producto = fc_producto End-SQL End-Procedure
37
Begin-Procedure Clave_Duplicada do Centrar_Show (' Error, es posible que el numero de corrida ya este registrado',0) stop End-Procedure
Begin-Procedure Obtener_Parametros !* Selecciona los parametros de este programa y los confirma de ser *! !* necesario *! let $parametros_cobis = '' let #indice_parametros = 0 Begin-Select pa_nombre pa_tipo pa_valor pa_parametro add 1 to #indice_parametros do Asignar_Parametros get $parametro_actual_cobis from Parametros_Programa (#indice_parametros) let $parametros_cobis = $parametros_cobis || $parametro_actual_cobis || ';' from cobis..ba_parametro where pa_sarta = #w_lote and pa_batch = #w_programa and pa_ejecucion = #w_secuencial order by pa_parametro End-Select !show (17,1) cl !Limpia el area de informacion de corrida !show (18,1) cl !Limpia el area de informacion de corrida !show (19,1) cl !Limpia el area de informacion de corrida !show (20,1) cl !Limpia el area de informacion de corrida ! ACTUALIZACION DEL LOG PARA LOS PARAMETROS RGA 07/10/96 ! Begin-SQL on-error=Abortar update cobis..ba_log set lo_parametro = $parametros_cobis where lo_sarta = #w_lote and lo_batch = #w_programa and lo_secuencial = #w_secuencial and lo_corrida = #w_corrida End-SQL End-Procedure
Begin-Procedure Asignar_Parametros !* Asigna los parametros leidos a las variables o permite *! !* que el usuario ingrese los valores *! let $confirmacion = 'Ingrese valor de ' || &pa_nombre || ' ( = ' || &pa_valor || ') ' evaluate &pa_tipo when = 'I' if $w_parametros = 'C' show $confirmacion input $valor_parametro 'Nuevo Valor' type = integer if $valor_parametro = '' let $valor_parametro = &pa_valor end-if put $valor_parametro into Parametros_Programa(#indice_parametros) else put &pa_valor into Parametros_Programa(#indice_parametros) end-if
38
when = 'D' if $w_parametros = 'C' let #validacion_fecha = 0 while #validacion_fecha = 0 show $confirmacion input $valor_parametro 'Nuevo Valor' type = char if $valor_parametro = '' let $valor_parametro = &pa_valor let #validacion_fecha = 1 else do Validar_Fecha ($valor_parametro,#validacion_fecha) end-if end-while !let $valor_parametro = substr($valor_parametro,1,2) || ! '/' || substr ($valor_parametro,4,2) || ! '/' || substr ($valor_parametro,7,2) put $valor_parametro into Parametros_Programa(#indice_parametros) else !let $valor_parametro = substr(&pa_valor,1,2) || ! '/' || substr (&pa_valor,4,2) || ! '/' || substr (&pa_valor,7,2) put $valor_parametro into Parametros_Programa(#indice_parametros) end-if when = 'C' if $w_parametros = 'C' show $confirmacion input $valor_parametro 'Nuevo Valor' type = char if $valor_parametro = '' let $valor_parametro = &pa_valor end-if put $valor_parametro into Parametros_Programa(#indice_parametros) else put &pa_valor into Parametros_Programa(#indice_parametros) end-if when = 'M' if $w_parametros = 'C' show $confirmacion input $valor_parametro 'Nuevo Valor' type = number if $valor_parametro = '' let $valor_parametro = &pa_valor end-if put $valor_parametro into Parametros_Programa(#indice_parametros) else put &pa_valor into Parametros_Programa(#indice_parametros) end-if end-evaluate End-Procedure
Begin-Procedure Finalizar_Corrida Begin-Select on-error=Abortar getdate() &fecha_final_log End-Select Begin-SQL on-error=Abortar update cobis..ba_log set lo_fecha_terminacion= &fecha_final_log, lo_num_reg_proc = #w_num_reg_proc, lo_estatus = 'F' where lo_sarta = #w_lote and lo_batch = #w_programa and lo_secuencial = #w_secuencial and lo_corrida = #w_corrida End-SQL
39
let #fin_corrida = 1 ! Verdadero do Actualizar_Reg_Proc End-Procedure
Begin-Procedure Abortar show beep show beep show beep show beep show beep if $modo_debug = 'S' !Modo debug no genera llamadas al log if $mensaje_error = 'N' show $sql-error else show $mensaje_error end-if stop end-if if $mensaje_error = 'N' let $mensaje_error = $sql-error end-if Begin-Select getdate() &fecha_final_log2 End-Select let $mensaje_error_show = ' Error : ' || $mensaje_error show $mensaje_error_show Begin-SQL update cobis..ba_log set lo_fecha_terminacion= &fecha_final_log2, lo_num_reg_proc = #w_num_reg_proc, lo_estatus = 'A', lo_razon = $mensaje_error where lo_sarta = #w_lote and lo_batch = #w_programa and lo_secuencial = #w_secuencial and lo_corrida = #w_corrida End-SQL let #return-status = 1 ! Para el sistema operativo stop End-Procedure
Begin-Procedure Actualizar_Reg_Proc let #posicion = 10 let #ba_frec_reg_proc = &ba_frec_reg_proc if $modo_debug <> 'S' and #ba_frec_reg_proc <> 0 if #fin_corrida <> 1 !No se trata del final add 1 to #w_num_reg_proc end-if let #estado_reg_proc = mod (#w_num_reg_proc,&ba_frec_reg_proc) if #estado_reg_proc = 0 or #fin_corrida = 1 ! Verdadero do Ejecutar_Actualizacion !show (17,20) '# ' &ba_ente_procesado ' EN PROCESO : ' if #nro_reg_prom <> 0 let #porcentaje = (#w_num_reg_proc / #nro_reg_prom) * 100 ! show (17,50) #w_num_reg_proc edit 99999 ! if #primer_despliege = 0 ! show (+1,20) '[ ]' ! let #primer_despliege = 1 ! end-if ! let #termometro = trunc(#porcentaje/100*30,0)
40
!if #termometro > 30 !Se sobrepaso el 100% estadistico ! let #termometro = 30 ! end-if ! let #ind_ter = 1 ! while #ind_ter <= #termometro ! let #ind_ter_pos = #ind_ter + 20 ! show (+1,#ind_ter_pos) '=' ! add 1 to #ind_ter ! end-while ! let #posicion = #posicion + 1 else show (17,20) '# ' &ba_ente_procesado ' EN PROCESO : ' #w_num_reg_proc edit 99999 end-if end-if end-if End-Procedure
Begin-Procedure Ejecutar_Actualizacion Begin-SQL on-error=Abortar update cobis..ba_log set lo_num_reg_proc = #w_num_reg_proc where lo_sarta = #w_lote and lo_batch = #w_programa and lo_secuencial = #w_secuencial and lo_corrida = #w_corrida End-SQL End-Procedure
Begin-Procedure ParamN (#indice,:#variable,$tabla,$cond,$mensaje) get $variable from Parametros_Programa (#indice) let #variable = to_number ($variable) if $tabla <> '' let $cond = $cond || $variable do Verificar_Existencia ($tabla,$cond,$mensaje) end-if End-Procedure
Begin-Procedure ParamS (#indice,:$variable,$tabla,$cond,$mensaje) get $variable from Parametros_Programa (#indice) if $tabla <> '' let $cond = $cond || '"' || $variable || '"' do Verificar_Existencia ($tabla,$cond,$mensaje) end-if End-Procedure
Begin-Procedure Verificar_Existencia ($tablas,$condicion,$mensaje) let #flag = 0 Begin-Select count(*) &nro_reg from [cobis..cl_filial : $tablas] where [$condicion] End-Select let #nro_reg = &nro_reg if #nro_reg = 0 let $_mensaje_error = $mensaje do Abortar
41
end-if End-Procedure
Begin-Procedure Comparar_Fechas ($fecha_i,$fecha_f,:#flag) let #flag = 1 let $aux_i = substr ($fecha_i,7,2) || substr ($fecha_i,1,2) || substr ($fecha_i,4,2) let $aux_f = substr ($fecha_f,7,2) || substr ($fecha_f,1,2) || substr ($fecha_f,4,2) if $aux_i > $aux_f let #flag = 0 end-if End-Procedure
Begin-Procedure Centrar_Show ($mensaje,#fila) !* Centra el $mensaje en la terminal *! let #centro = trunc (({ANCHO_PAN}-length($mensaje))/2,0) let #ci = 1 let $espacio = '' while #ci <= #centro let $espacio = $espacio || ' ' add 1 to #ci end-while let $mensaje = $espacio || $mensaje if #fila > 0 show (#fila,1) $mensaje else show (+1,1) $mensaje end-if End-Procedure
Begin-Procedure Finalizar_Programa !* Finaliza la corrida del programa reinicializando la impresora *! !* de tratarse de un reporte *! let #return-status = 0 ! Para el sistema operativo if $modo_debug <> 'S' !Si modo debug, no generar llamdas al log do Finalizar_Corrida end-if if &ba_tipo_batch = 'R' !Se trata de un reporte if #page-count <> 1 or #current-column <> 1 or #w_num_reg_proc <> 0 let $nro_pag = to_char (#page-count) let $msg_show = '(Se generaron ' || $nro_pag || ' paginas)' do Centrar_Show ($msg_show,19) else do Centrar_Show ('(No se genero niguna pagina)',19) end-if end-if show (20,28) '' End-Procedure
Begin-Procedure Nombre_Programa_Fuente (:$nombre) Begin-Select on-error=Abortar ba_arch_fuente &ba_nombre_archivo from cobis..ba_batch
42
where ba_batch = #_w_programa End-Select let $nombre = &ba_nombre_archivo End-Procedure
Begin-Procedure Generar_Listado (#oficina) do Nombre_Programa_Fuente ($archivo_fuente) Begin-Select convert(char(2),datepart(mm,getdate())) &mes_listado convert(char(2),datepart(dd,getdate())) &dia_listado substring(convert(char(4),datepart(yy,getdate())),3,2) &ani_listado convert(char(2),datepart(hh,getdate())) &hor_listado convert(char(2),datepart(mi,getdate())) &min_listado End-Select let #pos = instr($archivo_fuente,'.',1) - 1 let $archivo_fuente = substr($archivo_fuente,1,#pos) move &mes_listado to $mes_listado '00' move &dia_listado to $dia_listado '00' move &hor_listado to $hor_listado '00' move &min_listado to $min_listado '00' let $fecha_definitiva = $mes_listado || $dia_listado || &ani_listado || '_' || $hor_listado || $min_listado let $nombre_listado = '../listados/' || $archivo_fuente || '_' || $fecha_definitiva || '_of' || to_char(#oficina) || '.lis' open 'archivo.lis' as 28 for-append record=132:vary !LVC 19980115 write 28 from $nombre_listado !LVC 19980115 close 28 !LVC 19980115 new-report $nombre_listado Begin-SQL on-error=Abortar update cobis..ba_log set lo_parametro = lo_parametro + '&' + $nombre_listado where lo_sarta = #_w_lote and lo_batch = #_w_programa and lo_secuencial = #_w_secuencial and lo_corrida = #_w_corrida End-SQL End-Procedure
Begin-Procedure Generar_Listado2 (#oficina,#producto) do Nombre_Programa_Fuente ($archivo_fuente) Begin-Select convert(char(2),datepart(mm,getdate())) &mes_listado convert(char(2),datepart(dd,getdate())) &dia_listado substring(convert(char(4),datepart(yy,getdate())),3,2) &ani_listado convert(char(2),datepart(hh,getdate())) &hor_listado convert(char(2),datepart(mi,getdate())) &min_listado End-Select let #pos = instr($archivo_fuente,'.',1) - 1 let $archivo_fuente = substr($archivo_fuente,1,#pos) move &mes_listado to $mes_listado '00' move &dia_listado to $dia_listado '00' move &hor_listado to $hor_listado '00' move &min_listado to $min_listado '00' let $fecha_definitiva = $mes_listado || $dia_listado || &ani_listado || '_' || $hor_listado || $min_listado let $nombre_listado = '../listados/' || $archivo_fuente || '_' || to_char(#producto) || '_' || $fecha_definitiva || '_of' || to_char(#oficina) || '.lis' open 'archivo.lis' as 28 for-append record=132:vary !LVC 19980115 write 28 from $nombre_listado !LVC 19980115 close 28 !LVC 19980115
43