Você está na página 1de 320

UNIVERSIDAD DE OVIEDO ESCUELA POLITCNICA SUPERIOR DE INGENIERA DE GIJN

LENGUAJES Y SISTEMAS INFORMTICOS PROYECTO FIN DE CARRERA N 1082012 NALISIS TEORICO/PRCTICO DE LA TRADUCCIN DE UN LENGUAJE DE CUARTA GENERACIN A JAVA

DOCUMENTO N MEMORIA

NGEL SUREZ GARCA JULIO DE 2008 TUTOR: RAL IZQUIERDO CASTANEDO

NDICE:

PREAMBULO ........................................................................................................... 6 PLANTEAMIENTO 4GL............................................................................................... 8 INTRODUCCION 4GL ................................................................................................ 8 ESTUDIO DEL LENGUAJE INFORMIX-4GL ..................................................................... 9 INTERFACES DE UNA APLICACIN EN INFORMIX PARTES DE UNA APLICACIN TIPOS DE DATOS CARACTERSTICAS BSICAS DEL LENGUAJE EXPRESIONES 4GL PRERREQUISITOS 10 12 17 19 24 24 25 27 53 55 57 70 74 79 83 9

TRADUCTOR DEL LENGUAJE .................................................................................... 24 ALCANCE Y LIMITACIONES ANALIZADOR LEXICO ANALISIS DE LA SINTAXIS GENERACIN DE CDIGO

SEMANTICA, TABLA DE SIMBOLOS, Y MANEJO DE ERRORES

TRATAMIENTO DE SENTENCIAS DE INFORMIX-4GL ..................................................... 57 SENTENCIAS DE DEFINICIN DEL MDULO PRINCIPAL DE PROGRAMA SENTENCIAS DE MANEJO DE FUNCIONES SENTENCIAS DE CONTROL DEL FLUJO SENTENCIA DE DEFINICIN DE MENS

MBITO DE VARIABLES .......................................................................................... 86 PLANTEAMIENTO SQL............................................................................................. 89 ENFOQUE ............................................................................................................. 89 PRERREQUISITOS.................................................................................................. 90 ESTANDARES SQL ................................................................................................. 91 CONVENCIONES DE SINTAXIS ................................................................................ 92 CLASIFICACIN DE LAS SENTENCIAS SQL................................................................. 93 SENTENCIAS SQL DE DEFINICIN DE DATOS SENTENCIAS SQL DE MANIPULACIN DE DATOS 93 93 93 93 93 94 94 94 95

SENTENCIAS DE DECLARACIN Y UTILIZACIN DE VARIABLES

SENTENCIAS SQL DE MANIPULACIN DE CURSORES SENTENCIAS SQL DE OPTIMIZACIN-INFORMACIN SENTENCIAS SQL DE CONTROL DE ACCESO A LOS DATOS

SENTENCIAS SQL QUE GARANTIZAN LA INTEGRIDAD DE LOS DATOS SENTENCIAS SQL DE MANIPULACIN DINMICA DE DATOS SENTENCIA ALTER INDEX SENTENCIA ALTER TABLE SENTENCIA CLOSE SENTENCIA BEGIN WORK SENTENCIA CLOSE DATABASE SENTENCIA COMMIT WORK SENTENCIA CREATE AUDIT

ESTUDIO DE LAS SENTENCIAS SQL ......................................................................... 94

102 104 105 106 106 107 109 110 111 117

SENTENCIA CREATE DATABASE SENTENCIA CREATE INDEX SENTENCIA CREATE TABLE SENTENCIA CREATE VIEW SENTENCIA CREATE SYNONYM

3 SENTENCIA DATABASE 118 119 120 121 122 122 123 124 125 125 126 127 128 128 134 135 136 138 139 140 140 141 141 143 143 147 147 148 148 150

SENTENCIA DECLARE CURSOR SENTENCIA DELETE FROM SENTENCIA DROP AUDIT FOR SENTENCIA DROP DATABASE SENTENCIA DROP INDEX SENTENCIA DROP TABLE SENTENCIA DROP VIEW SENTENCIA EXECUTE SENTENCIA FETCH SETENCIA FLUSH SENTENCIA FREE SENTENCIA DROP SYNONYM

SENTENCIA GRANT

SENTENCIA INSERT INTO SENTENCIA LOAD FROM SENTENCIA OPEN SENTENCIA PUT SENTENCIA LOCK TABLE SENTENCIA PREPAPRE SENTENCIA RENAME COLUMN SENTENCIA RENAME TABLE SENTENCIA REVOKE SENTENCIA SELECT SENTENCIA START UNLOCK TABLE

SENTENCIA ROLLBACK WORK

SENTENCIA UNLOAD SENTENCIA UPDATE

SENTENCIAS DE MANIPULACIN DINMICA DE DATOS Y CURSORES ........................... 150 SENTENCIAS DE CONTROL DE FLUJO...................................................................... 153 ESTUDIO DE TIPOS DE DATOS .............................................................................. 154 TIPOS DATOS BASICOS TIPOS DE DATOS JDBC 154 156 157 161 164 167 169

UPDATE STATISTICS

TIPOS DE DATOS INFORMIX-SQL TIPO DE DATOS SQLSERVER TIPOS DE DATOS DE DB2 TABLA DE MAPEOS TIPOS DE DATOS DE ORACLE

MAPEO DE TIPOS DE DATOS ENTRE JDBC Y JAVA ..................................................... 172 FUNCIONES DE RECUPERACION DE DATOS SQL ....................................................... 174 CONVERSIONES DE TIPOS DE DATOS ..................................................................... 175 EXPRESIONES SQL .............................................................................................. 183 EXPRESIONES DE MANEJO DE COLUMNAS EXPRESIONES DE CONSTANTES FUNCIONES SQL EXPRESIONES AGREGADAS NOMBRES DE VARIABLES 184 188 191 195 196 TRATAMIENTO DE LAS CONVERSIONES NO IMPLICITAS 178

4 NOMBRES DE ELEMENTOS DE LA BASE DE DATOS .................................................... 196 OPERACIONES SOBRE EXPRESIONES SQL ............................................................... 197 TRATAMIENTO POR SQLSERVER TRATAMIENTO PO TRATAMIENTO POR DB2 ORACLE 199 203 206 208 210 211 212 213 213 214 217 217 218 222 222 223 223 224

CONFIGURACIN LOCAL....................................................................................... 209 ELEMENTOS DE INFORMIX ELEMENTOS DE ORACLE ELEMENTOS DE DB2 ELEMENTOS DE JAVA ELEMENTOS DE SQLSERVER

TRADUCCIN DE OPERADORES SOBRE EXPRESIONES

TRATAMIENTO DE LAS FECHAS.............................................................................. 216 RECONOCIMIENTO DE LAS FECHAS MOSTRAR VALORES

CONCLUSIONES Y EJEMPLO DE CONFIGURACIN

CREACIN DE OBJETOS: PROPIETARIO Y ACCESO .................................................... 222 OBJETOS CREADOS EN INFORMIX OBJETOS CREADOS EN DB2 CONCLUSIONES OBJETOS CREADOS EN SQLSERVER OBJETOS CREADOS EN ORACLE

INTERCAMBIO DE DATOS ENTRE JAVA Y EL GESTOR

CONFIGURACIN DE LA CONEXIN........................................................................ 225 PLANIFICACIN Y PRESUPUESTO ........................................................................... 226 MANUAL DE USUARIO .......................................................................................... 229 REQUISITOS HARDWARE REQUISITOS SOFTWARE CONFIGURACIN 229 229 230 233 234 235 237 237 238 239 242 243 245 247 248 249 251 251 252 253 254 255 256

EJECUCIN DEL TRADUCTOR

ANEXO I: FUENTES .............................................................................................. 235 EJEMPLO SENTENCIA ALTER TABLE EJEMPLO SENTENCIAS CONEXIN/DESCONEXIN EJEMPLO SENTENCIA CREACION INDICE

VERIFICACIN DE FUNCIONAMIENTO

EJEMPLO SENTENCIAS DE TRATAMIENTO DE TRANSACCIONES EJEMPLO SENTENCIA CREACION DE SINONIMOS EJEMPLO SENTENCIA CREACION DE TABLA EJEMPLO SENTENCIA CREACION VISTA EJEMPLO SENTENCIA DELETE EJEMPLO SENTENCIA DROP INDEX EJEMPLO SENTENCIA GRANT EJEMPLO SENTENCIAS CREACION TABLA TEMPORAL

EJEMPLO SENTENCIA DROP OBJETO EJEMPLO SENTENCIA INSERT

EJEMPLO SENTENCIA LOAD/UNLOAD EJEMPLO SENTENCIA LOCK/UNLOCK EJEMPLO SENTENCIA RENAME COLUMN EJEMPLO SENTENCIA RENAME TABLA EJEMPLO SENTENCIA PREPARE/EXECUTE PREPARE/DECLARE

5 EJEMPLO SENTENCIA DECLAREFORUPDATE EJEMPLO SENTENCIA TIPOS DE DATOS 258 262 267 269 272 275 280 283 284 288 305

EJEMPLO SENTENCIA FOREACH-FORUPDATE EJEMPLO DE MANEJO DE COLUMNAS Y CONSTANTES PREDEFINIDAS EJEMPLO DE MANEJO DE LITERALES, CONSTANTES Y VARIABLES EJEMPLO FUNCIONES DE MANEJO DE FECHAS EJEMPLO DE FUNCIONES MATEMTICAS EJEMPLO DE FUNCIONES AGREGADAS EJEMPLO DE FUNCION WEEKDAY

EJEMPLO DE MANEJO DE OPERACIONES SOBRE EXPRESIONES EJEMPLO DE MANEJO DE CONSTANTES TIPO FECHA

NDICE DE FIGURAS ............................................................................................ 315 NDICE DE TABLAS .............................................................................................. 316 INDICE DE CUADROS ........................................................................................... 318 REFERENCIAS BIBLIOGRAFICAS............................................................................. 319

PREAMBULO

La idea de este proyecto surgio hace varios aos, sobre el ao 2001, cuando trabajaba en una empresa cuyo principal producto era un ERP el cual estaba desarrollado en Informix-4GL y funcionaba sobre el gestor de bases de datos Informix-SE (Standard Engine). Debido al futuro incierto de Informix Software Inc. y por aadidura de sus productos y a la necesidad de innovacin tcnologica del producto los directivos de la empresa se plantean evolucionar el mismo. Esta evolucin viene marcada por dos premisas fundamentales: Reutilizacin de cdigo. Se Haban desarrollosado miles de ficheros de cdigo fuente que se pretendia reutilizar en la medida de lo posible. Aportar un interfaz grfico como front-end de la aplicacin. Informix permitia el desarrollo de aplicaciones en modo carcter y se puso como objetivo el aportar un interfaz ms amigable basado en un entorno grfico.

Aunque mi carrera profesional se desvinculo de dicha empresa, en el aos 2002, el proyecto en que se haba embarcado sta me parecio muy interesante tanto nivel personal como, incluso, comercial. Antes de mi marcha ya se podian ver los primeros resultados de dicho proyecto y sobre todo en el aspecto visual no alcanzaba los objetivos esperados, bsicamente habra una ventana de MS-DOS y cargaba la aplicacin aportando unicamente relieve, colorido y posibilidad de utilizar ratn, pero manteniendo el aspecto de la aplicacin original y no utilizando las posibilidades grficas que ofrecen las APIs de Windows. Ante esta situacin decido seguir por mi cuenta con el traductor de cdigo fuente Informix-4GL marcandome unos objetivos ms ambiciosos: Reutilizacin de miles/millones de lneas de cdigo fuente. (sin necesidad de modificar para ello el cdigo fuente). Aportar aspecto visual y un interface ms amigable para el usuario, utilizando para ello los recursos que posiblitan los sistemas actuales. Generar un cdigo objeto legible, entendible y fcilmente modificable/ampliable. Generar cdigo objeto multimdulo y multiplataforma. Permitir trabajar con diferentes gestores de bases de datos (otros aparte de Informix-SE).

El estudio, teorico-prctico, que se realiza en este proyecto trata de cuplir estos objetivos y para ello se divide en dos partes diferenciadas: Seccin 1: Estudio del lenguaje de programacin Informix-4GL. En esta primera parte se estudia el lenguaje Informix-4GL, se desarrolla un traductor de Informix-4GL a JAVA donde el anlisis sintctico se encarga de reconocer la sintaxis completa de Informix y se genera cdigo objeto JAVA para el mismo. Seccin 2: Estudio del SQL de Informix. En esta segunda parte se estudia la Sintaxis de las sentencias SQL de Informix, se evala la compatibilidad y posibilidad de ejecucin sobre los gestores de bases de datos estudiados. Este estudio se focaliza en los gestores de bases de datos: Informix, Oracle, SqlServer y DB2. En funcin del anlisis realizado y del gestor de bases de datos para el que se este generando cdigo se transformaran, si es preciso y posible, las sentencias SQL que aparecen en el cdigo fuente de tal forma que tengan el mismo comportamiento sobre el gestor de bases de datos destino que sobre el original.

PROGRAMACIN INFORMIX-4GL

ESTUDIO DEL LENGUAJE DE

PLANTEAMIENTO 4GL

Dentro de esta seccin se estudiar el lenguaje de programacin Informix-4GL, su sintaxis y semntica y en base a ello se construirn todos los componentes del traductor de tal forma que el programa generado permita la traduccin de ficheros fuentes .4GL a ficheros objeto .JAVA funcionalmente correctos. Como paso previo del anlisis se har una breve introduccin al lenguaje de programacin Informix-4GL con objeto de hacerse una idea global del mismo sus caractersticas y componentes as como de denotar la complejidad y amplitud del mismo. Posteriormente ya se entra en profundidad a describir cada uno de los elementos del traductor haciendo hincapi en aquellas temas que merecen especial atencin, destacando principalmente las caractersticas del componente de generacin de cdigo. Una vez explicados los componentes del traductor se pasa a analizar con total detalle la sentencias 4GL estudiadas destacando entre ellas: el tratamiento de los programas multimdulo, el mdulo GLOBALS y la sentencia MENU. Como elemento a destacar dentro del tratamiento de las sentencias 4GL es la posibilidad que se ofrece de aportar un entorno grfico a los programas generados lo cual es una de las mayores aportaciones con respecto a los programas originales.

INTRODUCCION 4GL

La Compaa Informix Software Inc. desarrollo un entorno de programacin con su propio lenguaje de 4 generacin: Informix-4GL el cual esta diseado especialmente para aplicaciones que trabajan con bases de datos y en particular para el gestor de base de datos Informix-SE. Informix-4GL es un lenguaje de 4 generacin que, aparte de las caractersticas tpicas de cualquier otro lenguaje: declaracin de variables y funciones, sentencias de control de flujo del programa, etc., soporta caractersticas especiales para llevar a cabo las siguientes acciones: Consultas y manejos de bases de datos usando SQL. Informix-4GL incluye todas las sentencias SQL, soportadas por Informix, como sentencias nativas del propio lenguaje. Informix-4GL admite embebidas sentencias SQL que son una extensin del Standard Query Language (SQL) desarrollado por IBM y cumple el nivel I del Standard de lenguajes de bases de datos (X3.135-1986). Preparar informes de datos de la base de datos o de otra fuente. Un informe, report, es un bloque de programa especializado que permite mostrar datos de la base de datos. La salida de un informe es normalmente tabular y puede ser diseada para imprimir con cabeceras y pies de pgina, siendo los dispositivos de salida posibles: pantalla, fichero, e impresora. Generacin de formatos de pantalla o formularios, y mens en aplicaciones multiusuario. Los formatos de pantalla se disean de forma independiente al programa.

ESTUDIO DEL LENGUAJE INFORMIX-4GL


INTERFACES DE UNA APLICACIN EN INFORMIX

En este punto se pretende mostrar las caractersticas y componentes del lenguaje Informix-4GL con objeto de hacer ver la amplitud del mismo y de la gran cantidad de elementos a tener en cuenta a la hora de hacer la traduccin del mismo a otro lenguaje.

Ficheros de datos

Inform es

Ventanas 4gl

Usuarios de la base de datos

Base de datos

Figura 1: Interfaces proporcionados por Informix-4GL Una aplicacin multiusuario escrita en Informix-4GL, como se muestra en la figura anterior tiene cuatro interfaces primarios: Acceso a bases de datos a travs del servidor de bases de datos Informix. Los programas escritos en Informix-4GL pueden acceder a bases de datos relacionales con un servidor de bases de datos de Informix apropiado. La base de datos puede estar situada en el mismo equipo que la aplicacin 4GL aunque a menudo la aplicacin se ejecuta desde un sistema cliente separado. Una vez que la conexin de red es correctamente establecida, el acceso a la base de datos es transparente para el usuario. Un mismo programa 4GL puede trabajar con un servidor de bases de datos local o con servidor de bases de datos de red. Comunicacin con el usuario a travs de una Terminal. La iteracin del programa con los usuarios es a travs de reas de pantalla, llamadas ventanas, las cuales tienen un tamao fijo de caracteres por fila y columna. El usuario de una aplicacin puede usar los siguientes entornos: Un emulador de Terminal en su ordenador personal o estacin de trabajo que se conecta al sistema UNIX. Un Terminal carcter conectado al sistema UNIX.

El Interface de usuario de Informix-4GL es programado en modo carcter. Una ventana 4GL puede mostrar un nmero fijo de caracteres horizontal y verticalmente. Cuando se declara una ventana en Informix-4GL se deben de especificar las dos dimensiones. Cada ventana 4GL no puede mostrar ms de un formulario al mismo tiempo. Acceso a ficheros secuenciales del sistema operativo. Las aplicaciones pueden usar ficheros de datos secuenciales, o planos, en las siguientes formas:

10 Con la sentencia UNLOAD que escribe las filas seleccionadas de una tabla de la base de datos en un fichero especificado. Con la sentencia LOAD que lee un fichero y inserta sus lneas como filas en una tabla especifica de la base de datos. Las sentencias START REPORT o REPORT que pueden enviar la salida del formulario a un fichero secuencial o a un comando del sistema operativo. La sentencia PRINT FILE que puede incorporar el contenido de un fichero en la salida de un formulario de Informix-4GL. La sentencia DISPLAY que puede ser usada para escribir en pantalla. Usando comandos del sistema operativo se puede redireccionar la salida a un fichero o a otro programa.

Generacin de informes que pueden ser enviados a diferentes destinos. Los programas escritos en Informix-4GL pueden generar potentes y flexibles informes, cuya salida es una serie de lneas impresas. La salida puede se redireccionada a uno de las siguientes destinos: La pantalla. Una impresora. A un fichero secuencial. A una tubera del sistema operativo hacia otro proceso.

La lgica para generar informes es la misma en todos los casos. El destino puede ser preestablecido al codificar el programa o determinado en tiempo de ejecucin.

PARTES DE UNA APLICACIN


Toda aplicacin realizada en Informix-4GL, como se muestra en la siguiente figura, puede estar compuesta de los siguientes tipos de ficheros: Cdigo fuente de pantallas (.PER). En ellas se especifica el interfaz de usuario de la aplicacin usando para ello ficheros editables (formato texto) en los que se especifica la apariencia visual del formulario y los tipos de datos y atributos de los campos del formulario. Los ficheros de especificacin de formularios son ficheros ASCII. Se puede usar un editor de texto para disear las etiquetas y los campos del formulario. Una vez diseado el formulario, este se compila con lo que se obtiene el fichero objeto del formulario (.FRM), el cual es un fichero binario portable a cualquier plataforma que soporte 4GL. Este fichero objeto es el que carga Informix-4GL durante la ejecucin. Ficheros fuente de mensajes (.MSG). El usuario puede escribir textos de ayuda u otros mensajes de forma independiente al los programas 4GL. As los programas pueden compartir un conjunto de mensajes y se pueden cambiar estos de forma independiente al programa. Este tipo de ficheros de mensajes son muy utilices para hacer los programas multilenguaje sin tener que para ellos definir programas diferentes. Los ficheros de mensajes son compilados obteniendo as un fichero de mensajes objeto (.IEM) el cual esta indexado para obtener as un acceso rpido. Igual que los formularios un fichero objeto de mensajes puede ser usado en diferentes aplicaciones.

11

F ich er os d e m en sa jes

E sp ecifica cion d e for m a tos

C od io fu en te 4 g l

.4 g l

F or m atos com p ila d os

F ich er os d e m esa jes com p ila d os C od igo fu en te com pila d o

Figura 2: Ficheros de los que consta una aplicacin en Informix Fichero fuente de programa (.4GL). Se pueden escribir un programa en uno o ms ficheros fuentes de cdigo fuente 4GL. En estos ficheros se especifica la lgica de programa a travs de sentencias 4GL en los ficheros fuentes del mismo. Debido a que Informix-4GL es un lenguaje de programacin estructurado, las sentencias ejecutables deben aparecer solo dentro de secciones lgicas del cdigo fuente llamadas: bloques de programa. Estas pueden ser la sentencia MAIN, REPORT, o FUNCTION. En un programa pequeo se pueden escribir todas las funciones dentro de un mismo fichero, pero cuando el programa crece, y por razones de organizacin, suele ser habitual definir funciones en ficheros separados. Cada fichero fuente, normalmente, refleja una unidad lgica de programa. La ejecucin de todo programa comienza de forma obligatoria con el bloque de programa llamado MAIN. El mdulo de cdigo fuente que contiene la sentencia MAIN es llamado: el mdulo MAIN. A continuacin se muestra un pequeo, pero completo, programa 4GL: MAIN CALL ejemplo() END MAIN FUNCTION ejemplo() DISPLAY "Hola, mundo" END FUNCTION En la implementacin RDS los ficheros fuentes de 4GL son compilados y generan un pseudo cdigo (.4go) el cual es independiente de la maquina y no es directamente ejecutable por el sistema operativo. Este debe ser interpretado por el intrprete de Informix-4GL. Cuando una aplicacin tiene varios mdulos fuente, primero se compilan estos generando mdulos objeto separados y posteriormente se deben de concatenar estos para generar el fichero (.4gi) que pueda ser interpretado por Informix. La forma de hacer esto es mediante la creacin de un fichero makefile. A continuacin se muestra un ejemplo de makefile: .SUFFIXES: .4go .4gl

12 .4gl.4go: @(echo 'Compilando $*' ; cd `dirname $<` ; fglpc $< ) PACTINV= mbuscom.4go\ mbuscoma.4go\ mcar.4go\ mcript.4go\ mtrapal.4go pactinv.4gi: $(PACTINV) makefile @echo 'Linkando pactinv.4gi' ; cat $(PACTINV) > pactinv.4gi

CARACTERSTICAS BSICAS DEL LENGUAJE


Informix-4GL soporta la programacin estructurada. Este diseo estimula la construccin de los programas como una familia de funciones simples y reutilizables. Adems tiene sintaxis abierta y permite distintos estilos de programacin. Los programas escritos en Informix-4GL son fcilmente refinables e incrementables. En los puntos siguientes se especifican todas las caractersticas de este lenguaje de tal forma que se pueda adquirir una idea concisa del mismo: Sensible al contexto. Informix-4GL no hace distincin entre maysculas y minsculas en las palabras reservadas o identificadores del cdigo fuente. Aunque si lo hace en las cadenas de caracteres introducidas entre comillas. Admite tanto la comilla simple () como la comilla doble () como delimitador de literales. Se pueden intercalar letras maysculas y minsculas en los nombre de identificadores, aunque durante el proceso de compilacin los identificadores son pasados a minsculas. Espacios, delimitadores de marca, smbolos de escape y delimitadores. Al igual que en C y Pascal, el lenguaje Informix-4GL es de formato libre. Los espacios en blanco, tabulaciones, y saltos de lnea son ignorados en la mayora de los contextos, as como los comentarios. Se debe de introducir, al menos, un espacio en blanco entre dos palabras reservadas, identificadores, o literales consecutivos en la misma lnea, a no ser que otro separador se haya introducido. No se pueden meter espacios en blanco dentro de una palabra reservada o identificador. Los espacios en blanco en los literales son considerados, por Informix-4GL, como parte de ste. El usuario puede usar libremente estos espacios en blanco para hacer ms cdigo fuente 4GL. fcil de leer el

No se pueden mezclar doble comilla y simple como delimitador de una misma cadena, por ejemplo la siguiente no es una cadena valida: No es una cadena valida Para incluir el delimitador de literales dentro de una cadena de caracteres se debe de preceder dicho literal con la barra invertida (\) o bien incluir dicho delimitador de cadena dentro de el otro delimitador de cadena. Ejemplos: Escriba \Y\ para continuar Escriba Y para continuar Escriba Y para continuar El compilador de Informix-4GL considera la barra invertida (\) como el carcter de escape por defecto y considera el carcter que le siga inmediatamente como un literal sin darle ningn significado especial. Para especificar que algo incluye como parte de si la barra invertida se debe de introducir la doble barra invertida (\\) en el lugar donde la simple barra se quiere que aparezca. Igualmente se usa \\\\ para representar la doble barra invertida.

13 Salvo en alguna sentencia preparada (PREPARE), en la sentencia PRINT y en la palabra reservada END SQL dentro de bloques SQL , Informix-4GL no requiere delimitador de sentencias aunque opcionalmente se puede utilizar el punto y coma (;) como delimitador. Conjunto de caracteres Validos. Informix-4GL requiere el conjunto de caracteres ASCII, aunque tambin soporta caracteres propios del cliente en fechas, identificadores, especificacin de pantallas y reportes. Sentencias 4GL. Un mdulo fuente de Informix-4GL puede contener sentencias y comentarios: La sentencia es la unidad lgica de cdigo en programas 4GL. Un comentario es una especificacin que Informix-4GL descarta.

No se pueden dividir una sentencia simple de Informix-4GL en varios mdulos. Esta regla es tambin aplicable para sentencias compuestas. Informix-4GL tiene caractersticas que permiten ensamblar grandes programas a partir de mltiples mdulos de cdigo fuente de forma sencilla. Las sentencias de Informix-4GL pueden contener: identificadores, palabras reservadas, literales, constantes, operadores, parntesis y expresiones. Informix distingue entre: sentencias SQL (Structured Query Language) y sentencias 4GL. Comentarios. Un comentario es un texto incluido dentro del los mdulos 4GL para ayudar a los lectores del cdigo fuente, pero dicho texto es ignorado por el compilador de Informix-4GL. Los comentarios se especifican de distintas formas: Un comentario puede empezar por una llave abierta ({) y finalizar con una llave cerrada (}). Este puede tener una o ms lneas. El smbolo de almohadilla (#) indica el principio de un comentario que termina al final de la misma lnea. Tambin se puede usar un par de signos menos (--) para indicar el principio de un comentario que termina al final de la lnea. Este comentario es el especificado por el Standard ANSI para SQL.

Informix-4GL ignora todo el texto incluido entre llaves o desde # o -- hasta el final de la lnea. Cuando se usan comentario se deben de tener en cuenta las siguientes restricciones: Dentro del una cadena de caracteres delimitada con comillas, Informix-4GL interpreta el smbolo de comentario como un literal mas y no como un indicador de comentario. Los comentarios son admitidos dentro de la seccin SCREEN de los ficheros de especificacin de pantallas. El smbolo # no se entiende como inicio de un comentario en un fichero de especificacin de pantallas, en una sentencia SQL o en el texto de una sentencia preparada. No se pueden usar las llaves como comentario dentro de un comentario. No se pueden especificar dos signos menos seguidos como parte de una expresin aritmtica ya que Informix-4GL interpreta que lo que sigue es un comentario. Se debe introducir un espacio en el medio o bien patentizarlos para separar los signos menos consecutivos.

mdulos de cdigo fuente y bloques de programa. Para se crean programas 4GL se deben de introducir sentencias y comentarios dentro de uno o ms ficheros de cdigo fuente llamados mdulos, cuyo nombre no puede exceder de 10 caracteres excluyendo la extensin del fichero.

14 Debido a que Informix-4GL es un lenguaje estructurado, las sentencias ejecutables son organizadas dentro de grandes unidades llamadas bloques de programa. Los mdulos 4GL pueden incluir tres tipos diferentes de bloques: MAIN, FUNCTION, y REPORTS.

Figura 3: Tipos de bloques en un programa Cada bloque comienza con la palabra reservada con la cual luego ser reconocido, y termina con la palabra reservada END correspondiente con cada tipo de bloque (EN MAIN, END FUNCTION, o END REPORT). A continuacin se detallan las reglas aplicables en la construccin de los bloques de programa: Todo programa 4GL debe contener exactamente un bloque MAIN. Este debe de ser el primer bloque de programa en el mdulo en el cual aparezca. A excepcin de ciertas declaraciones: DATABASE, DEFINE y GLOBALS no pueden aparecer sentencias 4GL fuera de un bloque de programa. Las variables que se declaran dentro de bloques de programa su mbito es el propio bloque en el cual se declaran. tas no pueden ser utilizadas desde otro bloque de programa. Las variables que se declaran fuera de un bloque de programa tienen un mbito hasta el final del mdulo en el cual son declaradas. Los bloques de programa no pueden partirse. Nunca pude ningn bloque de programa ser dividido en ms de un mdulo de programa. La sentencia DATABASE tiene efectos en tiempo de compilacin cuando aparece antes del primer bloque de programa del mdulo. Dentro de bloques de programa tiene efectos en tiempo de ejecucin. El mbito de la sentencia WHENEVER se extiende desde la primera vez que aparece hasta su prxima ocurrencia o bien hasta el fin del mdulo en el cual es declarada, pero la sentencia WHENEVER no puede aparecer fuera de un bloque de programa. Las sentencias: CALL, RETURN, EXIT PROGRAM, START REPORT, OUTPUT TO REPORT, FINISH REPORT, y TERMINATE REPORT y cualquier otra expresin 4GL que incluya una funcin predefinida como un operador pueden transferir el control de ejecucin del programa entre distintos bloques del programa.

Bloques de Sentencias. Informix-4GL define sentencias simples y sentencias compuestas: aquellas que pueden contener otras sentencias. Las sentencias: MAIN, FUNCTION, Y REPORT son casos especiales de sentencias compuestas. Las sentencias compuestas se muestran en la siguiente tabla: CASE CONSTRUCT DISPLAY ARRAY FOR FOREACH FUNCION GLOBLAS IF INPUT INPUT ARRAY MAIN MENU PROMPT REPORT SQL WHILE

Tabla 1: Sentencias compuestas de Informix-4GL

15 Todo sentencia compuesta soporta la palabra reservada END para indicar en fin de la misma. La mayora de las sentencias compuestas tambin soportan la palabra reservada: EXIT para transferir el control de ejecucin a la sentencia que sigue a continuacin de la finalizacin de la sentencia compuesta actual. Por definicin toda sentencia compuesta puede contener al menos una sentencia de bloque, un grupo de una o ms sentencias SQL consecutivas o otras sentencias 4GL. Informix-4GL permite que las sentencias de bloque sean vacas. Esta caracterstica permite compilar y ejecutar aplicaciones que no contengan funciones o reports para probar el comportamiento de programas an no completos. A diferencia de los bloques de programas, los cuales no pueden ser anidados, los bloques de sentencias 4GL pueden contener otros bloques de sentencias. La sentencia: GLOBALS puede incorporar indirectamente bloques de sentencias a travs del fichero referenciado. Las sentencias del fichero especificado son incorporadas en el mdulo actual durante la compilacin. Identificadores 4GL. Sentencias y especificaciones de formatos de pantalla pueden hacer referencia a algunas entidades de los programas 4GL por su nombre. Para crear nombres para las entidades de programa se declaran los identificadores. Un identificador es una cadena de caracteres que es declarada como el nombre de una entidad de programa que ha de seguir las siguientes reglas: Debe incluir al menos un carcter y no ms de 50. Solo letras ASCII, dgitos y el carcter de subrayado (_) son admitidos. Blancos, guiones y otros caracteres no alfanumricos no son admitidos. El carcter inicial debe de ser una letra o un subrayado.

Los identificadores 4GL no son sensibles al contexto. Se pueden obtener resultados inesperados si se declara como un identificador ciertas palabras reservadas de SQL, de los lenguajes C y C++ o del sistema operativo o red. Reglas para nombrar los Identificadores SQL. Las reglas para los identificadores SQL son similares a las de los identificadores 4GL, con las siguientes excepciones: La longitud de los identificadores SQL esta limitada a no ms de 18 caracteres. Los identificadores SQL entre comillas si son sensibles al contexto. Se pueden usar palabras reservadas como identificadores SQL, aunque se requieren cualificadores y puede hacer el cdigo difcil de mantener. Identificadores 4GL pueden ser iguales que identificadores SQL, pero esto requiere una especial atencin dentro del mbito de los identificadores 4GL.

mbito de referencia de los identificadores 4GL. Los identificadores 4GL se caracterizan por su mbito de referencia. Un punto del programa donde una entidad puede ser referenciada por su identificador se dice que esta dentro del mbito de referencia del identificador, por el contrario un punto del programa donde el identificador no es reconocido se dice que esta fuera del mbito de su referencia. El mbito de referencia de una variable se determina en funcin de donde aparece la sentencia DEFINE, que declara el identificador, en el mdulo fuente 4GL. Los identificadores de variables pueden ser: locales, de mdulo o, en algunos casos globales a todo el programa. A continuacin se indica el mbito de los mismos: La variables 4GL locales son declaradas dentro de un bloque de programa. Estas variables no pueden ser referenciadas por sentencias fuera del mismo bloque de programa. Las variables de mdulo, tambin llamadas modulares o estticas, pueden ser declaradas fuera de cualquiera bloque de programa: MAIN, REPORT, o FUNCTION. Estos

16 identificadores no pueden ser referenciados fuera del mdulo 4GL en el que se han declarado. Si dentro de la sentencias GLOBALS END GLOBALS se declaran variables en un mdulo, se puede extender el mbito de dichas variables a otro mdulo que incluya la sentencia GLOBALS <nombre de fichero> donde <nombre de fichero> especifica el fichero que contiene la declaracin de la sentencia GLOBALS END GLOBALS.

Hay nombres de constantes: NOTFOUND, TRUE y FALSE, y variables incorporadas como: status, int_flag, quit_flag y el registro SQLCA cuyo mbito es global. Estos identificadores predefinidos no es necesario sean declarados, son visibles en todas las sentencias 4GL y pueden ser referenciados desde cualquier mdulo 4GL. Ocurre lo mismo con las funciones incorporadas y los operadores tales como LENGTH() y INFIELD(). Tambin son de mbito global los nombres de ventanas, formatos de pantalla, reports y funciones. El mbito de los identificadores de los formatos de pantalla incluye todas las sentencias 4GL que son ejecutadas mientras el formato de pantalla esta abierto. La siguiente tabla resume el mbito de referencia de los identificadores 4GL para varios tipos de entidades de los programas 4GL: Entidad de Programa Constantes Argumentos Variable mbito de referencia Global Local a su funcin o report. Mdulo (si es declarada fuera de todo bloque de programa) Local ( si es declarada dentro de un bloque de programa) Campos de screen, arrays o records Identificadores de Pantalla o ventanas Sentencias label Mientras el formato de pantalla permanezca abierto Globales (a partir de que son declarados) Local al bloque de programa en el cual aparece

Tabla 2. mbito de referencia de los identificadores 4GL Dentro de cada mbito, cada identificador 4GL debe de ser nico. Tampoco puede tener el mismo nombre un argumento de funcin o report que el propio identificador de dicha funcin o report. mbito y visibilidad de los identificadores SQL. Por defecto el mbito de un cursor o un objeto preparado es desde su declaracin hasta el final del mdulo o hasta que especficamente es liberado. El resto de los identificadores SQL tienen mbito global. Una vez liberado una sentencia preparada (PREPARE) o declarada (DECLARE) a utilizarse el mismo nombre para referenciar otra. no puede volver

Las sentencias no pueden hacer referencia a elementos de la base de datos tal como: tablas, columnas, o ndices hasta que la base de datos que contiene dicho elemento no sea abierta. Si se asigna a un elemento 4GL el nombre de otro SQL, el primero tiene precedencia dentro de su mbito. Para evitar ambigedades en las sentencias DELETE, INSERT, SELECT, Y UPDATE (y en solo estas), se puede utilizar el prefijo (@) al nombre de una tabla o columna que tenga el mismo nombre que una variable 4GL. En cualquier otro caso el identificador 4GL es visible en cualquier contexto ambiguo. Variables con igual identificador. En tiempo de compilacin se produce un error si se declara el mismo nombre a dos variables que tengan el mismo mbito. Aunque si se puede declarar el mismo nombre si ambas variables tienen distinto mbito.

17 Si una variable local tiene el mismo nombre que una variable global o de tipo mdulo, la variable local tiene precedencia dentro del bloque de programa en el cual es declarada. En cualquier otra parte del programa el identificador har referencia a la variable global o de tipo mdulo. Una variable de tipo mdulo puede tener el mismo nombre que una variable global si esta es declarada en un mdulo diferente. Dentro del mdulo en el cual es declarada, la variable tipo mdulo tiene precedencia sobre la variable global. Las sentencias de dicho mdulo no podrn hacer referencia a la variable global. En resumen: en la porcin de programa donde ms de una variable tiene el mismo identificador, Informix-4GL da precedencia a las variables tipo mdulo sobre las globales, y a las variables locales sobre las de cualquier otro mbito.

TIPOS DE DATOS
En Informix-4GL toda variable ha de ser declarada de un tipo de dato. Un tipo de dato permite definir el tipo de informacin que puede ser almacenada y el tipo de operaciones que se puede hacer con l. El usuario debe declarar el tipo de dato para cada variable, argumento de funciones y reports y los valores de retorno de las funciones. Los argumentos de funciones y reports puedes ser de cualquier tipo 4GL a excepcin de ARRAY. En ocasiones el valor almacenado como un tipo de dato puede ser convertido a otro. La siguiente tabla muestra los tipos de datos soportados por Informix-4GL: Tipo de Dato 4GL ARRAY OF type BYTE CHAR(tamao) CHARACTER DATE DATETIME DECIMAL(p, s) Tipo de valor que almacena Arrays de valores de cualquier otro tipo de dato 4GL simple Un tipo de dato binario cuya longitud es 231 bytes Cadena de caracteres de cmo mximo 32767 bytes de longitud Esta palabra reservada es sinnimo de CHAR Especifica una fecha Especifica una fecha y la hora del da Nmero en formato punto fijo, con una parte entera de longitud (p) y una parte decimal de longitud (s) Nmero en formato punto fijo, con entera de longitud (p) una parte

DECIMAL(p) DEC FLOAT DOUBLE PRECISION INTEGER INT INTERVAL

Esta palabra reservada es sinnimo de DECIMAL Nmero en formato punto fijo de cmo mximo 32 dgitos de longitud Esta palabra reservada es sinnimo de FLOAT Nmero entero cuyo valor puede oscilar entre el rango: -2.147.483.647 a + 2.147.483.647 Esta palabra reservada es sinnimo de INTEGER Extensin de tiempo en aos y meses o una unidad de tiempo mas pequea

18 MONEY NUMERIC REAL RECORD SMALLFLOAT SMALLINT TEXT VARCHAR(tamao) Tabla 3: Tipos de datos 4GL Con la excepcin de ARRAY y RECORD, los tipos de datos 4GL corresponden con los tipos de datos SQL validos en los servidores de bases de datos Informix. Los tipos de datos 4GL son un superconjunto de los tipos de datos SQL, que los servidores de bases de datos Informix admiten, con las siguientes excepciones: El tipo de dato SERIAL de SQL no es un tipo de dato 4GL. Se debe usar el tipo de dato INTEGER para guardar los tipos de datos SERIAL recibidos de la base de datos. No se puede usar la palabra reservada SERIAL en una sentencia 4GL que no sea una sentencia SQL. 4GL no reconoce los tipos de datos NCHAR Y NVARCHAR. Cuando el servidor de bases de datos retorna un tipo de dato NCHAR este es convertido de forma automtica a un valor CHAR, y no se puede updatar un tipo de dato NCHAR con un tipo de CHAR. De forma similar NVARCHAR es convertido en VARCHAR y un tipo de dato VARCHAR no puede updatar un campo de la base de datos de tipo NVARCHAR. 4GL no reconoce los tipos de datos: ITFIXED, BITVARYING, BLOB, BOLEAN, CLOB, DISTINCT, INT8, LIST, LVARCAHR, MULTISET, OPAQUE, REFERENCE, ROW, SERIAL8, SET, o un tipo de datos definido por el usuario en el servidor de bases de datos Informix. TEXT y BYTE son llamados tipos de datos largos. ARRAY y RECORD tipos de datos estructurados o compuestos. Y el resto son llamados tipos de datos simples. Dentro de estos se diferencias: Tipos de datos tipo Carcter: CHAR(longitud), CHARACTER(longitud), y VARCHAR(longitud, mnimo reservado). Tipos de dato tipo Fecha: DATE, DATETIME, INTERVAL. Tipos de dato tipo Nmero: SMALLINT, INTEGER, INT, DECIMAL(precisin, escala), DEC(precisin, escala), NUMERIC(precisin, escala), MONEY(precisin, escala), FLOAT, DOUBLE PRECISION, SMALLFLOAT y REAL. Cantidad de moneda con una escala y precisin Esta palabra reservada es sinnimo de DECIMAL Esta palabra SMALLFLOAT reservada es sinnimo de

Conjunto de valores, de distintos tipos de datos, ordenados Nmero en formato punto fijo, de cmo mximo 16 dgitos de precisin Nmero entero con un rango de 32767 a 32767 Cadena de caracteres de longitud mxima 232 bytes Cadena de caracteres de longitud variable, su tamao a de ser menor de 255 bytes

Los tipos de datos de Informix-4GL se pueden clasificar en varias categoras, que son:

En la declaracin de variables se puede usar la palabra reservada LIKE, lo cual permite declarar variables de forma ms simple ya que el tipo de dato se especifica como una columna de la base de datos.

19

EXPRESIONES 4GL
Una expresin 4GL es una secuencia de operandos, operadores y parntesis que Informix-4GL puede evaluar como un valor simple. Sentencias, funciones, formatos de pantalla, operadores, y expresiones pueden tener expresiones como argumentos, componentes, u operandos. El contexto donde aparece una expresin as como su sintaxis determina el tipo de dato que esta retorna. En base al tipo de dato que las expresiones retornan, stas se clasifican en: Booleanas Integer Number Carcter Time Retorna TRUE o FALSE (o NULL en algunos contextos). Retorna un nmero entero de tipo INT o SMALLINT. Retorna un valor de que puede ser de cualquier tipo de dato tipo Nmero. Retorna un valor tipo: CHAR o VARCHAR. Retorna un valor de tipo: DATE, DATETIME, o INTERVAL.

DIFERENCIAS ENTRE EXPRESIONES 4GL Y EXPRESIONES SQL


Las expresiones incluidas en sentencias SQL son evaluadas por el servidor de bases de datos y no por el interprete de Informix. El conjunto de operadores que pueden aparecen en las expresiones SQL se asemejan mucho al los que se pueden utilizar en 4GL pero no son idnticos. Un programa 4GL puede incluir operadores 4GL, pero hay restricciones en las sentencias SQL. De igual manera muchos operadores SQL no son validos en expresiones 4GL. Los siguientes operandos y operadores SQL no pueden aparecer en una expresin 4GL: Identificadores SQL, tal como nombres de columnas de tablas o de bases de datos. Las palabras reservadas de SQL: USER y ROWID. Funciones agregadas que no tengan su par en las sentencias 4GL. Los operadores BETWEEN e IN. Las palabras reservada de expresiones SQL: EXIST, ALL, ANY, y SOME. El operador aritmtico de exponenciacin (**) y de mdulo (MOD). Los operadores que actan sobre cadenas: ASCII, COLUMN, SPACE, SPACES, y WORDWRAP. Los operadores que actan sobre campos: FIELD_TOUCHED(), GET_FLDBUF(), e INFIELD(). Los operadores de reports: LINENO, y PAGENO. El operador TIME y DATE().

De igual modo tampoco se pueden incluir los siguientes operadores 4GL en expresiones SQL:

COMPONENTES DE LAS EXPRESIONES 4GL


Una expresin 4GL puede incluir los siguientes componentes: Operadores. Parntesis para marcar una precedencia diferente de la que hay por defecto en los operadores. Y operandos.

OPERADORES EN EXPRESIONES 4GL


Los operadores que se muestran en la siguiente tabla son los que pueden aparecen en las expresiones 4GL. Expresiones con varios operadores son evaluadas de acuerdo con su precedencia, de mayor (16) a menor (1) y asociatividad.

20 Operador . [] ( ) UNITS + ** MOD * / + || LIKE MATCHES < <= = == >= > != <> IN() BETWEEN . AND IS NULL NOT AND OR ASCII CLIPPED COLUMN ORD SPACES USING Menor que Menor igual que Igual que Mayor igual que Mayor que Distinto Pertenencia a un conjunto Rango Si es nulo Negacin lgica Interseccin lgica Unin lgica Retorna el carcter ASCII Borra caracteres blancos Indica el inicio de la impresin Retorna el cdigo numrico de un ASCII Inserta espacios en blanco Formatea cadenas de caracteres De derecha De Izquierda De izquierda De izquierda De izquierda De izquierda De derecha 7 6 5 4 3 2 1 De izquierda 8 Descripcin Elementos de un registro ndice de arrays o subcadenas Llamada a funciones Cualificador simple de intervalos Mas unario Menos unario Exponenciacin Mdulo Multiplicacin Divisin Suma Resta Concatenacin Comparacin de Cadenas De izquierda De derecha 10 9 De izquierda 11 De izquierda 12 De izquierda 13 Asociatividad De izquierda De izquierda Ninguna De izquierda De derecha 15 14 Precedencia 16

21 WORDWRAP Muestra texto en varias lneas

Tabla 4: Operadores de las expresiones 4GL Aparte de lo anterior tambin son aplicables con mnima precedencia los siguientes operadores: Operadores sobre campos: FIELD_TOUCHED(), GET_FLDBUF(), y INFIELD(). Operadores sobre reports: SPACE, LINENO y PAGENO. Operadores de tiempo: CURRENT, DATE(), DAY(), EXTEND(), MDY(), MONTH(), TIME, TODAY, WEEKDAY(), y YEAR()

Muchos operadores 4GL no soportan operandos tipo RECORD o ARRAY, pero si aceptan como un operando una variable que sea un elemento de estos.

OPERANDOS EN EXPRESIONES 4GL


Los operandos en expresiones 4GL pueden ser uno de los siguientes: Nombres de variables. Toda expresin 4GL puede contener el nombre de una variable de un tipo de dato simple o de constantes: TRUE, FALSE o NOTFOUND. Las variables tambin pueden ser un elemento simple de un registro o de un array. Hay tres casos especiales en los cuales otros identificadores pueden ser operandos en expresiones 4GL: El atributo opcional COLOR en la especificacin de pantallas, los operadores incorporados FIELD_TOUCHED(), GET_FLDBUF(), y INFIELD(), y los identificadores de tipo BYTE o TEXT como operandos de los operadores booleanos IS NULL e IS NOT NULL. Si una variable es miembro de un registro se ha de cualificar sta con el nombre del registro, como prefijo, separado por un punto (.). Llamadas a funciones que retornen un nico valor. Las expresiones pueden incluir llamadas a funciones que retornen nica y exclusivamente un valor. Las funciones pueden ser: definidas por el usuario o funciones incorporadas a condicin de que retornen un valor simple de un tipo de dato valido. Literales. Cualquier otra expresin 4GL.

Dos expresiones no pueden aparecer consecutivamente sin algn separador, pero si se pueden anidar expresiones dentro de otras expresiones. En algunos contextos, sin embargo, la complejidad de las expresiones 4GL esta restringida.

TIPO DE EXPRESIONES
El tipo de dato de una expresin viene determinado por el tipo de dato que resulta de evaluar los operandos que intervienen en la misma. As estos pueden ser:

EXPRESIONES BOOLEANAS
En 4GL una expresin booleana es aquella que retorna o bien TRUE (definido como 1) o FALSE (definido como 0) o en algunos contextos NULL. La sintaxis de las expresiones booleanas en sentencias 4GL no es idntica a las condiciones booleanas en sentencias SQL. En las expresiones booleanas pueden aparecer los siguientes operadores: Los operadores lgicos: AND, OR y NOT que permiten combinar una o ms expresiones booleanas en una expresin booleana simple. Operadores booleanos que chequean operandos y retornar valores booleanos, como son: Comparaciones de igualdad/desigualdad. El operador IS NULL que examina valores nulos.

22 Los operadores MATCHES o LIKE para comparar cadenas de caracteres. El operador BETWEEN AND que compara valores en un rango. El operador IN() comprueba la pertenencia a un conjunto de elementos.

Cualquier tipo de expresin 4GL puede tambin ser una expresin booleana. Se puede usar una variable INT o SMALLINT para almacenar los valores retornados TRUE, FALSE o NULL. Se pueden obtener resultados inesperados de una comparacin booleana si los operandos son de distinto tipo de dato. Las expresiones booleanas en las sentencias 4GL: CASE, IF, o WHILE retornarn FALSE si uno de los elementos de la comparacin es NULL, exceptuando si son operandos de los operadores IS NULL o IS NOT NULL.

EXPRESIONES ENTERAS
Una expresin entera es aquella que retorna un nmero entero. Las expresiones enteras pueden ser componentes de expresiones de cualquier otro tipo. Seis operadores aritmticos pueden aparecer en una expresin entera, y deben tener expresiones enteras a ambos lados del operador, estos se muestran en la siguiente tabla: Smbolo ** Mod * / + Nombre Exponenciacin Mdulo Multiplicacin Divisin Adicin Sustraccin Nombre del Resultado Precedencia Potencia Resto entero Producto Cociente Suma Diferencia 12 12 11 11 10 10

Tabla 5. Operadores sobre expresiones enteras Todos los clculos aritmticos son realizados despus de convertir ambos operandos a un valor DECIMAL (aunque los operandos del operador MOD son convertidos primero a INTEGER). Se pueden utilizar los operadores unarios: mas (+) y menos (-) a la izquierda una expresin para indicar el signo de la misma. Para los valores que no llevan signo, por defecto, se consideran en positivo (+). Se deben usar parntesis para separar el operador de restar del operador unario menos, si estos van consecutivos como se muestra en el siguiente caso: minuendo - (sustraendo). Informix-4GL interpreta los dos menos consecutivos como un indicador de comentario.

EXPRESIONES DE TIPO NMERO


Una expresin tipo nmero es una especificacin que evala un nmero real. Si un operando de una expresin de tipo nmero es el valor NULL, Informix-4GL evala la expresin completa al valor NULL. El rango de valores en una expresin de tipo nmero la fija el tipo de dato de la variable que recibe el resultado. Los operadores aritmticos y operadores aplicables a expresiones tipo nmero. unarios que se aplican para enteros tambin son

EXPRESIONES TIPO CARCTER


Una expresin de tipo carcter es una especificacin que evala cadenas de caracteres.

23 Si una expresin tipo carcter incluye una variable 4GL o una funcin cuyo valor no es ni de tipo CHAR ni de tipo VARCHAR, 4GL intenta convertir el valor a una cadena de caracteres. La longitud mxima de una cadena de caracteres es la aquella con la cual fue declarada. Los valores mximos son 32767 bytes para valores de tipo CHAR y 255 bytes para valores de tipo VARCHAR. Si expresiones de tipo carcter son los operandos de un operador relacional, 4GL evala ambas expresiones de tipo carcter y luego compara los valores que retornan de acuerdo con su posicin dentro de la secuencia natural. Por defecto Informix-4GL TAB (= CONTROL-I) NEWLINE (= CONTROL-J) FORMFEED (= CONTROL-L) Y desde ASCII 32 (= blanco) hasta 128 (= ~) considera los siguientes caracteres como imprimibles:

Una cadena de caracteres que incluya uno o ms caracteres no imprimibles puede ser un operando o el valor de retorno de una expresin de tipo carcter. sta puede ser almacenada en una variable 4GL o en una columna de la base de datos de tipo: CHAR, VARCAHR y TEXT.

EXPRESIONES DE TIPO TIEMPO


Una expresin tipo tiempo es una especificacin de cmo Informix-4GL puede evaluar un valor de tipo DATE, DATETIME, o INTERVAL. Estos tres tipos de datos estn relacionados lgicamente porque ellos expresan valores en unidades de tiempo pero, a diferencia de los tipos de datos numricos y tipo caracteres para los cuales Informix-4GL soporta conversiones automticas de tipo (con sus posibles restricciones basadas en truncaciones o desbordamientos), las conversiones entre tipos de datos de tiempo son ms limitadas. En un contexto donde una expresin de tipo tiempo es requerida, valores de tipo DATE o DATETIME pueden ser a menudo sustituidos unos por otros. Los valores de tipo INTERVAL, sin embargo, no pueden ser convertidos a valores tipo DATE o DATETIME. Las expresiones de tiempo pueden ser operandos de algunos operadores aritmticos. Si el valor de retorno est dentro del rango de un tipo de dato DATE valido, la expresin retorna un valor tipo DATE. Los operadores aritmticos que pueden operar sobre valores de tipo DATE son sustraccin, y los operadores de relacin. la adicin y la

24

TRADUCTOR DEL LENGUAJE

Una vez definidas las caractersticas bsicas del lenguaje, lo cual nos hace tener una somera idea sobre la complejidad del mismo, se contina con la explicacin de los elementos del traductor. En esta seccin se delimitar los prerrequisitos, alcance y enfoque que se va ha seguir dentro del proceso de traduccin, se explica cada componente del traductor y como se enfocan los problemas planteados al traducir cdigo fuente Informix-4GL a JAVA.

PRERREQUISITOS
Se parte de un cdigo fuente escrito en Informix-4GL versin 4.16 y como especificacin sintctica se considerar esta versin del lenguaje aunque se han incorporado aquellas ampliaciones sintcticas producidas hasta versiones inferiores a la 6.0. El traductor se ha desarrollado en JAVA y como versin mnima para compilar los fuentes del mismo es la versin JAVA 1.3. Se admiten versiones superiores a sta. El programa ha sido probado tambin con las versiones 1.4 y 1.5 de forma satisfactoria. El cdigo objeto generado como resultado de la ejecucin del traductor (.JAVA) necesita como mnimo la versin JAVA 1.3 para su compilacin y ejecucin.

ALCANCE Y LIMITACIONES
El traductor que se ha creado esta diseado para reconocer la sintaxis completa de Informix-4GL e Informix-SQL. Para garantizar que el analizador sintctico es correcto se prob sobre ms de 1500 ficheros de cdigo fuente con resultados satisfactorios. Como l objetivo principal por el cual surge este proyecto es la reutilizacin de cdigo fuente se parte de la premisa de que los ficheros fuentes contienen programas/mdulos sintctica y semnticamente correctos. Esto podra, errneamente como se ver ms adelante, llevar a pensar que los componentes de traductor se podran ver reducidos en la parte correspondiente al analizador semntico, la utilizacin de la tabla de smbolos e incluso el manejo de errores. Como limitaciones ms importantes dentro de la parte 4GL de este traductor estn: no se tratarn todas las sentencias del lenguaje y alguna de ellas con restricciones, y solo se considerarn los tipos de datos simples. Como este proyecto tiene dos partes diferenciadas y muy amplias: 4GL y SQL se ha decido limitar la parte del 4GL a aquellas sentencias bsicas que permitan definir un programa, como contrapartida la parte SQL ser estudiada en toda su profundidad y se aportarn en ella mejoras sustnciales respecto al lenguaje original. La sentencias 4GL que sern tratadas son: Sentencias de definicin de mdulos: MAIN, END MAIN, FUNCTION, END FUNCTION, GLOBALS. Sentencias de control de flujo: WHILE, FOR, FOREACH, CASE, RETURN, CONTINUE, IF, EXIT. Sentencias de definicin de variables: DEFINE, tipos de datos. Sentencias 4GL puntuales: LET, CALL, DATABASE, WHENEVER. Sentencia MENU.

El diseo del traductor sigue la metodologa clsica: anlisis descendente y traduccin en un solo paso, aunque aportando caractersticas modernas como la aplicacin del concepto: patrn estratgica a la hora de definir el generador de cdigo. As y de forma esquemtica el traductor tiene los siguientes componentes:

25

T a b l a d e S m b o l o s

Cdigo fuente Analizador Lxico Analizador Sintctico Analizador Semntico Generacin de Cdigo

M a n e j o d e e r r o r e s

GI

GO

GS

GD

CoI

CoO

CoS

CoD

Cdigo objeto dependiente Figura 4: Componentes del traductor A la hora de traducir cdigo fuente se tendr en cuenta para que gestor de bases de datos se esta generando el cdigo objeto y en funcin de ello se instanciar el mdulo de generacin de cdigo adecuado. En las secciones siguientes se estudian cada una de las partes del traductor.

ANALIZADOR LEXICO
Dentro del analizador lxico hay pocos elementos que destacar. Como todo analizador lxico procesa el cdigo fuente retornando tokens y diferenciando en estos entre los identificadores y las palabras reservadas. Se ha de tener en cuenta que existen tokens que pueden ser al mismo tiempo identificador y palabra reservada. Esto ocurre, principalmente, porque dentro del lenguaje de programacin Informix-4GL estn embebidas las sentencias de Informix-SQL. Durante el anlisis sintctico se aplican reglas semnticas que permiten el uso de dichas palabras reservadas de Informix-SQL como identificadores de Informix-4GL al igual que en el lenguaje original. Algunas de estas palabras reservadas son: error, status, sqlca, sqlerrd, pageno, lineno, etc. Las palabras reservadas de Informix-4GL se muestran en la figura siguiente:

26

absolute accept add after all allowing alter and any arg_val array arr_count arr_curr asc ascii at attribute attributes audit auto average avg before begin between blink blue bold border bottom break by call case char check clear clipped close cluster columns command comment commit composites connect construct continue count create current cyan database date datetime day dba decimal declare default defaults defer define delete delimiter describe dim display displayonly distinct double down downshift drop else end entry errorlog err_get err_print err_quit escape every exclusive execute exists exit exitnow external false fetch field file fins first float flush for foreach format from function globals goto grant green group having headings help hour if immediate include incorrect index infield initialize input insert instructions integer interrupt into invisible is joining key label last left length let level like line lines load lock log long magenta main margin master matches mdy message minute mode modify money month need netauf next nextfield noentry not notfound noupdate null num_args on open option options or order otherwise outer output page pause percent picture pipe prepare previous print printer privileges program prompt public put queryclear quit record recover register relative remove rename report required reslog resource return returning reverse revoke right rollback rollforward row rows run screen scroll scr_line second select serial set set_count share skip sleep smallint some space spaces sqlawarn sqlca sqlcode sqlerrd start startlog statistics status step stop sum synonym table tables then through thru time to today top trailer true type typedef underline union unique unix unload unlock up update upshift user using validate value values verify view wait waiting warning weekday when whenever where while white window with without work wrap year yellow zerofill Figura 5: Palabras reservadas de Informix Cuando se inicializa el traductor se cargan las palabras reservadas de Informix en una tabla HASH de tal forma que durante el reconocimiento de los tokens se consulta en la misma si es una palabra reservada o por el contrario ser: un identificador, una constante, un operador o un delimitador. Los operadores que son reconocidos durante el anlisis lxico se muestran en la siguiente tabla: Operador < <= = == > Descripcin menor que menor igual que igual que mayor que

27 >= <> != || * / + ** mayor igual que Desigualdad Concatenacin Multiplicacin Divisin Resta Suma Exponenciacin

Tabla 6: Operadores reconocidos por el analizador lxico Los comentarios del cdigo fuente son ignorados a la hora de tratar los ficheros. Informix admite comentarios de lnea, estas empieza por: # --, y comentarios de varias lneas, en este caso los bloques comentados estn incluidos entre llaves: {}. Durante el lxico tambin se reconocen las siguientes constantes: Operador entero decimal carcter cadena fecha fecha/hora nmero positivo Descripcin entero negativo o 1, +54, -46 1.0, 1.3e+34, .32E-34, 43e+34 'a' Ejemplos

nmero decimal carcter simple cadena de caracteres fecha corta fecha larga

cadena dd/mm/yyyy yyyy-mm-dd hh:mm:ss.ffff

Tabla 7: Constantes reconocidas por el analizador lxico

ANALISIS DE LA SINTAXIS
A continuacin se detallan las producciones que definen la gramtica de Informix y las cuales se reflejan en el analizador sintctico del traductor creado. <MDULO4GL> ::= <SENTENCIADATABASE> <GLOBALES> <VBLESBGLOBALES> <PROGRAMA> <SENTENCIADATABASE> ::= <VACIO> <SENTENCIADATABASE> ::= database <NOMBREDB> <ATRIBDB> <ATRIBDB> ::= <VACIO> <ATRIBDB> ::= exclusive <NOMBREDB> ::= <VARIABLE> <NOMBREDB> ::= <CTE_CADENA> <GLOBALES> ::= <VACIO> <GLOBALES> ::= <GLOBALS> <GLOBALS> ::= globals <RESTOGLOBALS> <RESTOGLOBALES> ::= <FICHERO> <RESTOGLOBALES> ::= <VBLES> end globals <VBLESGLOBALES> ::= <VACIO> <VBLESGLOBALES> ::= <VBLES> <PROGRAMA> ::= <PRIMSENT>

28 <PRIMSENT> ::= <OTRASENT> <RESTOPROG> <PRIMSENT> ::= <SENTENCIAMAIN> <RESTOPROG> <RESTOPROG> ::= <VACIO> <RESTOPROG> ::= <OTRASENT> <RESTOPROG> <OTRASENT> ::= <SENTENCIAFUNCION> <OTRASENT> ::= <SENTENCIAREPORT> <SENTENCIAMAIN> ::= main <CUERPOMAIN> end main <CUERPOMAIN> ::= <VACIO> <CUERPOMAIN> ::= <SENTENCIADEFINE> <SENTENCIADATABASE> <SENTDELMAIN> <SENTDELMAIN> ::= <MASSENTDELMAIN> <MASSENTDELMAIN> ::= <VACIO> <MASSENTDELMAIN> ::= <UNASENTDELMAIN> <MASSENTDELMAIN> <UNASENTDELMAIN> ::= <SENTENCIA> <SENTENCIAFUCNION> ::= function <IDENTIFICADOR> <ARGUMENTOS> <CUERPOF> end function <CUERPOF> ::= <SENTENCIADEFINE> <SENTSDELAFUNCION> <SENTSDELAFUNCION> ::= VACIO> <SENTSDELAFUNCION> ::= <UNASENTDELAFUNCION> <SENTSDELAFUNCION> <UNASENTDELAFUNCION> ::= <SENTENCIA4GL> <UNASENTDELAFUNCION> ::= <SENTENCIASQL> <SENTENCIAREPORT> ::= report <IDENTIFICADOR> <ARGUMENTOS> <CUERPOR> end report <CUERPOP> ::= <SENTENCIADEFINE> <SECCOUTPUT> <SECCORDER> <SECCFORMAT> <SECCOUTPUT> ::= <VACIO> <SECCOUTPUT> ::= output <UNAOUTPUT> <MASOUTPUT> <MASOUTPUT> ::= <VACIO> <MASOUTPUT> ::= <UNAOUTPUT> <MASOUTPUT> <UNAOUTPUT> ::= report to <DESTREPORT> <UNAOUTPUT> ::= <PAGEDIMENSION> <DESTREPORT> ::= <CTE_CAD> <DESTREPORT> ::= printer <DESTREPORT> ::= screen <DESTREPORT> ::= file <CTE_CAD> <DESTREPORT> ::= pipe <OPCMODE> <STRINGOVBLE> <OPCMODE> ::= <VACIO> <OPCMODE> ::= in <RESTOOPCMODE> mode <RESTOOPCMODE> ::= line <RESTOOPCMODE> ::= form <PAGEDIMENSION> ::= page length <OPCIGUAL> <ENTERO> <PAGEDIMENSION> ::= top of page <OPCIGUAL> <CTE_CAD> <PAGEDIMENSION> ::= left margin <OPCIGUAL> <ENTERO> <PAGEDIMENSION> ::= top margin <OPCIGUAL> <ENTERO> <PAGEDIMENSION> ::= bottom margin <OPCIGUAL> <ENTERO> <PAGEDIMENSION> ::= right margin <OPCIGUAL> <ENTERO> <SECCORDER> ::= <VACIO> <SECCORDER> ::= order <EXTERNAL> by <ARGSORDER> <EXTERNAL> ::= <VACIO> <EXTERNAL> ::= external <ARGSORDER> ::= <IDENTIFICADOR> <MODARGSORDER> <MASARGSORDER> <MODARGSORDER> ::= <VACIO> <MODARGSORDER> ::= asc <MODARGSORDER> ::= desc <MASARGSORDER> ::= <VACIO> <MASARGSORDER> ::= <COMA> <ARGSORDER> <SECCFORMAT> ::= format <CUERPOFORMAT> <CUERPOFORMAT> ::= <EVERYROW> <CUERPOFORMAT> ::= <ELTOSFORMAT> <MASELTOSFORMAT> <EVERYROW> ::= every row <MASELTOSFORMAT>::= <VACIO> <MASELTOSFORMAT>::= <ELTOSFORMAT> <MASELTOSFORMAT> <ELTOSFORMAT> ::= <ELTOFORMAT> <SENTENCIASREPORT> <ELTOFORMAT> ::= <AFGERG>

29 <ELTOFORMAT> ::= <BEFOREG> <ELTOFORMAT> ::= <FIRSTPAGE> <ELTOFORMAT> ::= <PAGEHEADER> <ELTOFORMAT> ::= <ONEVERYROW> <ELTOFORMAT> ::= <PAGETRAILER> <ELTOFORMAT> ::= <ONLASTROW> <AFTERG> ::= after group of <ARGUMENTOREPORT> <BEFOREG> ::= before group of <ARGUMENTOREPORT> <FIRSTPAGE> ::= first page header <PAGETRAILER> .:= page trailer <PAGEHEADER> .:= page header <ONEVERYROW> ::= on every row <SENTENCIADEFINE> ::= <VACIO> <SENTENCIADEFINE> ::= <VBLES> <VBLES> ::= <DEFVBLE> <MASDEFVBLES> <MASDEFVBLES> ::= <VACIO> <MASDEFVBLES> ::= <DEFVBLE> <MASDEFVBLES> <DEFVBLE> ::= define <DEFINICIONVBLES> <DEFINICIONVBLES> ::= <UNAVBLE> <OTRASVBLES> <TIPODATO> <MASVBLES> <MASVBLES> ::= <VACIO> <MASVBLES> ::= <COMA> <DEFINICIONVBLES> <UNAVBLE> ::= <IDENTIFICADOR> <OTRASVBLES>::= <VACIO> <OTRASVBLES>::= <COMA> <UNAVBLE> <OTRASVBLES> <TIPODATO> ::= <TIPODATOLIKE> <TIPODATO> ::= <TIPODATO4GL> <TIPODATOLIKE> ::= like <PROPIETARIO> <IDENTIFICADOR> <PTO> <IDENTIFICADOR> <PROPIETARIO> ::= <VACIO> <PROPIETARIO> ::= <IDENTIFICADOR> <PTO> <TIPODATO4GL> ::= <TIPOBASICO> <TIPODATO4GL> ::= <DARRAY> <TIPODATO4GL> ::= <DRECORD> <TIPODATO4GL> ::= byte <TIPODATO4GL> ::= text <TIPOBASICO> ::= char <RESTO1DIM> <TIPOBASICO> ::= character <RESTO1DIM> <RESTO1DIM> ::= <VACIO> <RESTO1DIM> ::= <PAR1> <NMERO> <PAR2> <TIPOBASICO> ::= int <TIPOBASICO> ::= integer <TIPOBASICO> ::= real <TIPOBASICO> ::= smallfloat <TIPOBASICO> ::= smallint <TIPOBASICO> ::= date <TIPOBASICO> ::= dec <RESTO2DIM> <TIPOBASICO> ::= decimal <RESTO2DIM> <TIPOBASICO> ::= numeric <RESTO2DIM> <RESTO2DIM> ::= <VACIO> <RESTO2DIM> ::= <PAR1> <NMERO> <SCALADEC> <PAR2> <SCALADEC> ::= <VACIO> <SCALADEC> ::= <COMA> <NMERO> <TIPOBASICO> ::= money <RESTO2DIM> <TIPOBASICO> ::= double precision <RESTO1DIM> <TIPOBASICO> ::= float <RESTO1DIM> <TIPOBASICO> ::= varchar <RESTO2DIM> <TIPOBASICO> ::= datetime <DATETIMEQUALIFIER> <TIPOBASICO> ::= interval <INTERVALQUALIFIER> <DRECORD> ::= record <RESTORECORD> <RESTORECORD>::= like <PROPIETARIO> <IDENTIFICADOR> <PTO> <ASTERISCO> <RESTORECORD>::= <DEFCAMPOSRECORD> end record <DEFCAMPOSRECORD> ::= <DEFINICIONVBLES> <DARRAY> ::= array <LEEDIMARRAY> of <NOARRAYTIPODATO> <LEEDIMARRAY> ::= COR1> <NMERO> <MASDIM> <COR2>

30 <MASDIM> ::= <VACIO> <MASDIM> ::= <COMCA> <NMERO> <MASDIM> <NOARRAYTIPODATO> ::= <TIPOBASICO> <NOARRAYTIPODATO> ::= <DRECORD> <NOARRAYTIPODATO> ::= byte <NOARRAYTIPODATO> ::= text <DATETIMEQUALIFIER> ::= datetimequalifier <INTERVALQUALIFIER> ::= intervalqualifier <NMERO> ::= nmero <SCALDEC> ::= nmero <SENTENCIAS> ::= <SENTENCIA> <SENTENCIAS> <sENTENCIAS> ::= <VACIO> <SENTENCIA> ::= <SENTENCIA4GL> <SENTENCIA> ::= <SENTENCIASQL> <------------> <SENTENCIA4GL> ::= <SENTANCIACALL> <SENTENCIACALL> ::= call <IDENTIFICADOR> <PAR1> <ARGSLLAMADAF> <PAR2> <RESTOSENTENCIACALL> <RESTOSENTENCIACALL> ::= <VACIO> <RESTOSENTENCIACALL> ::= returning <VBLESRECIBERDO> <ARGSLLAMADAF> ::= <VACIO> <ARGSLLAMADAF> ::= <EXPR4GL> <MASARGSLLAMADAF> <MASARGSLLAMADAF> ::= <VACIO> <MASARGSLLAMADAF> ::= <COMA> <EXPR4GL> MASARGSLLAMADAF> <SENTENCIA4GL> ::= <SENTENCIACASE> <SENTENCIACASE> ::= case <CRITERIOCASE> <OTHERWISEBLOCK> end case <CRITERIOCASE> ::= <CRITERIOCASEMULTIPLE> <CRITERIOCASE> ::= <CRITERIOCASESIMPLE> <CRITERIOCASESIMPLE> ::= <EXPR4GL> <WHENSIMPLE> <CRITERIOCASESIMPLE> ::= <PAR1> <EXPR4GL> <PAR2> <WHENSIMPLE> <CRITERIOCASEMULTIPLE> ::= when <EXPRBOOL> <SENTDELCASE> <MASWHENMULTIPLE> <MASWHENMULTIPLE> ::= <VACIO> <MASWHENMULTIPLE> ::= when <EXPRBOOL> <SENTDELCASE> <MASWHENMULTIPLE> <WHENSIMPLE> ::= when <EXPR4GL> <SENTDELCASE> <MASWHENSIMPLE> <MASWHENSIMPLE> ::= <VACIO> <MASWHENSIMPLE> ::= when <EXPR4GL> <SENTDELCASE> <MASWHENSIMPLE> <OTHERWISEBLOCK> ::= otherwise SENTDELCASE> <SENTDELCASE> ::= <UNASENTDELCASE> <MASSENTDELCASE> <MASSENTDELCASE> ::= <VACIO> <MASSENTDELCASE> ::= <UNASENTDELCASE> <MASSENTDELCASE> <UNASENTDELCASE> ::= <SENTENCIA> <SENTENCIA4GL> ::= <SENTENCIACLEAR> <SENTENCIACLEAR> ::= clear form <SENTENCIACLEAR> ::= clear window <IDENTIFICADOR> <SENTENCIACLEAR> ::= clear window screen <SENTENCIACLEAR> ::= clear screen <SENTENCIACLEAR> ::= clear <CLAUSULASCAMPO> <SENTENCIA4GL> ::= <SENTENCIACLOSE> <SENTENCIACLOSE> ::= close form <IDENTIFICADOR> <SENTENCIACLOSE> ::= close window <IDENTIFICADOR> <SENTENCIA4GL> ::= <SENTENCIACONSTRUCT> <SENTENCIACONSTRUCT> ::= construct <CONSTRUCTVBLE> <OPCIONALCONSTRUCT> <OPCIONALCONSTRUCT> ::= <ATRIBUTECLAUSE> <HELP> <CONSTRUCTBLOCK> <CONSTRUCTVBLE> ::= <VARIABLE> on <COLUMNLIST> from <CLAUSUSLACAMPO> <CONSTRUCTVBLE> ::= by name <VARIABLE> on <COLUMNLIST> <CONSTRUCTBLOCK> ::= <VACIO> <CONSTRUCTBLOCK> ::= <UNCONSTRUCTBLOCK> <MASCONSTRUCTBLOCK> end construct <MASCONSTRUCTBLOCK> ::= <VACIO>

31 <MASCONSTRUCTBLOCK> ::= <UNCONSTRUCTBLOCK> <MASCONSTRUCTBLOCK> <UNCONSTRUCTBLOCK> ::= before <MASBEFOREAFTERCONSTRUCTBLOCK> <SENTDELCONSTRUCT> <UNCONSTRUCTBLOCK> ::= after <MASBEFOREAFTERCONSTRUCTBLOCK> <SENTDELCONSTRUCT> <UNCONSTRUCTBLOCK> ::= on key <PARAMETROSONKEY> <SENTDELCONSTRUCT> <MASBEFOREAFTERCONSTRUCTBLOCK> ::= construct <MASBEFOREAFTERCONSTRUCTBLOCK> ::= field <CAMPOS> <SENTDELCONSTRUCT> ::= <UNASENTDELCONTRUCT> <MASSENTENCIASDELCONSTRUCT> <MASSENTENCIASDELCONSTRUCT> ::= <VACIO> <MASSENTENCIASDELCONSTRUCT> ::= <UNASENTDELCONTRUCT> <MASSENTENCIASDELCONSTRUCT> <UNASENTDELCONTRUCT> ::= <SENTENCIA> <UNASENTDELCONTRUCT> ::= <SENTNEXTFIELDCONSTRUCT> <SENTNEXTFIELDCONSTRUCT> ::= next field <NEXTFIELDCONSTRUCT> <NEXTFIELDCONSTRUCT> ::= previos <NEXTFIELDCONSTRUCT> ::= next <NEXTFIELDCONSTRUCT> ::= <CLAUSULACAMPO> <SENTENCIA4GL> ::= <SENTENCIACONTINUE> <SENTENCIACONTINUE> ::= continue <PALRESCONTINUE> <SENTENCIA4GL> ::= <SENTENCIACURRENT> <SENTENCIACURRENT> ::= current window is <RESTOSENTENCIACURRENT> <RESTOSENTENCIACURRENT> ::= screen <RESTOSENTENCIACURRENT> ::= <IDENTIFICADOR> <SENTENCIA4GL> ::= <SENTENCIADATABASE> <SENTENCIA4GL> ::= <SENTENCIADEFINE> <SENTENCIA4GL> ::= <SENTENCIADISPLAY> <SENTENCIADISPLAY> ::= display <RESTOSENTENCIADISPLAY> <RESTOSENTENCIADISPLAY> ::= by name <LISTADEVBLES> <ATTRIBUTECLAUSE> <RESTOSENTENCIADISPLAY> ::= <EXPRS> <MASSENTENCIADISPLAY> <MASSENTENCIADISPLAY> ::= at <EXPRINT> <COMA> <EXPRINT> <ATTRIBUTECLAUSE> <MASSENTENCIADISPLAY> ::= to <CLAUSULASCAMPO> <ATTRIBUTECLAUSE> <RESTOSENTENCIADISPLAY> ::= form <IDENTIFICADOR> <ATTRIBUTECLAUSE> <RESTOSENTENCIADISPLAY> ::= array <IDENTIFICADOR> to <IDENTIFICADOR> <PTO> <ASTERISCO> <RESTODISPLAYARRAY> <RESTODISPLAYARRAY> ::= <ATTRIBUTECLAUSE> <LASTDISPLAYARRAY> <LASTDISPLAYARRAY> ::= <VACIO> <LASTDISPLAYARRAY> ::= end display <LASTDISPLAYARRAY> ::= <ONKEYBLOCK> end display <ONKEYBLOCK> ::= on key <PARAMETROSONKEY> <SENTDELONKEY> <SENTDELDISPLAYARRAY> ::= <UNASENTDELDISPLAYARRAY> <MASSENTDELDISPLAYARRAY> <MASSENTDELDISPLAYARRAY> ::= <VACIO> <MASSENTDELDISPLAYARRAY> ::= <UNASENTDELDISPLAYARRAY> <MASSENTDELDISPLAYARRAY> <UNASENTDELDISPLAYARRAY> ::= <SENTENCIA> <SENTENCIA4GL> ::= <SENTENCIAERROR> <SENTENCIAERROR> ::= error <EXPRS> <ATTRIBUTECLAUSE> <SENTENCIA4GL> ::= <SENTENCIAEXIT> <SENTENCIAEXIT> ::= exit <RESTOSENTEXITP> <RESTOSENTEXITP> ::= case <RESTOSENTEXITP> ::= construct <RESTOSENTEXITP> ::= display <RESTOSENTEXITP> ::= for <RESTOSENTEXITP> ::= foreach <RESTOSENTEXITP> ::= input <RESTOSENTEXITP> ::= menu <RESTOSENTEXITP> ::= report <RESTOSENTEXITP> ::= prompt <RESTOSENTEXITP> ::= while

32 <RESTOSENTEXITP> ::= program <RESTOEXITPROGRAM> <RESTOEXITPROGRAM> ::= <VACIO> <RESTOEXITPROGRAM> ::= <PAR1> <EXPRINT> <PAR2> <RESTOEXITPROGRAM> ::= <EXPRINT> <SENTENCIA4GL> ::= <SENTENCIAFINISHREPORT> <SENTENCIAFINISHREPORT> ::= finish report <IDENTIFICADOR> <SENTENCIA4GL> ::= <SENTENCIAFOR> <SENTENCIAFOR> ::= for <VARIABLE> <IGUAL> <EXPRINT> to <EXPRINT> <OPCINCFOR> <SENTDELFOR> end for <OPCINCFOR> ::= <VACIO> <OPCINCFOR> ::= step <EXPRINT> <SENTDELFOR> ::= <UNASENTDELFOR> <MASSENTDELFOR> <MASSENTDELFOR> ::= <VACIO> <MASSENTDELFOR> ::= <UNASENTDELFOR> <MASSENTDELFOR> <UNASENTDELFOR> ::= <SENTENCIA4GL> <UNASENTDELFOR> ::= <SENTENCIASQL> <SENTENCIA4GL> ::= <SENTENCIAFOREACH> <SENTENCIAFOREACH> ::= foreach <IDENTIFICADOR> <OPCINTOFOREACH> <SENTDELFOREACH> end foreach <OPCINTOFOREACH> ::= into <LISTADEVBLES> <OPCINTOFOREACH> ::= <VACIO> <SENTDELFOREACH> ::= <UNASENTDELFOREACH> <MASSENTDELFOREACH> <MASSENTDELFOREACH> ::= <VACIO> <MASSENTDELFOREACH> ::= <SENTDELFOREACH> <UNASENTDELFOREACH> ::= <SENTENCIASQL> <UNASENTDELFOREACH> ::= <SENTENCIA4GL> <SENTENCIA4GL> ::= <SENTENCIAGOTO> <SENTENCIAGOTO> ::= goto <OPCDOSPTOSGOTO> <IDENTIFICADOR> <OPCDOSPTOSGOTO> ::= <VACIO> <OPCDOSPTOSGOTO> ::= <DOSPTOS> <SENTENCIA4GL> ::= <SENTENCIAIF> <SENTENCIAIF> ::= if <EXPRBOOL> then <SENTDELIF> <OPCELSEIF> end if <OPCELSEIF> ::= <VACIO> <OPCELSEIF> ::= else <SENTDELIF> <SENTDELIF> ::= <VACIO> <SENTDELIF> ::= <UNASENTDELIF> <MASSENTDELIF> <MASSENTDELIF> ::= <VACIO> <MASSENTDELIF> ::= <SENTDELIF> <UNASENTDELIF> ::= <SENTENCIA4GL> <UNASENTDELIF> ::= <SENTENCIASQL> <SENTENCIA4GL> ::= <SENTENCIAINITIALIZE> <SENTENCIAINITIALIZE> ::= initialize <LISTADEVBLES> <RESTOINITIALIZE> <RESTOINITIALIZE> ::= to null <RESTOINITIALIZE> ::= like <RESTOLIKEINITIALIZE> <RESTOLIKEINITIALIZE> ::= <UNARESTOLIKEINITIALIZE> <MASRESTOLIKEINITIALIZE> <MASRESTOLIKEINITIALIZE> ::= <VACIO> <MASRESTOLIKEINITIALIZE> ::= <COMA> <UNARESTOLIKEINITIALIZE> <MASRESTOLIKEINITIALIZE> <UNARESTOLIKEINITIALIZE> ::= <PROPIETARIO> <IDENTIFICADOR> <PTO> <ULTUNARESTOLIKEINITIALIZE> <ULTUNARESTOLIKEINITIALIZE> ::= <IDENTIFICADOR> <ULTUNARESTOLIKEINITIALIZE> ::= <ASTERISCO> <SENTENCIA4GL> ::= <SENTENCIAINPUT> <SENTENCIAINPUT> ::= input <INPUTARRAYONO> <INPUTARRAYONO> ::= <BINDINGCLAUSE> <ATTRIBUTECLAUSE> <HELP> <INPUTBLOCK> <BINDINGCLAUSE> ::= by name <LISTDEAVBLES> <OPCWITHOUTDEFAULTS>

33 <BINDINGCLAUSE> ::= <LISTADEVBLES> <OPCWITHOUTDEFAULTS> from <CLAUSULASCAMPO> <OPCWITHOUTDEFAULTS> ::= <VACIO> <OPCWITHOUTDEFAULTS> ::= without defaults <INPUTBLOCK> ::= <VACIO> <INPUTBLOCK> ::= <UNAINPUTBLOCK> <MASINPUTBLOCK> end input <MASINPUTBLOCK> ::= <VACIO> <MASINPUTBLOCK> ::= <UNINPUTBLOCK> <MASINPUTBLOCK> <UNAINPUTBLOCK> ::= <PARTE1INPUTBLOCK> <PARTE2INPUTBLOCK> <PARTE1INPUTBLOCK> ::= before <RESTOPARTE1INPUTBLOCK> <PARTE1INPUTBLOCK> ::= after <RESTOPARTE1INPUTBLOCK> <PARTE1INPUTBLOCK> ::= on key <PARAMETROSONKEY> <RESTOPARTE1INPUTBLOCK> ::= field <CLAUSULASCAMPO> <RESTOPARTE1INPUTBLOCK> ::= input <PARTE2DELINPUTBLOCK> ::= <VACIO> <PARTE2DELINPUTBLOCK> ::= <SENTDELINPUTBLOCK> <SENTDELINPUTBLOCK> ::= <UNASENTDELINPUTBLOCK> <MASSENTDELINPUTBLOCK> <MASSENTDELINPUTBLOCK> ::= <VACIO> <MASSENTDELINPUTBLOCK> ::= <UNASENTDELINPUTBLOCK> <MASSENTDELINPUTBLOCK> <UNASENTDELINPUTBLOCK> ::= <SENTENCIA4GL> <UNASENTDELINPUTBLOCK> ::= <SENTENCIASQL> <UNASENTDELINPUTBLOCK> ::= <SENTNEXTFIELDINPUTBLOCK> <SENTNEXTFIELDINPUTBLOCK> ::= next field <NEXTFIELDINPUTBLOCK> <NEXTFIELDINPUTBLOCK> ::= next <NEXTFIELDINPUTBLOCK> ::= previos <NEXTFIELDINPUTBLOCK> ::= <IDENTIFICADOR> <INPUTARRAYONO> ::= array <BINDINGARRAYCLAUSE> <ATTRIBUTECLAUSE> <HELP> <INPUTARRAYBLOCK> <BINDINGARRAYCLAUSE> ::= <IDENTIFICADOR> <OPCWITHOUTDEFAULTS> from <IDENTIFICADOR> <PTO> <ASTERISCO> <INPUTARRAYBLOCK> ::= <UNAINPUTARRAYBLOCK> <MASINPUTARRAYBLOCK> end input <MASINPUTARRAYBLOCK> ::= <VACIO> <MASINPUTARRAYBLOCK> ::= <UNINPUTARRAYBLOCK> <MASINPUTARRAYBLOCK> <UNAINPUTARRAYBLOCK> ::= <PARTE1INPUTARRAYBLOCK> <PARTE2DELINPUTARRAYBLOCK> <PARTE1INPUTARRAYBLOCK> ::= before <RESTOPARTE1INPUTBLOCK> <PARTE1INPUTARRAYBLOCK> ::= after <RESTOPARTE1INPUTBLOCK> <PARTE1INPUTARRAYBLOCK> ::= on key <PARAMETROSONKEY> <RESTOPARTE1INPUTARRAYBLOCK> ::= field <CLAUSULASCAMPO> <RESTOPARTE1INPUTARRAYBLOCK> ::= input <RESTOPARTE1INPUTARRAYBLOCK> ::= delete <RESTOPARTE1INPUTARRAYBLOCK> ::= insert <RESTOPARTE1INPUTARRAYBLOCK> ::= row <PARTE2DELINPUTARRAYBLOCK> ::= <VACIO> <PARTE2DELINPUTARRAYBLOCK> ::= <SENTDELINPUTARRAYBLOCK> <SENTDELINPUTARRAYBLOCK> ::= <UNASENTDELINPUTARRAYBLOCK> <MASSENTDELINPUTARRAYBLOCK> <MASSENTDELINPUTARRAYBLOCK> ::= <VACIO> <MASSENTDELINPUTARRAYBLOCK> ::= <UNASENTDELINPUTARRAYBLOCK> <MASSENTDELINPUTARRAYBLOCK> <UNASENTDELINPUTARRAYBLOCK> ::= <SENTENCIA4GL> <UNASENTDELINPUTARRAYBLOCK> ::= <SENTENCIASQL> <UNASENTDELINPUTARRAYBLOCK> ::= <SENTNEXTFIELDINPUTBLOCK> <SENTNEXTFIELDINPUTBLOCK> ::= next field <NEXTFIELDINPUTBLOCK> <NEXTFIELDINPUTARRAYBLOCK> ::= next <NEXTFIELDINPUTARRAYBLOCK> ::= previos <NEXTFIELDINPUTARRAYBLOCK> ::= <CLAUSULACAMPO> <sENTENCIA4GL> ::= <SENTENCIALABEL> <SENTENCIALABEL> ::= label <IDENTIFICADOR> <DOSPTOS> <sENTENCIA4GL> ::= <SENTENCIALET> <SENTENCIALET> ::= let <RESTOSENTENCIALET> <RESTOSENTENCIALET> ::= <IDENTIFICADOR> <PTO> <ASTERISCO> <IGUAL> <IDENTIFICADOR> <PTO> <ASTERISCO>

34 <RESTOSENTENCIALET> ::= <VBLERECIBERDO> <IGUAL> <RESTOSENTLET> <RESTOSENTLET> ::= null <RESTOSENTLET> ::= <EXPRS4GL> <sENTENCIA4GL> ::= <SENTENCIALOCATE> <SENTENCIALOCATE> ::= locate <LISTADEVBLES> in <RESTOLOCATE> <RESTOLOCATE> ::= memory <RESTOLOCATE> ::= file <RESTOFILELOCATE> <RESTOFILELOCATE> ::= <VACIO> <RESTOFILELOCATE> ::= <CTE_CAD> <RESTOFILELOCATE> ::= <VARIABLE> <sENTENCIA4GL> ::= <SENTENCIAMENU> <SENTENCIAMENU> ::= menu <STRINGOVBLE> <MENUCONTROLBLOCK> end menu <MENUCONTROLBLOCK> ::= <UNMENUCONTROLBLOCK> <MASMENUCONTROLBLOCK> <MASMENUCONTROLBLOCK> ::= <VACIO> <MASMENUCONTROLBLOCK> ::= <UNMENUCONTROLBLOCK> <MASMENUCONTROLBLOCK> <UNMENUCONTROLBLOCK> ::= <PARTE1MENUCONTROLBLOCK> <SENTDELMENU> <PARTE1MENUCONTROLBLOCK> ::= before menu <PARTE1MENUCONTROLBLOCK> ::= command <COMMANDBLOCK> <COMMANDBLOCK> ::= <OPCKEYMENU> <MASOPCKEYMENU> <COMMANDBLOCK> ::= <MASCOMMANDBLOCK> <MASOPCKEYMENU> ::= <VACIO> <MASOPCKEYMENU> ::= <MASCOMMANDBLOCK> <MASCOMMANDBLOCK> ::= <STRINGOVBLE> <OPCSTRINGOVBLE> <HELP> <OPCKEYMENU> ::= key <PARAMETROSONKEYMENU> <SENTDELMENUCONTROLBLOCK> ::= <UNASENTDELMENUCONTROLBLOCK> <MASSENTDELMENUCONTROLBLOCK> <MASSENTDELMENUCONTROLBLOCK> ::= <VACIO> <MASSENTDELMENUCONTROLBLOCK> ::= <SENTDELMENU> <UNASENTDELMENUCONTROLBLOCK> ::= next option <STRINGOVBL> <UNASENTDELMENUCONTROLBLOCK> ::= show <RESTOSHOWHIDEMENU> <UNASENTDELMENUCONTROLBLOCK> ::= hide <RESTOSHOWHIDEMENU> <UNASENTDELMENUCONTROLBLOCK> ::= <SENTENCIA4GL> <UNASENTDELMENUCONTROLBLOCK> ::= <SENTENCIASQL> <RESTOSHOWHIDEMENU> ::= option <MASRESTOSHOWHIDEMENU> <MASRESTOSHOWHIDEMENU> ::= all <MASRESTOSHOWHIDEMENU> ::= <STRINGSOVBLES> <sENTENCIA4GL> ::= <SENTENCIAMESSAGE> <SENTENCIAMESSAGE> ::= message <STRINGSOVBLES> <ATRIBUTECLAUSE> <sENTENCIA4GL> ::= <SENTENCIANEED> <SENTENCIANEED> ::= need <EXPRINT> lines <sENTENCIA4GL> ::= <SENTENCIAOPEN> <SENTENCIAOPEN> ::= open <RESTOSENTOPEN> <RESTOSENTOPEN> ::= form <IDENTIFICADOR> from <STRINGOVBLE> <RESTOSENTOPEN> ::= window at <EXPRINT> <COMA> <EXPRINT> with <RESTOOPENWINDOW> <OPENWINDOWATTRIBUTECLAUSE> <RESTOOPENWINDOW> ::= form <STRINGOVBLE> <RESTOOPENWINDOW> ::= <EXPRINT> rows <COMA> <EXPRINT> columns <sENTENCIA4GL> ::= <SENTENCIAOPTIONS> <SENTENCIAOPTIONS> ::= options <RESTOSENTOPTIONS> <RESTOSENTOPTIONS> ::= <UNASENTOPTIONS> <MASSENTOPTIONS> <MASSENTOPTIONS> ::= <VACIO> <MASSENTOPTIONS> ::= <COMA> <UNASENTOPTIONS> <MASSENTOPTIONS> <UNASENTOPTIONS> ::= comment <RESTO1UNASENTOPTIONS> <UNASENTOPTIONS> ::= error <RESTO1UNASENTOPTIONS> <UNASENTOPTIONS> ::= form <RESTO1UNASENTOPTIONS> <UNASENTOPTIONS> ::= menu <RESTO1UNASENTOPTIONS> <UNASENTOPTIONS> ::= message <RESTO1UNASENTOPTIONS> <UNASENTOPTIONS> ::= prompt <RESTO1UNASENTOPTIONS>

35 <RESTO1UNASENTOPTIONS> ::= line <RESERVEDLINEPOSITION> <UNASENTOPTIONS> ::= accept <RESTO2UNASENTOPTIONS> <UNASENTOPTIONS> ::= delete <RESTO2UNASENTOPTIONS> <UNASENTOPTIONS> ::= insert <RESTO2UNASENTOPTIONS> <UNASENTOPTIONS> ::= next <RESTO2UNASENTOPTIONS> <UNASENTOPTIONS> ::= previous <RESTO2UNASENTOPTIONS> <RESTO2UNASENTOPTIONS> ::= key <KEYPARAM> <UNASENTOPTIONS> ::= help <RESTO3UNASENTOPTIONS> <RESTO3UNASENTOPTIONS> ::= <RESTO2UNASENTOPTIONS> <RESTO3UNASENTOPTIONS> ::= file <CTE_CAD> <UNASENTOPTIONS> ::= display attribute <OPTIONSATRIBUTECLAUSE> <UNASENTOPTIONS> ::= input <RESTO4UNASENTOPTIONS> <RESTO4UNASENTOPTIONS> ::= wrap <RESTO4UNASENTOPTIONS> ::= no wrap <RESTO4UNASENTOPTIONS> ::= attribute <ATRIBUTECLAUSEOPTIONS> <UNASENTOPTIONS> ::= file order <RESTO5UNASENTOPTIONS> <RESTO5UNASENTOPTIONS> ::= unconstrained <RESTO5UNASENTOPTIONS> ::= constrained <UNASENTOPTIONS> ::= sql interrupt <RESTO6UNASENTOPTIONS> <RESTO6UNASENTOPTIONS> ::= on <RESTO6UNASENTOPTIONS> ::= off <sENTENCIA4GL> ::= <SENTENCIAOUTPUTTOREPORT> <SENTENCIAOUTPUTTOREPORT> ::= output to report <IDENTIFICADOR> <PAR1> <ARGSOUTPUTTOREPROT> <PAR2> <ARGSOUTPUTTOREPORT> ::= <VACIO> <ARGSOUTPUTTOREPORT> ::= <EXPR4GL> <MASARGSOUTPUTTOREPORT> <MASARGSOUTPUTTOREPORT> ::= <VACIO> <MASARGSOUTPUTTOREPORT> ::= <COMA> <EXPR4GL> <MASARGSOUTPUTTOREPORT> <SENTENCIAPRINT> ::= print <RESTOPRINT> <RESTOPRINT> ::= <VACIO> <RESTOPRINT> ::= file <CTE_CAD> <RESTOPRINT> ::= <OTROSELTOSRESTOPRINT> <FINRESTOPRINT> <FINRESTOPRINT> ::= <VACIO> <FINRESTOPRINT> ::= <PTOYCOMA> <OTROSELTOSRESTOPRINT> ::= <ELTORESTOPRINT> <MASOTROSELTOSRESTOPRINT> <MASOTROSELTOSRETOPRINT> ::= <VACIO> <MASOTROSELTOSRETOPRINT> ::= <COMA> <ELTORESTOPRINT> <MASOTROSELTOSRESTOPRINT> <ELTORESTOPRINT> ::= byte <VARIABLE> <ELTORESTOPRINT> ::= text <VARIABLE> <OPCWORDWRAP> <ELTORESTOPRINT> ::= <EXPR> <RESTOOPCWORDWRAP> <OPCWORDWRAP> ::= <VACIO> <OPCWORDWRAP> ::= wordwrap <RESTOOPCWORDWRAP> <RESTOOPCWORDWRAP> ::= right margin <EXPRINT> <RESTOOPCWORDWRAP> ::= <VACIO> <OPCWORDWRAP> ::= <VACIO> <OPCWORDWRAP> ::= wordwrap <RESTOOPCWORDWRAP> <RESTOOPCWORDWRAP> ::= right margin <EXPRINT> <RESTOOPCWORDWRAP> ::= <VACIO> <sENTENCIA4GL> ::= <SENTENCIAPROMPT> <SENTENCIAPROMPT> ::= prompt <STRINGSOVBLES> <ATTRIBUTECLAUSE> for <OPCCHAR> <VBLERECIBERDO> <HELP> <ATTRIBUTECLAUSE> <RESTOSENTPROMPT> <RESTSENTPROMPT> ::= <VACIO> <RESTSENTPROMPT> ::= <ONKEYPROMPT> end prompt <ONKEYPROMPT> ::= <UNAONKEYPROMPT> <MASONKEYPROMPT> <MASONKEYPROMPT> ::= <VACIO> <MASONKEYPROMPT> ::= <UNAONKEYPROMPT> <MASONKEYPROMPT> <UNAONKEYPROMPT> ::= on key <PARAMETROSONKEY> <SENTDELPROMPT> <SENTDELPROMPT> ::= <UNASENTDELPROMPT> <MASSENTDELPROMPT> <MASSENTDELPROMPT> ::= <VACIO> <MASSENTDELPROMPT> ::= <SENTDELPROMPT> <UNASENTDELPROMPT> ::= <SENTENCIA>

36 <SENTENCIA4GL> ::= <SENTENCIARETURN> <SENTENCIARETURN> ::= return <EXPRS4GL> <sENTENCIA4GL> ::= <SENTENCIARUN> <SENTENCIARUN> ::= run <STRINGOVBLE> <RESTOSENTRUN> <RESTOSENTRUN> ::= returning <VBLERECIBERDO> <RESTOSENTRUN> ::= without waiting <sENTENCIA4GL> ::= <SENTENCIASCROLL> <SENTENCIASCROLL> ::= scroll <CLAUSUSLACAMPO> <UPODOWNSCROLL> <OPCBYSCROLL> <UPODOWNSCROLL> ::= up <UPODOWNSCROLL> ::= down <OPCBYSCROLL> ::= <VACIO> <OPCBYSCROLL> ::= by <INTEGEROVBLE> <sENTENCIA4GL> ::= <SENTENCIASLEEP> <SENTENCIASLEEP> ::= sleep <EXPRINT> <sENTENCIA4GL> ::= <SENTENCIASTARTREPORT> <SENTENCIASTARTREPORT> ::= start report <IDENTIFICADOR> <RESTOSTARTREPROT> <RESTOSTARTREPORT> ::= <OPCTOCLAUSE> <OPCWITHDIMENSIONS> <OPCTOCLAUSE> ::= <VACIO> <OPCTOCLAUSE> ::= to <DESTINOSREPORT> <DESTINOSREPORT> ::= <DESTINOREPORT> <DESTINOSREPORT> ::= output <MASDESTINOREPOT> <MASDESTINOREPOT> ::= <STRINGOVBLE> <OPCRESTODESTINOREPORT> <OPCRESTODESTINOREPORT> ::= <VACIO> <OPCRESTODESTINOREPORT> ::= destination <STRINGOVBLE> <PAGEDIMENSIONS> ::= <PAGEDIMENSION> <MASPAGEDIMENSIONS> <MASPAGEDIMENSIONS> ::= <VACIO> <MASPAGEDIMENSIONS> ::= <COMA> <PAGEDIMENSION> <MASPAGEDIMENSIONS> <sENTENCIA4GL> ::= <SENTENCIASQLEXEC> <SENTENCIASQLEXEC> ::= sql <SENTENCIASSQL> <OPCPTOYCOMA> end sql <OPCPTOYCOMA> ::= <VACIO> <OPCPTOYCOMA> ::= <PTOYCOMA> <sENTENCIA4GL> ::= <SENTENCIATERMINATE> <SENTENCIATERMINATE> ::= terminate report <IDENTIFICADOR> <SENTENCIA4GL> ::= <SENTENCIAUNLOAD> <SENTENCIAUNLOAD> ::= unload to <STRINGOVBLE> <OPCDELIMITER> <RESTOSENTUNLOAD> <RESTOSENTUNLOAD> ::= <SENTENCIASELECT> <RESTOSENTUNLOAD> ::= <VARIABLE> <sENTENCIA4GL> ::= <SENTENCIAVALIDATE> <SENTENCIAVALIDATE> ::= validate <LISTADEVBLES> like <RESTOVALIDATE> <RESTOVALIDATE> ::= <UNARESTOVALIDATE> <MASRESTOVALIDATE> <MASRESTOVALIDATE> ::= <VACIO> <MASRESTOVALIDATE> ::= <COMA> <UNARESTOVALIDATE> <MASRESTOVALIDATE> <UNARESTOVALIDATE> ::= <PROPIETARIO> <IDENTIFICADOR> <PTO> <RESTOUNAVALIDATE> <RESTOUNAVALIDATE> ::= <ASTERISCO> <RESTOUNAVALIDATE> ::= <IDENTIFICADOR> <sENTENCIA4GL> ::= <SENTENCIAWHENEVER> <SENTENCIAWHENEVER> ::= whenever <PARTE1WHENEVER> <PARTE2WHENEVER> <PARTE1WHENEVER> ::= not found <PARTE1WHENEVER> ::= <PARTE1ERRORWHENEVER><PARTE2ERRORWHENEVER> <PARTE1WHENEVER> ::= warning <PARTE1WHENEVER> ::= sqlwarning <PARTE1ERRORWHENEVER> ::= <VACIO> <PARTE1ERRORWHENEVER> ::= any <PARTE2ERRORWHENEVER> ::= sqlerror

37 <PARTE2ERRORWHENEVER> ::= error <PARTE2WHENEVER> ::= continue <PARTE2WHENEVER> ::= stop <PARTE2WHENEVER> ::= call <IDENTIFICADOR> <PARTE2WHENEVER> ::= <PARTE1GOTOWHENEVER> <PARTE2GOTOWHENEVER> <PARTE1GOTOWHENEVER> ::= go to <PARTE1GOTOWHENEVER> ::= goto <PARTE2GOTOWHENEVER> ::= <DOSPTOS> <IDENTIFICADOR> <PARTE2GOTOWHENEVER> ::= <IDENTIFICADOR> <sENTENCIA4GL> ::= <SENTENCIAWHILE> <SENTENCIAWHILE> ::= while <EXPRBOOL> <SENTDELWHILE> end while <SENTDELWHILE> ::= <UNASENTDELWHILE> <MASSENTDELWHILE> <MASSENTDELWHILE> ::= <VACIO> <MASSENTDELWHILE> ::= <SENTDELWHILE> <UNASENTDELWHILE> ::= <SENTENCIA> <-----------> <INTEGEROVBLE> ::= <NMERO> <INTEGEROVBLE> ::= <VARIABLE> <STRINGSOVBLES> ::= <STRINGOVBLE> <MASSTRINGSOVBLES> <MASSTRINGSOVBLES> ::= <VACIO> <MASSTRINGSOVBLES> ::= <COMA> <STRINGSOVBLES> <OPCSTRINGOVBLE> ::= <VAIO> <OPCSTRINGOVBLE> ::= <STRINGOVBLE> <STRINGOVBLE> ::= <CTE_CAD> <STRINGOVBLE> ::= <VARIABLE> <PROPIETARIO> ::= <VACIO> <PROPIETARIO> ::= <CTE_CAD> <PTO> <PROPIETARIO> ::= <IDENTIFICADOR> <PTO> <NAMEDVALUE> ::= <VARIABLE> <NAMEDVALUE> ::= <CONSTANTE> <VARIABLE> ::= <VBLERECIBERDO> <CONSTANTE> ::= true <CONSTANTE> ::= false <CONSTANTE> ::= notfound <VARIABLES> ::= <VARIABLE> <MASVARIABLES> <MASVARIABLES> ::= <VACIO> <MASVARIABLES> ::= <COMA> <VARIABLES> <HELP> ::= <VACIO> <HELP> ::= help <NMERO> <OPCCHAR> ::= <VACIO> <OPCCHAR> ::= char <VBLESRECIBERDO> ::= <VBLERECIBERDO> <MASVBLESRECIBERDO> <MASVBLERECIBERDO> ::= <VACIO> <MASVBLERECIBERDO> ::= <COMA> <VBLESRECIBERDO> <VBLERECIBERDO> ::= <IDENTIFICADOR> <RESTOVBLERECIBERDO> <RESTOVBLERECIBERDO> ::= <VACIO> <RESTOVBLERECIBERDO> ::= <PTO> <VBLERECIBERDO> <RESTOVBLERECIBERDO> ::= <COR1> <DIMELTOARRAY> <COR2> <RETOARRAYRECIBERDO> <RETOARRAYRECIBERDO> ::= <VACIO> <RETOARRAYRECIBERDO> ::= <PTO> <IDENTIFICADOR> <RESTOARRAYRECIBERDO> <DIMELTOARRAY> ::= <EXPRINT> <RESTODIMELTOARRAY> maximo 3 dimensiones <RESTODIMELTOARRAY> ::= <VACIO> <RESTODIMELTOARRAY> ::= <COMA> <EXPRINT> <RESTODIMELTOARRAY> <LISTADEVBLES> ::= <LISTADEVBLE> <MASLISTADEVBLES> <MASLISTADEVBLES> ::= <VACIO>

38 <MASLISTADEVBLES> ::= <COMA> <LISTADEVBLES> <LISTADEVBLE> ::= <IDENTIFICADOR> <RESTOLISTADEVBLE> <RESTOLISTADEVBLE> ::= <VACIO> <RESTOLISTADEVBLE> ::= <PTO> <RESTOREGLISTADEVBLE> <RESTOLISTADEVBLE> ::= <COR1> <DIMELTOARRAY> <COR2> <RESTOREGLISTADEVBLE> ::= <IDENTIFICADOR> <MASRESTOREGLISTADEVBLE> <RESTOREGLISTADEVBLE> ::= <ASTERISCO> <MASRESTOREGLISTADEVBLE> ::= <PTO> <RESTOREGLISTADEVBLE> <MASRESTOREGLISTADEVBLE> ::= <ULTIMOREGLISTADEVBLE> <ULTIMOREGLISTADEVBLE> ::= <VACIO> <ULTIMOREGLISTADEVBLE> ::= through <HASTAREGLISTADEVBLE> <ULTIMOREGLISTADEVBLE> ::= thru <HASTAREGLISTADEVBLE> <HASTAREGLISTADEVBLE> ::= <IDENTIFICADOR> <PTO> <IDENTIFICADOR> <MASHASTAREGLISTADEVBLE> <MASHASTAREGLISTADEVBLE> ::= <VACIO> <MASHASTAREGLISTADEVBLE> ::= <PTO> <IDENTIFICADOR> <MASHASTAREGLISTADEVBLE> <ARGUMENTOS> ::= <PAR1> <ARGS> <PAR2> <ARGS> ::= <VACIO> <ARGS> ::= <ARGUMENTO> <MASARGUMENTOS> <ARGUMENTO> ::= <IDENTIFICADOR> <MASARTUMENTOS> ::= <VACIO> <MASARGUMENTOS> ::= <COMA> <ARGUMENTO> <MASARGUMENTOS> <ARGUMENTOREPORT> ::= <IDENTIFICADOR> <RESTOARGREPORT> <RESTOARGREPORT> ::= <VACIO> <RESTOARGREPORT> ::= <PTO> <ARTUMENTOREPORT> <COLUMNLIST> ::= <IDENTIFICADOR> <RESTO1COLUMNLIST> <MASCOLUMNLIST> <MASCOLUMNLIST> ::= <VACIO> <MASCOLUMNLIST> ::= <COMA> <COLUMNLIST> <RESTO1COLUMNLIST> ::= <VACIO> <RESTO1COLUMNLIST> ::= <PTO> <RESTO2COLUMNLIST> <RESTO2COLUMNLIST> ::= <IDENTIFICADOR> <RESTO3COLUMNLIST> <RESTO2COLUMNLIST> ::= <ASTERISCO> <RESTO3COLUMNLIST> ::= <VACIO> <RESTO3COLUMNLIST> ::= <PTO> <IDENTIFICADOR> <CAMPOS> ::= <CAMPO> <MASCAMPOS> <MASCAMPOS> ::= <VACIO> <MASCAMPOS> ::= <COMA> <CAMPO> <MASCAMPOS> <CAMPO> ::= <IDENTIFICADOR> <CLAUSULASCAMPO> ::= <CLAUSULACAMPO> <MASCLAUSULACAMPO> <MASCLAUSULACAMPO> ::= <VACIO> <MASCLAUSULACAMPO> ::= <COMA> <CLAUSULACAMPO> <MASCLAUSULACAMPO> <CLAUSULACAMPO> ::= <IDENTIFICADOR> <PARTE1CLAUSULACAMPO> <CLAUSULACAMPO> ::= formonly <PTO> <PARTE2CLAUSULACAMPO> <PARTE1CLAUSULACAMPO> ::= <VACIO> <PARTE1CLAUSULACAMPO> ::= <COR1> <EXPRINT> <COR2> <PTO> <PARTE2CLAUSULACAMPO> <PARTE1CLAUSULACAMPO> ::= <PTO> <PARTE2CLAUSULACAMPO> <PARTE2CLAUSULACAMPO> ::= <IDENTIFICADOR> <PARTE2CLAUSULACAMPO> ::= <ASTERISCO> <PARTE2CLAUSULACAMPO> ::= <THRUNOTACION> <THRUNOTACION> ::= thru <IDENTIFICADOR> <RESTOTHRUNOTACION> <THRUNOTACION> ::= through <IDENTIFICADOR> <RESTOTHRUNOTACION> <RESTOTHRUNOTACION> ::= <COR1> <EXPRINT> <COR2> <PTO> <IDENTIFICADOR> <RESTOTHRUNOTACION> ::= <PTO> <IDENTIFICADOR> <ATTRIBUTECLAUSE> ::= <VACIO> <ATTRIBUTECLAUSE> ::= attribute <PAR1> <COLORATTRIBUTE> <MODATTRIBUTE> <PAR2> <COLORATTRIBUTE> ::= <UNMODATTRIBUTE> <COLORATTRIBUTE> ::= black

39 <COLORATTRIBUTE> ::= blue <COLORATTRIBUTE> ::= cyan <COLORATTRIBUTE> ::= green <COLORATTRIBUTE> ::= magenta <COLORATTRIBUTE> ::= red <COLORATTRIBUTE> ::= white <COLORATTRIBUTE> ::= yellow <COLORATTRIBUTE> ::= bold <COLORATTRIBUTE> ::= dim <COLORATTRIBUTE> ::= invisible <COLORATTRIBUTE> ::= normal <MODATTRIBUTE> ::= <COMA> <UNMODATTRIBUTE> <MODATTRIBUTE> <MODATTRIBUTE> ::= <VACIO> <UNMODATTRIBUTE> ::= reverse <UNMODATTRIBUTE> ::= blink <UNMODATTRIBUTE> ::= underline <OPENWINDOWATTRIBUTECLAUSE> ::= <VACIO> <OPENWINDOWATTRIBUTECLAUSE> ::= attribute <PAR1> <OWCOLORATTRIBUTE> <OWMASMODATTRIBUTE> <PAR2> <OWCOLORATTRIBUTE> ::= <OWUNMODATTRIBUTE> <OWCOLORATTRIBUTE> ::= black <OWCOLORATTRIBUTE> ::= blue <OWCOLORATTRIBUTE> ::= cyan <OWCOLORATTRIBUTE> ::= green <OWCOLORATTRIBUTE> ::= magenta <OWCOLORATTRIBUTE> ::= red <OWCOLORATTRIBUTE> ::= white <OWCOLORATTRIBUTE> ::= yellow <OWCOLORATTRIBUTE> ::= bold <OWCOLORATTRIBUTE> ::= dim <OWCOLORATTRIBUTE> ::= normal <OWUNMODATTRIBUTE> ::= reverse <OWUNMODATTRIBUTE> ::= border <OWUNMODATTRIBUTE> ::= <OTROOWMODATTTRIBUTE> line <RESERVEDLINEPOSITION> <OTROOWMODATTTRIBUTE> ::= comment <OTROOWMODATTTRIBUTE> ::= form <OTROOWMODATTTRIBUTE> ::= menu <OTROOWMODATTTRIBUTE> ::= message <OTROOWMODATTTRIBUTE> ::= prompt <RESERVEDLINEPOSITION> ::= first <FIRSTRESERVEDLINEPOSITION> <RESERVEDLINEPOSITION> ::= last <LASTRESERVEDLINEPOSITION> <RESERVEDLINEPOSITION> ::= <INTEGEROVBLE> <FIRSTRESERVEDLINEPOSITION> ::= <MAS> <INTEGEROVBLE> <LASTRESERVEDLINEPOSITION> ::= <MENOS> <INTEGEROVBLE> <OWMASMODATTRIBUTE> ::= <COMA> <UNMODATTRIBUTE> <OWMASMODATTRIBUTE> <OWMASMODATTRIBUTE> ::= <VACIO> <OPTIONSATTRIBUTECLAUSE> ::= attribute <PAR1> <OPUNAUOTRA> <PAR2> <OPUNAUOTRA> ::= <OPCOLORATTRIBUTE> <OPMODATTRIBUTE> <OPUNAUOTRA> ::= form <OPUNAUOTRA> ::= window <OPCOLORATTRIBUTE> ::= <OPUNMODATTRIBUTE> <OPCOLORATTRIBUTE> ::= black <OPCOLORATTRIBUTE> ::= blue <OPCOLORATTRIBUTE> ::= cyan <OPCOLORATTRIBUTE> ::= green <OPCOLORATTRIBUTE> ::= magenta <OPCOLORATTRIBUTE> ::= red <OPCOLORATTRIBUTE> ::= white <OPCOLORATTRIBUTE> ::= yellow <OPCOLORATTRIBUTE> ::= bold <OPCOLORATTRIBUTE> ::= dim <OPCOLORATTRIBUTE> ::= normal

40 <OPCOLORATTRIBUTE> ::= invisible <OPMODATTRIBUTE> ::= <COMA> <OPUNMODDATTRIBUTE> <OPMODATTRIBUTE> <OPMODATTRIBUTE> ::= <VACIO> <OPUNMODATTRIBUTE> ::= reverse <OPUNMODATTRIBUTE> ::= border <OPUNMODATTRIBUTE> ::= underline <RESERVEDLINEPOSITION> ::= first <FIRSTRESERVEDLINEPOSITION> <RESERVEDLINEPOSITION> ::= last <LASTRESERVEDLINEPOSITION> <RESERVEDLINEPOSITION> ::= <INTEGEROVBLE> <FIRSTRESERVEDLINEPOSITION> ::= <MAS> <INTEGEROVBLE> <FIRSTRESERVEDLINEPOSITION> ::= <VACIO> <LASTRESERVEDLINEPOSITION> ::= <MENOS> <INTEGEROVBLE> <LASTRESERVEDLINEPOSITION> ::= <VACIO> <PARAMETROSONKEY> ::= <PAR1> <KEYPARAM> <MASKEYPARAM> <PAR2> <MASKEYPARAM> ::= <VACIO> <MASKEYPARAM> ::= <COMA> <KEYPARAM> <MASKEYPARAM> <KEYPARAM> ::= <PALRES> <KEYPARAM> ::= <TECLAFUNCION> <KEYPARAM> ::= <CONTROLKEY> <CONTROLKEY> ::= control <GUION> <LETRA> <----------------> <EXPR4GL> ::= <EXPR> <EXPR> ::= <EXPRUSING> <MASEXPRUSING> <MASEXPRUSING> ::= <VACIO> <MASEXPRUSING> ::= using <EXPRUSING> <MASEXPRUSING> <EXPRUSING> ::= <EXPRCONDICIONALOR> <MASEXPRCONDICIONALOR> <MASEXPRCONDICIONALOR> ::= <VACIO> <MASEXPRCONDICIONALOR> ::= or <EXPRCONDICIONALOR> <MASEXPRCONDICIONALOR> <EXPRCONDICIONALOR> ::= <EXPRCONDICIONALAND> <MASEXPRCONDICIONALAND> <MASEXPRCONDICIONALAND> ::= <VACIO> <MASEXPRCONDICIONALAND> ::= and <EXPRCONDICIONALAND> <MASEXPRCONDICIONALAND> <EXPRCONDICIONALAND> ::= <EXPRIS> <MASEXPRIS> <MASEXPRIS> ::= <VACIO> <MASEXPRIS> ::= is null <MASESPRIS> null == <expris> <MASEXPRIS> ::= is not null <MASESPRIS> null == <expris> --> <exprprim> <cte> <EXPRIS> ::= <EXPRBETWEEN> <MASEXPRBETWEEN> <MASEXPRBETWEEN> ::= <VACIO> <MASEXPRBETWEEN> ::= between <EXPRBETWEEN> <MASEXPRBETWEEN> <EXPRBETWEEN> ::= <EXPRIN> <MASEXPRIN> <MASEXPRIN> ::= <VACIO> <MASEXPRIN> ::= in <PAR1> <EXPRS> <PAR2> <MASEXPRIN> MIRAR <EXPRIN> ::= <EXPRRELACION> <MASEXPRRELACION> <MASEXPRRELACION> ::= <VACIO> <MASEXPRRELACION> ::= compigual <EXPRRELACION> <MASEXPRRELACIOM> <MASEXPRRELACION> ::= compdesigual <EXPRRELACION> <MASEXPRRELACION> <MASEXPRRELACION> ::= menor <EXPRRELACION> <MASEXPRRELACION> <MASEXPRRELACION> ::= mayor <EXPRRELACION> <MASEXPRRELACION> <MASEXPRRELACION> ::= menorigual <EXPRRELACION> <MASEXPRRELACION> <MASEXPRRELACION> ::= mayorigual <EXPRRELACION> <MASEXPRRELACION> <EXPRRELACION> ::= <EXPRLIKE> <MASEXPRLIKE> <MASEXPRLIKE> ::= <VACIO> <MASEXPRLIKE> ::= like <EXPRLIKE> <MASEXPRLIKE> <MASEXPRLIKE> ::= matches <EXPRLIKE> <MASEXPRLIKE> <EXPRLIKE> ::= <EXPRCONCATENACION> <MASEXPRCONCATENACION> <MASEXPRCONCATENACION> ::= <VACIO> <MASEXPRCONCATENACION> ::= <CONCAT> <EXPRCONCATENACION> <MASEXPRCONCATENACION> <MASEXPRCONCATENACION> ::= <COMA> <EXPRCONCATENACION> <MASEXPRCONCATENACION> <EXPRCONCATENACION> ::= <EXPRADICION> <MASEXPRADICION>

41 <MASEXPRADICION> ::= <VACIO> <MASEXPRADICION> ::= mas <EXPRADICION> <MASEXPRADICION> <MASEXPRADICION> ::= menos <EXPRADICION> <MASEXPRADICION> <EXPRADICION> ::= <EXPRMULTIPLY> <MASEXPRMULTIPLY> <MASEXPRMULTIPLY> ::= <VACIO> <MASEXPRMULTIPLY> ::= <POR> <EXPRMULTIPLY> <MASEXPRMULTIPLY> <MASEXPRMULTIPLY> ::= <ENTRE> <EXPRMULTIPLY> <MASEXPRMULTIPLY> <EXPRMULTIPLY> ::= <EXPREXPMOD> <MASEXPREXPMOD> <MASEXPREXPMOD> ::= <MOD> <EXPREXPMOD> <MASEXPREXPMOD> <MASEXPREXPMOD> ::= <EXP> <EXPREXPMOD> <MASEXPREXPMOD> <EXPREXPMOD> ::= <EXPRUNITS> <MASEXPRUNITS> <MASEXPRUNITS> ::= <VACIO> <MASEXPRUNITS> ::= units <CTEUNITS> <MASEXPRUNITS> <EXPRUNITS> ::= <EXPRUNARIA> <EXPRUNARIA> ::= ascii <EXPRUNARIA> <EXPRUNARIA> ::= <EXPRUNARIA> clipped <EXPRUNARIA> ::= column <EXPRUNARIA> <EXPRUNARIA> ::= ord <PAR1> <EXPRUNARIA> <PAR2> <EXPRUNARIA> ::= <EXPRUNARIA> spaces <EXPRUNARIA> ::= <EXPRUNARIA> wordwrap <EXPRUNARIA> ::= not <EXPRUNARIA> <EXPRUNARIA> ::= <MAS> <EXPRUNARIA> <EXPRUNARIA> ::= <MENOS> <EXPRUNARIA> <EXPRUNARIA> ::= <EXPRUNARIA> units <EXPRUNITS> <EXPRUNARIA> ::= <EXPRPRIMARIA> <EXPRPRIMARIA> ::= <PARENTESIS1> <EXPR> <PARENTESIS2> <EXPRPRIMARIA> ::= <LITERAL> <EXPRPRIMARIA> ::= <VARIABLE> <EXPRPRIMARIA> ::= <LLAMADAFUNCION> <EXPRPRIMARIA> ::= <LLAMADAFUNCIONPREDEFINIDA> <EXPRPRIMARIA> ::= <EXPRESIONAGREGADA> <LITERAL> ::= ctecualquiertipo <CTEUNITS> ::= year <CTEUNITS> ::= month <CTEUNITS> ::= day <CTEUNITS> ::= hour <CTEUNITS> ::= minute <CTEUNITS> ::= second <CTEUNITS> ::= fraction <LLAMADAFUNCION> ::= <IDENTIFICADOR> <PAR1> <ARGSLLAMADAF> <PAR2> <RESTOSENTENCIACALL> <ARGSLLAMADAF> ::= <VACIO> <ARGSLLAMADAF> ::= <EXPR4GL> <MASARGSLLAMADAF> <MASARGSLLAMADAF> ::= <VACIO> <MASARGSLLAMADAF> ::= <COMA> <EXPR4GL> <MASARGSLLAMADAF> <LLAMADAFUNCIONPREDEFINIDA> ::= <AGREGATEREPORTFUNCTIONS> <LLAMADAFUNCIONPREDEFINIDA> ::= <AGREGATEFUNCTIONS> <AGRETATEREPORTFUNCTIONS> ::= <OPCGROUPAGREGATE> <UNAAGREGATEREPORFUNCTION> <OPCGROUPAGREGATE> ::= <VACIO> <OPCGROUPAGREGATE> ::= group <UNAAGRETATEREPORTFUNCTION> ::= <VACIO> <UNAAGRETATEREPORTFUNCTION> ::= percent <RESTOPERCENTCONUNT> <UNAAGRETATEREPORTFUNCTION> ::= count <RESTOPERCENTCONUNT> <UNAAGRETATEREPORTFUNCTION> ::= avg <RESTOAVGSUM> <OPCAVGSUMMAXMIN> <UNAAGRETATEREPORTFUNCTION> ::= sum <RESTOAVGSUM> <OPCAVGSUMMAXMIN> <UNAAGRETATEREPORTFUNCTION> ::= max <EXPR4GL> <OPCAVGSUMMAXMIN> <UNAAGRETATEREPORTFUNCTION> ::= min <EXPR4GL> <OPCAVGSUMMAXMIN> <RESTOPERCENTCONUNT> ::= <PAR1> <ASTERISCO> <PAR2> <RESTOAVGSUM> ::= <EXPRNUM> <RESTOAVGSUM> ::= <INBERVALVALUE>

42 <OPCAVGSUMMAXMIN> ::= <VACIO> <OPCAVGSUMMAXMIN> ::= where <EXPRBOOL> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> <AGREGATEFUNCTIONS> ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= ::= arg_val <PAR1> <EXPR> <PAR2> arr_count <PAR1> <PAR2> arg_curr <PAR1> <PAR2> cursor_name <PAR1> <EXPR> <PAR2> downshift <PAR1> <EXPR> <PAR2> upshift <PAR1> <EXPR> <PAR2> err_get <PAR1> <EXPR> <PAR2> fgl_drawbox <PAR1> <EXPR> <PAR2> fgl_getenv <PAR1> <EXPR> <PAR2> fgl_getkey <PAR1> <PAR2> fgl_keyval <PAR1> <EXPR> <PAR2> fgl_lastkey <PAR1> <PAR2> fgl_scr_size <PAR1> <EXPR> <PAR2> length <PAR1> <EXPR> <PAR2> nuv_args <PAR1> <PAR2> ord <PAR1> <EXPR> <PAR2> scr_line <PAR1> <PAR2> set_count <PAR1> <PAR2>

<EXPRAGREGADA> ::= current <RESTOCURRENT> <EXPRAGREGADA> ::= date <RESTODATE> <EXPRAGREGADA> ::= day <PAR1> <EXPR> <PAR2> <EXPRAGREGADA> ::= month <PAR1> <EXPR> <PAR2> <EXPRAGREGADA> ::= year <PAR1> <EXPR> <PAR2> <EXPRAGREGADA> ::= weekday <PAR1> <EXPR> <PAR2> <EXPRAGREGADA> ::= extend <PAR1> <EXPR> <OPCDATETIMEQUALIFIER> <PAR2> <EXPRAGREGADA> ::= field_touched <PAR1> <SUBCLAUSULASCAMPO> <PAR2> <EXPRAGREGADA> ::= get_fldbuf <PAR1> <SUBCLAUSULACAMPO> <PAR2> <EXPRAGREGADA> ::= infield <PAR1> <SUBCLAUSULACAMPO> <PAR2> <EXPRAGREGADA> ::= pageno <EXPRAGREGADA> ::= lineno <EXPRAGREGADA> ::= today <EXPRAGREGADA> ::= time <RESTOTIME> <RESTOCURRENT> ::= <VACIO> <RESTOCURRENT> ::= <DATETIMEQUALIFIER> <RESTODATE> ::= <VACIO> <RESTODATE> ::= <PAR1> <EXPR> <PAR2> <RESTOTIME> ::= <VACIO> <RESTOTIME> ::= <PAR1> <EXPR> <PAR2> <------------> <SENTENCIASQL> ::= <SENTENCIAALTER> <SENTENCIAALTER> ::= alter <RESTOSENTENCIAALTER> <RESTOSENTENCIAALTER> ::= <SENTENCIAALTERINDEX> <RESTOSENTENCIAALTER> ::= <SENTENCIAALTERTABLE> <SENTENCIAALTERINDEX> ::= index <ELTONAME> to <OPCNOT> cluster <SENTENCIAALTERTABLE> ::= table <ELTONAME> <ALTERTABLECLAUSULAS> <ALTERTABLECLAUSULAS> ::= <UNAALTERTABLECLAUSULAS> <MASALTERTABLECLAUSULAS> <MASALTERTABLECLAUSULAS> ::= <VACIO> <MASALTERTABLECLAUSULAS> ::= <COMA> <UNAALTERTABLECLAUSULAS> <MASALTERTABLECLAU <UNAALTERTABLECLAUSULAS> ::= add <RESTOADDALTERCLAUSULA> <UNAALTERTABLECLAUSULAS> ::= drop <RESTODROPALTERCLAUSULA> <UNAALTERTABLECLAUSULAS> ::= modify <RESTOMODIFYALTERCLAUSULA> <UNAALTERTABLECLAUSULAS> ::= lock mode <PAR1> <PAGEOROW> <PAR2> <RESTOADDALTERCLAUSULA> ::= constraint <TABLACONSTRAINTDEF> <RESTOADDALTERCLAUSULA> ::= <PAR1> <ADDCOLUMNSDEFINITION> <PAR2> <ADDCOLUMNSDEFINITION>::= <UNAADDCOLUMNSDEFINITION> <MASADDCOLUMNSDEFINITION>

43 <MASADDCOLUMNSDEFINITION> ::= <VACIO> <MASADDCOLUMNSDEFINITION> ::= <UNAADDCOLUMNSDEFINITION> <MASADDCOLUMNSDEFINITIO <UNAADDCOLUMNSDEFINITION> ::= <COLUMNDEFINITION> <OPCBEFORECOLUMN> <OPCBEFORECOLUMN> ::= <VACIO> <OPCBEFORECOLUMN> ::= before <IDENTIFICADOR> <RESTOMODIFYALTERCLAUSULA> ::= next size <ENTERO> <RESTOMODIFYALTERCLAUSULA> ::= <PAR1> <COLUMNSDEFINITION> <PAR2> <RESTODROPALTERCLAUSULA> ::= constraint <PAR1> <ELTOSNAME> <PAR2> <RESTODROPALTERCLAUSULA> ::= <PAR1> <COLUMNS> <PAR2> <COLUMNDEFINITION> ::= <UNACOLUMNDEFINITION> <MASCOLUMNDEFINITION> <MASCOLUMNDEFINITION> ::= <COMA> <UNACOLUMNDEFINITION> <MASCOLUMNDEFINITION> <MASCOLUMNDEFINITION> ::= <VACIO> <SENTENCIASQL> ::= <SENTENCIABEGINWORK> <SENTENCIABEGINWORK> ::= begin work <SENTENCIASQL> ::= <SENTENCIACLOSE> <SENTENCIACLOSE> ::= <SENTENCIACLOSECURSOR> <SENTENCIACLOSE> ::= <SENTENCIACLOSEDATABASE> <SENTENCIACLOSECURSOR> ::= close <IDENTIFICADOR> <SENTENCIACLOSEDATABASE> ::= close database <SENTENCIASQL> ::= <SENTENCIACOMMITWORK> <SENTENCIACOMMITWORK> ::= commit work <SENTENCIASQL> ::= <SENTENCIACONNECT> <SENTENCIACONNECT> ::= connect to <NOMBREBD> <SENTENCIASQL> ::= <SENTENCIACREATE> <SENTENCIACREATE> ::= create <RESTOSENTENCIACREATE> <RESTOSENTENCIACREATE> ::= audit for <ELTONAME> in <CTE_CAD> <RESTOSENTENCIACREATE> ::= database <SENTENCIACREATEDATABASE> <RESTOSENTENCIACREATE> ::= procedure from <STRINGOVBLE> <RESTOSENTENCIACREATE> ::= table <SENTENCIACREATETABLE> <RESTOSENTENCIACREATE> ::= temp table <SENTENCIACREATETEMPTABLE> <RESTOSENTENCIACREATE> ::= view <SENTENCIACREATEVIEW> <RESTOSENTENCIACREATE> ::= <OPCUNIQUEDISTINCT> <OPCCLUSTER> index <SENTENCIACREATEINDEX> <RESTOSENTENCIACREATE> ::= <OPCPUBLICPRIVATE> synonym <SENTENCIACREATESYNONYM> <SENTENCIACREATEDATABASE> ::= <NOMBREDB> <OPCSELOG> <OPCSELOG> ::= <VACIO> <OPCSELOG> ::= with log in <CTE_CAD> <OPCMODEANSI> <OPCMODEANSI> ::= <VACIO> <OPCMODEANSI> ::= mode ansi <SENTENCIACREATEINDEX> ::= <ELTONAME> on <ELTONAME> <PAR1> <ELTOSINDICE> <PAR2> <ELTOSINDICE> ::= <ELTOINDICE> <MASELTOSINDICE> <MASELTOSINDICE> ::= <VACIO> <MASELTOSINDICE> ::= <COMA> <ELTOINDICE> <MASELTOSINDICE> <ELTOINDICE> ::= <IDENTIFICADOR> <OPCASCDESC> <SENTENCIACREATESYNONYM> ::= <ELTONAME> for <ELTONAME> <SENTENCIACREATETABLE> ::= <ELTONAME> <PAR1> <CAMPOSCREATETABLE> <PAR2> <OPCSTORAGEOPTION> <OPCSTORAGEOPTION> ::= <VACIO> <OPCSTORAGEOPTION> ::= in <CTE_CAD> <OPCSTORAGEOPTION> ::= in <VARIABLE> <OPCEXTENTOPC> <OPCLOCKMODE> <OPCEXTENTOPC> ::= <VAIO>

44 <OPCEXTENTOPC> ::= <OPCEXTENTSIZE> <OPCNEXTSIZE> <OPCEXTENTOPC> ::= <OPCNEXTSIZE> <OPCEXTNTSIZE> ::= <VACIO> <OPCEXTNTSIZE> ::= extent size <ENTERO> <OPCNEXTSIZE> ::= <VACIO> <OPCNEXTSIZE> ::= next size <ENTERO> <OPCLOCKMODE> ::= <VACIO> <OPCLOCKMODE> ::= lock mode <OPCPAGEROW> <CAMPOSCREATETABLE> ::= <COLUMNDEFINITION> <RESTOCAMPOSCREATETABLE> <COLUMNDEFINITION> ::= <IDENTIFICADOR> <TIPODATOSQL> <OPCNOTNULL> <OPCCOLUMNCONSTRAINTDEF> <OPCCOLUMNCONSTRAINTDEF> ::= <UNIQUEDISTINCT> <OPCCONSTRAINT> <RESTOCAMPOSCREATETABLE> ::= <VACIO> <RESTOCAMPOSCREATETABLE> ::= <COMA> <CONSTRAINTDEF> <RESTOCAMPOSCREATETABLE> <CONSTRAINTDEF> ::= <UNIQUEDISTINCT> <PAR1> <COLUMNS> <PAR2> <OPCCONSTRATINT> <SENTENCIACREATETEMPTABLE> ::= <IDENTIFICADOR> <PAR1> <CAMPOSCREATETEMPTABLE> <PAR2> <OPCWHITNOLOG> <OPCSTORAGEOPTION> <OPCWITHNOLOG> ::= <VACIO> <OPCWITHNOLOG> ::= with no log <CAMPOSCREATETEMPTABLE> ::= <TEMPCOLUMNSDEFINITION> <RESTOCAMPOSCREATETEMPTABLE> <TEMPCOLUMNSDEFINITION> ::= <UNATEMPCOLUMNDEFINITION> <MASTEMPCOLUMNDEFINITION> <MASTEMPCOLUMNDEFINITION> ::= <VACIO> <MASTEMPCOLUMNDEFINITION> ::= <COMA> <UNATEMPCOLUMNDEFINITION> <MASTEMPCOLUMNDEFINITION> <UNATEMPCOLUMNDEFINITION> ::= <IDENTIFICADOR> <TIPODATOSQL> <OPCNOTNULL> <OPCTEMPCOLUMNCONSTRAINTDEF> <OPCTEMPCOLUMNCONSTRAINTDEF> ::= unique <OPCTEMPCOLUMNCONSTRAINTDEF> ::= distinct <OPCTEMPCOLUMNCONSTRAINTDEF> ::= primary key <OPCTEMPCOLUMNCONSTRAINTDEF> ::= <CHECKCLAUSE> <CHECKCLAUSE> ::= check <PAR1> <EXPRSQL> <PAR2> <RESTOCAMPOSCREATETEMPTABLE> ::= <VACIO> <RESTOCAMPOSCREATETEMPTABLE> ::= <COMA> <TEMPCONSTRAINTDEF> <RESTOCAMPOSCREATETEMPTABLE> <TEMPCONSTRAINTDEF> ::= <CHECKCLAUSE> <TEMPCONSTRAINTDEF> ::= <UNATEMPCONSTRAINTDEF> <OTRATEMPCONSTRAINTDEF> <UNATEMPCONSTRAINTDEF> ::= unique <UNATEMPCONSTRAINTDEF> ::= distinct <UNATEMPCONSTRAINTDEF> ::= primary key <OTRATEMPCONSTRAINTDEF> ::= <PAR1> <COLUMNS> <PAR2> <SENTENCIACREATEVIEW> ::= <ELTONAME> <OPCCOLUMNS> as <SENTENCIASELECT> <OPCWITHCHECKOPTION> <OPCWITHCHECKOPTION> ::= <VACIO> <OPCWITHCHECKOPTION> ::= with check option <SENTENCIASQL> ::= <SENTENCIADATABASE> <SENTENCIADATABASE> ::= <VACIO> <SENTENCIADATABASE> ::= database <NOMBREDB> <ATRIBDB> <ATRIBDB> ::= <VACIO> <ATRIBDB> ::= exclusive <NOMBREDB> ::= <VARIABLE> <NOMBREDB> ::= <CTE_CADENA> <SENTENCIASQL> ::= <SENTENCIADECLARE> <SETENCIADECLARE> ::= declare <IDENTIFICADOR> <CURSOROSCROLLCURSOR> <CURSOROSCROLLCURSOR> ::= cursor <OPCWITHHOLD> for <SENTDELCURSOR> <CURSOROSCROLLCURSOR> ::= scroll cursor <OPCWITHHOLD> for <SENTDELSCROLLCURSOR> <SENTDELCURSOR> ::= <SENTENCIAINSERT>

45 <SENTDELCURSOR> ::= <SENTENCIASELECT> <OPCFORUPDATECURSOR> <OPDFORUPDATECURSOR> ::= <VACIO> <OPCFORUPDATECURSOR> ::= for update <MASFORUPDATECURSOR> <MASFORUPDATECURSOR> ::= <VACIO> <MASFORUPDATECURSOR> ::= of <COLUMNS> <SENTDELCURSOR> ::= <IDENTIFICADOR> <SENTDELSCROLLCURSOR> ::= <SENTENCIASELECT> <SENTDELSCROLLCURSOR> ::= <IDENTIFICADOR> <SENTENCIASQL> ::= <SENTENCIADELETE> <SENTENCIADELETE> ::= delete from <ELTONAME> <OPCRESTODELETE> <OPCRESTODELETE> ::= <VACIO> <OPCRESTODELETE> ::= where <MASRESTODELETE> <MASRESTODELETE> ::= current of <IDENTIFICADOR> <MASRESTODELETE> ::= <EXPRSQL> <SENTENCIASQL> ::= <SENTENCIADISCONNECT> <SENTENCIADISCONNECT> ::= disconnect current <SENTENCIASQL> ::= <SENTENCIADROP> <SENTENCIADROP> ::= drop <RESTOSENTDROP> <RESTOSENTDROP> ::= audit for <ELTONAME> <RESTOSENTDROP> ::= database <NOMBREDB> <RESTOSENTDROP> ::= index <ELTONAME> <RESTOSENTDROP> ::= synonym <ELTONAME> <RESTOSENTDROP> ::= table <ELTONAME> <RESTOSENTDROP> ::= view <ELTONAME> <SENTENCIASQL> ::= <SENTENCIAEXECUTE> <SENTENCIAEXECUTE> ::= execute <RESTOSENTEXECUTE> <RESTOSENTEXECUTE> ::= <IDENTIFICADOR> <RESTOSENTENCIAEXECUTE> <RESTOSENTENCIAEXECUTE> ::= <VACIO> <RESTOSENTENCIAEXECUTE> ::= <USINGOINTO> <LISTADEVBLES> <RESTOSENTEXECUTE> ::= immediate <STRINGOVBLE> <SENTENCIASQL> ::= <SENTENCIAFETCH> <SETENCIAFETCH> ::= fetch <PARTE1FETCH> <IDENTIFICADOR> <OPCPARTE2FETCH> <PARTE1FETCH> ::= <VACIO> <PARTE1FETCH> ::= next <PARTE1FETCH> ::= previous <PARTE1FETCH> ::= prior <PARTE1FETCH> ::= first <PARTE1FETCH> ::= last <PARTE1FETCH> ::= current <PARTE1FETCH> ::= relative <OPCMASMENOS> <INTEGEROOVBE> <PARTE1FETCH> ::= absolute <INTEGEROVBLE> <OPCPARTE2FETCH> ::= <VACIO> <OPCPARTE2FETCH> ::= into <LISTADEVBLES> <SENTENCIASQL> ::= <SENTENCIAFLUSH> <SENTENCIAFLUSH> ::= flush <IDENTIFICADOR> <SENTENCIASQL> ::= <SENTENCIAFREE> <SENTENCIAFREE> ::= free <IDENTIFICADOR> <SENTENCIAFREE> ::= free <VARIABLE> <SENTENCIASQL> ::= <SENTENCIAGRANT> <SENTENCIAGRANT> ::= grant <RESTOSENTGRANT> <RESTOSENTGRANT> ::= <DATABASEPRIVILEGES> to <USERSGRANT> <RESTOSENTGRANT> ::= <TABLEPRIVILEGES> on <ELTONAME> to <USERGRANT> <OPCGRANTOPT> <OPCASVALOR> <USERSGRANT> ::= public <USERSGRANT> ::= <USUARIOS> <DATABASEPRIVILEGES> ::= connect

46 <DATABASEPRIVILEGES> ::= resource <DATABASEPRIVILEGES> ::= dba <TABLEPRIVILEGES> ::= all <OPCPRIVILEGES> <TABLEPRIVILEGES> ::= <UNPRIVILEGE> <MASPRIVILEGES> <MASPRIVILEGES> ::= <VACIO> <MASPRIVILEGES> ::= <COMA> <UNPRIVILEGE> <MASPRIVILEGES> <UNPRIVILEGES> ::= insert <UNPRIVILEGES> ::= delete <UNPRIVILEGES> ::= index <UNPRIVILEGES> ::= alter <UNPRIVILEGES> ::= update <OPCRESTOTABLEPRIVILEGES> <UNPRIVILEGES> ::= select <OPCRESTOTABLEPRIVILEGES> <OPCRESTOTABLEPRIVILEGES> ::= <PAR1> <COLUMNS> <PAR2> <SENTENCIASQL> ::= <SENTENCIAINSERT> <SENTENCIAINSERT> ::= insert into <ELTONAME> <OPCCOLUMNS> <RESTOSENTINSERT> <RESTOINSERT> ::= <SENTENCIASELECT> <RESTOINSERT> ::= <CLAUSULAVALUES> <SENTENCIASQL> ::= <SENTENCIALOAD> <SENTENCIALOAD> ::= load from <STRINGOVBLE> <OPCDELIMITER> <RESTOSENTLOAD> <RESTOSENTLOAD> ::= insert into <EXPRNAME> <OPCCOLUMNS> <RESTOSENTLOAD> ::= <VARIABLE> <SENTENCIASQL> ::= <SENTENCIALOCK> <SENTENCIALOCK> ::= lock table <ELTONAME> in <SHAREEXCLUSIVE> mode <SENTENCIASQL> ::= <SENTENCIAOPEN> <SENTENCIAOPEN> ::= open <IDENTIFICADOR> <RESTOSENTOPEN> <RESTOSENTOPEN> ::= <VACIO> <RESTOSENTOPEN> ::= using <VARIABLES> <OPCWITHREOPTIMIZATION> <SENTENCIASQL> ::= <SENTENCIAPREPARE> <SENTENCIAPREPARE> ::= prepare <IDENTIFICADOR> from <STRINGOVBLE> <SENTENCIASQL> ::= <SENTENCIAPUT> <SENTENCIAPUT> ::= put <IDENTIFICADOR> <RESTOSENTPUT> <RESTOSENTPUT> ::= <VACIO> <RESTOSENTPUT> ::= from <VARIABLES> <SENTENCIASQL> ::= <SENTENCIARECOVER> <SENTENCIARECOVER> ::= recover table <ELTONAME> <SENTENCIASQL> ::= <SENTENCIARENAME> <SENTENCIARENAME> ::= rename <RESTOSENTRENAME> <RESTOSENTRENAME> ::= column <ELTONAME> <PTO> <IDENTIFICADOR> to <IDENTIFICADOR> <RESTOSENTRENAME> ::= table <OPCIDPTO> <IDENTIFICADOR> to <IDENTIFICADOR> <SENTENCIASQL> ::= <SENTENCIAREVOKE> <SENTENCIAREVOKE> ::= revoke <PARTE1SENTREVOKE> <PARTE2SENTREVOKE> <PARTE1SENTREVOKE> ::= <TABLEPRIVILEGES> on <ELTONAME> <PARTE1SENTREVOKE> ::= <DATABASEPRIVILEGES> <PARTE2SENTREVOKE> ::= from <MASPARTE2SENTREVOKE> <MASPARTE2SENTREVOKE> ::= public <MASPARTE2SENTREVOKE> ::= <COLUMNS> <TABLEPRIVILEGES> ::= all <OPCPRIVILEGES> <TABLEPRIVILEGES> ::= <UNPRIVILEGIO> <MASPRIVILEGIOS> <MASPRIVILEGIOS> ::= <VACIO> <MASPRIVILEGIOS>::= <COMA> <UNPRIVILEGIO> <MASPRIVILEGIOS> <UNPRIVILEGIO> ::= insert <UNPRIVILEGIO> ::= delete <UNPRIVILEGIO> ::= select <UNPRIVILEGIO> ::= update

47 <UNPRIVILEGIO> ::= index <UNPRIVILEGIO> ::= alter <DATABASEPRIVILEGES> ::= connect <DATABASEPRIVILEGES> ::= dba <DATABASEPRIVILEGES> ::= resource <SENTENCIASQL> ::= <SENTENCIAROLLBACK> <SENTENCIAROLLBACK> ::= rollback work <SENTENCIASQL> ::= <SENTENCIAROLLFORWARD> <SENTENCIAROLLFORWARD> ::= rollforward database <NOMBREDB> <SENTENCIASQL> ::= <SENTENCIASELECT> <SENTENCIASELECT> ::= select <SELECTCLAUSE> <OPCINTOCLAUSE> <FROMCLAUSE> <RESTO1SENTSELECT> <RESTO1SENTSELECT> ::= <UNIONSELECT> <RESTO1SENTSELECT> ::= <OPCWHERECLAUSE> <OPCGROUPBYCLAUSE> <OPCHAVINGCLAUSE> <RESTO2SENTSELECT> <RESTO2SENTSELECT> ::= <UNIONSELECT> <RESTO2SENTSELECT> ::= <OPCORDERBYCLAUSE> <OPCINTOTEMPCLAUSE> <UNIONSELECT> ::= union <OPCALL> <SENTENCIASELECT> <SELECTCLAUSE> ::= <OPCALLUNIQUEDISTINCT> <RESTOSELECTCLAUSE> <RESTOSELECTCLAUSE> ::= <UNASELECTITEM> <MASSELECTITEM> <MASSELECTITEM> ::= <VACIO> <MASSELECTITEM> ::= <COMA> <UNASELECTITEM> <MASSELECTITEM> <UNASELECTITEM> ::= <ASTERISCO> <UNASELECTITEM> ::= <PROPIETARIOSQL> <IDENTIFICADOR> <PTO> <ASTERISCO> <UNASELECTITEM> ::= <EXPRSQL> <RESTOUNASELECTITEM> <RESTOUNASELECTITEM> ::= <VACIO> <RESTOUNASELECTITEM> ::= <OPCAS> <IDENTIFICADOR> <OPCINTOCLAUSE> ::= <VACIO> <OPCINTOCLAUSE> ::= into <LISTADEVBLES> <FROMCLAUSE> ::= from <ELTONAME> <OPCALIAS> <OPCADICIONALTABLES> <OPCALIAS> ::= <VACIO> <OPCALIAS> ::= <OPCAS> <IDENTIFICADOR> <OPCADICIONALTABLES> ::= <VACIO> <OPCADICIONALTABLES> ::= <COMA> <ADICIONALTABLES> <ADICIONALTABLES> ::= <UNAADICIONALTABLES> <MASADICIONALTABLES> <MASADICIONALTABLES> ::= <VACIO> <MASADICIONALTABLES> ::= <COMA> <UNAADICIONALTABLES> <MASADICIONALTABLES> <UNAADICIONALTABLES> ::= <ELTOADICIONALTABLES> <UNAADICIONALTABLES> ::= outer <RESTOUNAADICIONALTABLES> <RESTOUNAADICIONALTABLES> ::= <ELTOADICIONALTABLES> <RESTOUNAADICIONALTABLES> ::= <PAR1> <ELTOADICIONALTABLES> <OPCADICIONALTABLES> <PAR2> <ELTOADICIONALTABLES> ::= <ELTONAME> <RESTOELTOADICIONALTABLES> <RESTOELTOADICIONALTABLES> ::= <VACIO> <RESTOELTOADICIONALTABLES> ::= <OPCAS> <IDENTIFICADOR> <OPCWHERECLAUSE> ::= <VACIO> <MASWHERECLAUSE> ::= <EXPRSQL> <OPCGROUPBYCLAUSE> ::= <VACIO> <OPCGROUPBYCLAUSE> ::= group by <RESTGROUPBYCLAUSE> <RESTGROUPBYCLAUSE> ::= <UNAGROUPBYCLAUSE> <MASGROUPBYCLAUSE> <MASGROUPBYCLAUSE> ::= <VACIO> <MASGROUPBYCLAUSE> ::= <COMA> <UNAGROUPBYCLAUSE> <MASGROUPBYCLAUSE> <UNAGROUPBYCLAUSE> ::= <ENTERO> <UNAGROUPBYCLAUSE> ::= <ELTOSEL> <OPCASCDESC> <OPCHAVINGCLAUSE> ::= <VACIO> <OPCHAVINGCLAUSE> ::= having <EXPRSQL> <OPCORDERBYCLAUSE> ::= <VACIO> <OPCORDERBYCLAUSE> ::= order by <UNAORDERBYCLAUSE> <MASORDERBYCLAUSE> <MASORDERBYCLAUSE> ::= <VACIO> <MASORDERBYCLAUSE> ::= <COMA> <UNAORDERBYCLAUSE> <MASORDERBYCLAUSE> <UNAORDERBYCLAUSE> ::= <ENTERO> <OPCASCDESC>

48 <UNAORDERBYCLAUSE> ::= <UNAORDERBYCLAUSE> ::= <OPCINTOTEMPCLAUSE> ::= <OPCINTOTEMPCLAUSE> ::= rowid <OPCASCDESC> <ELTOSEL> <OPCASCDESC> <VACIO> into temp <IDENTIFICADOR> <OPCWITHNOLOG>

<SENTENCIASQL> ::= <SENTENCIASTART> <SENTENCIASTART> ::= start <NOMBREBD> <SENTENCIASQL> ::= <SENTENCIAUNLOD> <SENTENCIAUNLOAD> ::= unload to <STRINGOVBLE> <OPCDELIMITER> <RESTOSENTUNLOAD> <RESTOSENTUNLOAD> ::= <SENTENCIASELECT> <RESTOSENTUNLOAD> ::= <VARIABLE> <SENTENCIASQL> ::= <SENTENCIAUNLOCK> <SENTENCIAUNLOCK> ::= unlock table <ELTONAME> <SENTENCIASQL> ::= <SENTENCIAUNPDATE> <SENTENCIAUPDATE> ::= update <RESTOSENTUPDATE> <RESTOSENTUPDATE> ::= statistics <OPCFORTABLE> <RESTOSENTUPDATE> ::= <ELTONAME> set <CLAUSULASET> <OPCWHERECLAUSULASET> <CLAUSULASET> ::= <PAR1> <ELTOSSEL> <PAR2> <CASO1CLAUSULASET> <CLAUSULASET> ::= <ASTERISCO> <CASO1CLAUSULASET> <CLAUSULASET> ::= <ELTONAME> <RESTOCLAUSUALSET> <RESTOCLAUSULASET> ::= <PTO> <ASTERISCO> <CASO1CLAUSULASET> <RESTOCLAUSULASET> ::= <PTO> <IDENTIFICADOR> <IGUAL> <CASO2CLAUSULASET> <RESTOCLAUSULASET> ::= <IGUAL> <CASO2CLAUSULASET> <CASO1CLAUSULASET> ::= <IGUAL> <RESTOCASO1CLAUSULASET> <RESTOCASO1CLAUSULASET> ::= <PAR1> <ELTOSCASO1CLAUSULASET> <PAR2> <RESTOCASO1CLAUSULASET> ::= <REFERECEDVALUES> <ELTOSCASO1CLAUSULASET> ::= <UNAELTOCASO1CLAUSULASET> <MASELTOCASO1CLAUSULASET> <MASELTOCASO1CLAUSULASET> ::= <VACIO> <MASELTOCASO1CLAUSULASET> ::= <COMA> <UNAELTOCASO1CLAUSULASET> <MASELTOCASO1CLAUSULASET> <UNAELTOCASO1CLAUSULASET> ::= <SENTENCIASELECT> //select ... <UNAELTOCASO1CLAUSULASET> ::= <EXPRSQL> <UNAELTOCASO1CLAUSULASET> ::= <REFRERENCEDVALUES> <RESTOUNAELTOCASO1CLAUSULASET> <RESTOUNAELTOCASO1CLAUSULASET> ::= <VACIO> <RESTOUNAELTOCASO1CLAUSULASET> ::= <MASMENOSPORENTRE> <EXPRSQLADICION> <MASEXPRSQLADICION> <CASO2CLAUSULASET> ::= <UNAELTOCASO2CLAUSULASET> <MASELTOCASO2CLAUSULASET> <MASELTOCASO2CLAUSULASET> ::= <VACIO> <MASELTOCASO2CLAUSULASET> ::= <COMA> <ELTONAME> <IGUAL> <CASO2CLAUSULASET> <UNAELTOCASO2CLAUSULASET> ::= <SENTENCIASELECT> <UNAELTOCASO2CLAUSULASET> ::= <EXPRSQL> <OPCWHERECLAUSULASET> ::= <VACIO> <OPCWHERECLAUSULASET> ::= where <RESTOOPCWHERECLAUSULASET> <RESTOOPCWHERECLAUSULASET> ::= current of <IDENTIFICADOR> <RESTOOPCWHERECLAUSULASET> ::= <EXPRSQL> <OPCFORTABLE> ::= <VACIO> <OPCFORTABLE> ::= for table <ELTONAME> <--------> <TIPODATOSQL> ::= serial <RESTO1DIM> <TIPODATOSQL> ::= text <RESTOTEXTBYTESQL> <TIPODATOSQL> ::= byte <RESTOTEXTBYTESQL> <TIPOADTOSQL> ::= <TIPOBASICO> <RESTOTEXTBYTESQL> ::= <VACIO> <RESTOTEXTBYTESQL> ::= in <RESTO2TEXTBYTESQL> <RESTO2TEXTBYTESQL> ::= table <RESTO2TEXTBYTESQL> ::= <IDENTIFICADOR> <NOMBREBD> ::= <VARIABLE> <NOMBREBD> ::= <CTE_CADENA>

49 <ELTOSNAME> ::= <ELTONAME> <MASELTOSNAME> <MASELTOSNAME> ::= <VACIO> <MASELTOSNAME> ::= <ELTONAME> <MASELTOSNAME> <ELTONAME> ::= <OPCDATABASE> <PROPIETARIOSQL> <IDENTIFICADOR> <ELTONAME> ::= <PROPIETARIOSQL> <IDENTIFICADOR> <PROPIETARIOSQL> ::= <VACIO> <PROPIETARIOSQL> ::= <CTE_CAD> <PTO> <ELTOSSEL> ::= <ELTOSEL> <MASELTOSSEL> <MASELTOSSEL> ::= <VACIO> <MASELTOSSEL> ::= <COMA> <ELTOSEL> <MASELTOSSEL> <ELTOSEL> ::= <ELTONAME> <PTO> <IDENTIFICADOR> <ELTOSEL> ::= <IDENTIFICADOR> <CLAUSULAVALUES> ::= values <PAR1> <ELTOSCLAUSULAVALUES> <PAR2> <ELTOSCLAUSULAVALUES> ::= <UNAELTOSCLAUSULAVALUES> <MASELTOSCLAUSULAVALUES> <MASELTOSCLAUSULAVALUES> ::= <VAIO> <MASELTOSCLAUSULAVALUES> ::= <COMA> <UNAELTOSCLAUSULAVALUES> <MASELTOSCLAUSULAVALUES> <UNAELTOSCLAUSULAVALUES> ::= null <UNAELTOSCLAUSULAVALUES> ::= <EXPRCONSTANTESQL> <UNAELTOSCLAUSULAVALUES> ::= <RECORDREFERENCE> <RESTOVBLECLAUSULAVALUES> <RESTOVBLECLAUSULAVALUES> ::= <VACIO> <RESTOVBLECLAUSULAVALUES> ::= <PTO> <ASTERISCO> <RESTOVBLECLAUSULAVALUES> ::= thru <RECORDREFERENCE> <REFERENCEDVALUES> ::= <RECORDREFERENCE> <RESTOREFEENCEDVALUES> <RESTOREFEENCEDVALUES> ::= <VACIO> <RESTOREFEENCEDVALUES> ::= thru <RECORDREFERENCE> <RESTOREFEENCEDVALUES> ::= <PTO> <ASTERISCO> <EXPRSCONSTANTESQL> ::= <EXPRCONSTANTESQL> <MASEXPRCONSTANTESQL> <MASEXPRCONSTANTESQL> ::= <VACIO> <MASEXPRCONSTANTESQL> ::= <COMA> <EXPRCONSTANTESQL> <MASEXPRCONSTANTESQL> <EXPRCONSTANTESQL> ::= <CTE_CAD> <EXPRCONSTANTESQL> ::= user <EXPRCONSTANTESQL> ::= <DECIMAL> <EXPRCONSTANTESQL> ::= today <EXPRCONSTANTESQL> ::= current <MASCTECURRENT> <MASCTECURRENT> ::= <VACIO> <MASCTECURRENT> ::= <DATETIMEQUALIFIER> <EXPRCONSTANTESQL> ::= <DATETIMELITERAL> <EXPRCONSTANTESQL> ::= <INTERVALLITERAL> <EXPRCOLUMN> ::= <OPCARROBA> <ELTONAME> <PTO> <RESTOEXPRCOLUMN> <RESTOEXPRCOLUMN> ::= <IDENTIFICADOR> <OPCDIM> <RESTOEXPRCOLUMN> ::= rowid <OPCARROBA> ::= <VACIO> <OPCARROBA> ::= arroba <OPCDIM> ::= <VACIO> <OPCDIM> ::= <COR1> <ENTERO> <COMA> <ENTERO> <COR2> <OPCIGUAL> ::= <VACIO> <OPCIGUAL> ::= igual <OPCALL> ::= <VACIO> <OPCALL> ::= all

50 <OPCAS> ::= <VACIO> <OPCAS> ::= as <OPCNOT> ::= <VACIO> <OPCNOT> ::= not <OPCNOTNULL> ::= <VACIO> <OPCNOTNULL> ::= not null <OPCFORTABLE> ::= <VACIO> <OPCFORTABLE> ::= for table <ELTONAME> <OPCMODEANSI> ::= <VACIO> <OPCMODEANSI> ::= mode ansi <OPCALLUNIQUEDISTICT> ::= <VACIO> <OPCALLUNIQUEDISTICT> ::= all <OPCALLUNIQUEDISTICT> ::= <UNIQUEDISTICT> <OPCUNIQUEDISTICT> ::= <VACIO> <OPCUNIQUEDISTICT> ::= <UNIQUEDISTICT> <UNIQUEDISTICT> ::= unique <UNIQUEDISTICT> ::= distinct <USINGINTO> ::= using <USINGINTO> ::= itno <OPCMASMENOS> ::= <VACIO> <OPCMASMENOS> ::= mas <OPCMASMENOS> ::= menos <SHAREEXCLUSIVE> ::= share <SHAREEXCLUSIVE> ::= exclusive <ONOFF> ::= on <ONOFF> ::= off <OPCCONSTRAINT> ::= <VACIO> <OPCCONSTRAINT> ::= constraint <ELTONAME> <OPCESCAPE> ::= <VACIO> <OPCESCAPE> ::= escape <CTE_CADENA> <OPCCLUSTER> ::= <VACIO> <OPCCLUSTER> ::= cluster <OPCPUBLICPRIVATE> ::= <VACIO> <OPCPUBLICPRIVATE> ::= public <OPCPUBLICPRIVATE> ::= private <OPCASCDESC> ::= <VACIO> <OPCASCDESC> ::= asc <OPCASCDESC> ::= desc <OPCWITHHOLD> ::= <VACIO> <OPCWITHHOLD> ::= with hold <OPCWITHREOPTIMIZATION> ::= <VACIO> <OPCWITHREOPTIMIZATION> ::= with reoptimization <OPCWITHNOLOG> ::= <VACIO> <OPCWITHNOLOG> ::= with no log

51 <OPCDELIMITER> ::= <VACIO> <OPCDELIMITER> ::= delimiter <STRINGOVBLE> <OPCCOLUMNS> ::= <VACIO> <OPCCOLUMNS> ::= <PAR1> <COLUMNS> <PAR2> <COLUMNS> ::= <ELTOCOLUMNS> <MASCOLUMNS> <MASCOLUMNS> ::= <VACIO> <MASCOLUMNS> ::= <COMA> <ELTOCOLUMNS> <MASCOLUMNS> <ELTOCOLUMNS> ::= <IDENTIFICADOR> <-----------> <EXPRSQL> ::= <EXPRSQLSQLCONDICIONALOR> <MASEXPRSQLSQLCONDICIONALOR> <MASEXPRSQLSQLCONDICIONALOR> ::= <VACIO> <MASEXPRSQLSQLCONDICIONALOR> ::= or <EXPRSQLSQLCONDICIONALOR> <MASEXPRSQLSQLCONDICIONALOR> <EXPRSQLSQLCONDICIONALOR> ::= <EXPRSQLSQLCONDICIONALAND> <MASEXPRSQLSQLCONDICIONALAND> <MASEXPRSQLSQLCONDICIONALAND> ::= <VACIO> <MASEXPRSQLSQLCONDICIONALAND> ::= and <EXPRSQLSQLCONDICIONALAND> <MASEXPRSQLSQLCONDICIONALAND> <EXPRSQLSQLCONDICIONALAND> ::= <EXPRSQLNOT> <MASEXPRSQLNOT> <MASEXPRSQLNOT> ::= <VACIO> <MASEXPRSQLNOT> ::= not <EXPRSQLNOT> <MASEXPRSQLNOT> <EXPRSQLNOT> ::= <EXPRSQLIS> <MASEXPRSQLIS> <MASEXPRSQLIS> ::= <VACIO> <MASEXPRSQLIS> ::= is null <MASESPRSQLIS> <MASEXPRSQLIS> ::= is not null <MASESPRSQLIS> <EXPRSQLIS> ::= <EXPRSQLBETWEEN> <MASEXPRSQLBETWEEN> <MASEXPRSQLBETWEEN> ::= <VACIO> <MASEXPRSQLBETWEEN> ::= between <EXPRSQL> and <EXPRSQL> <MASEXPRSQLBETWEEN> <EXPRSQLBETWEEN> ::= <EXPRSQLIN> <MASEXPRSQLIN> <MASEXPRSQLIN> ::= <VACIO> <MASEXPRSQLIN> ::= in <PAR1> <RESTOEXPRSQLIN> <PAR2> <MASEXPRSQLIN> <RESTOEXPRSQLIN> ::= <EXPRSCONSTANTESQL> <RESTOEXPRSQLIN> ::= <SENTENCIASELECT> <EXPRSQLIN> ::= <EXPRSQLSQLRELACION> <MASEXPRSQLSQLRELACION> <MASEXPRSQLRELACION> ::= <VACIO> <MASEXPRSQLRELACION> ::= compigual <EXPRSQLRELACION> <MASEXPRSQLRELACIOM> <MASEXPRSQLRELACION> ::= compdesigual <EXPRSQLRELACION> <MASEXPRSQLRELACION> <MASEXPRSQLRELACION> ::= menor <EXPRSQLRELACION> <MASEXPRSQLRELACION> <MASEXPRSQLRELACION> ::= mayor <EXPRSQLRELACION> <MASEXPRSQLRELACION> <MASEXPRSQLRELACION> ::= menorigual <EXPRSQLRELACION> <MASEXPRSQLRELACION> <MASEXPRSQLRELACION> ::= mayorigual <EXPRSQLRELACION> <MASEXPRSQLRELACION> <EXPRSQLRELACION> ::= <EXPRSQLLIKE> <MASEXPRSQLLIKE> <MASEXPRSQLLIKE> ::= <VACIO> <MASEXPRSQLLIKE> ::= like <STRINGOVBLE> <OPCESCAPE> <MASEXPRSQLLIKE> <MASEXPRSQLLIKE> ::= matches <STRINGOVBLE> <OPCESCAPE> <MASEXPRSQLLIKE> <EXPRSQLLIKE> ::= <EXPRSQLADICION> <MASEXPRSQLADICION> <MASEXPRSQLADICION> ::= <VACIO> <MASEXPRSQLADICION> ::= mas <EXPRSQLADICION> <MASEXPRSQLADICION> <MASEXPRSQLADICION> ::= menos <EXPRSQLADICION> <MASEXPRSQLADICION> <EXPRSQLADICION> ::= <EXPRSQLMULTIPLY> <MASEXPRSQLMULTIPLY> <MASEXPRSQLMULTIPLY> ::= <VACIO> <MASEXPRSQLMULTIPLY> ::= por <EXPRSQLMULTIPLY> <MASEXPRSQLMULTIPLY> <MASEXPRSQLMULTIPLY> ::= entre <EXPRSQLMULTIPLY> <MASEXPRSQLMULTIPLY> <EXPRSQLMULTIPLY> ::= <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= exist <PAR1> <SENTENCIASELECT> <PAR2> <EXPRSQLUNARIA> ::= any <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= all <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= some <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= not <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= mas <EXPRSQLUNARIA> <EXPRSQLUNARIA> ::= menos <EXPRSQLUNARIA>

52 <EXPRSQLUNARIA> ::= <EXPRSQLPRIMARIA> <EXPRSQLPRIMARIA> ::= <PARENTESIS1> <EXPRSQL> <PARENTESIS2> <EXPRSQLPRIMARIA> ::= <EXPRCOLUMN> <EXPRSQLPRIMARIA> ::= <EXPRCONSTANTESQL> <EXPRSQLPRIMARIA> ::= <EXPRSQLLLAMADAFUNCION> <EXPRSQLPRIMARIA> ::= <EXPRAGREGADA> <EXPRSQLPRIMARIA> ::= <VARIABLE> <---------> <IDENTIFICADOR> ::= identificador <CTE_CADENA> ::= cadena <AROBA> ::= arroba <VACIO> ::= vacio <FICHERO> ::= <CTE_CAD> <CTE_CAD> ::= <COMILLAS> cadenacar <COMILLAS> <COMILLAS> ::= comillas <GUION> ::= guion <LETRA> ::= letra <PTO> ::= pto <PAR1> ::= par1 <PAR2> ::= par2 <COMA> ::= coma <COR1> ::= cor1 <COR2> ::= cor2 <ASTERISCO> ::= asterisco <CONCAT> ::= barraverticaldoble El analizador sintctico implementa esta gramtica. La gramtica no es LL1 en todos los casos estas situaciones son resueltas durante la codificacin. Los casos que no cumplen LL1 son: y

Al hacer referencia al nombre de una elemento de una tabla. Esto se da en varias ocasiones dentro de la definicin sintctica: Dentro de la definicin de tipos de datos en: like <PROPIETARIO> <IDENTIFICADOR> <PTO> <IDENTIFICADOR> like <PROPIETARIO> <IDENTIFICADOR> <PTO> <ASTERISCO> <PROPIETARIO> <IDENTIFICADOR> <PTO> <ULTUNARESTOLIKEINITIALIZE> <PROPIETARIO> <IDENTIFICADOR> <PTO> <RESTOUNAVALIDATE>

Dentro de la sentencia INITIALIZE en: Dentro de la sentencia VALIDATE en: En todas las sentencias SQL al hacer referencia al nombre de una tabla o al campo de una tabla.

Todos estos casos no son ni siquiera LL3 ya que para determinar si se esta recuperando el nombre de una tabla o el propietario se debe leer tres tokens: un identificador, punto, e identificador y en funcin del siguiente (punto o vaci) y se podr saber que elemento se esta tratando. En las sentencias END, EXIT, OPEN, CLOSE y CONTINUE se ha tenido cuidado al definir las producciones de su definicin sintctica para evitar no fuese LL1. La nica sentencia que debe ser contemplada y tratada en el sintctico para evitar problemas es: END MAIN Sentencia IF. Se soluciona durante el sintctico y al generar cdigo de tal forma que se andale ELSE con el ultimo IF Dentro de la sentencia REPORT, paginas: en la seccin OUTPUT al tratar las dimensiones de las

<PAGEDIMENSION> ::= top of page <OPCIGUAL> <CTE_CAD>

53 <PAGEDIMENSION> ::= top margin <OPCIGUAL> <ENTERO> No es LL1 pero si LL2 tratado directamente por el analizador sintctico. Se dan otros casos, que son controlados dentro del sintctico/semntico, debido a la posibilidad de que ciertas palabras reservadas se puedan utilizar como identificadores.

SEMANTICA, TABLA DE SIMBOLOS, Y MANEJO DE ERRORES


Como se comento, al definir los componentes del traductor y, dado que partimos de ficheros fuente sintctica y semnticamente correctos se podra, errneamente, creer que estos elementos del traductor no son precisos. A lo largo de los diferentes puntos de sta seccin se proceder a estudiar estos componentes y durante ese proceso de ver con claridad la necesidad de los mismos.

ANALIZADOR SEMANTICO
El analizador semntico, como su nombre indica, permite aadir reglas semnticas al traductor. ste es preciso por muchas razones, a continuacin se detallan algunas de ellas: Permite controlar situaciones en las cuales la definicin sintctica no es LL1, como el caso de la sentencia END MAIN. Valores por defecto en la definicin de variables. En la definicin de las variables de Informix4GL y campos de la base de datos Informix permite cierta libertad como en el caso de los tipos de datos CHAR, DECIMAL, etc., en los cuales de forma opcional se pueden dejar sin especificar la dimensin de los mismos sin que esto implique ningn error sintctico. A la hora de traducir estas definiciones a JAVA no se plantea ningn problema ya que uno se pasar a String y el otro a Double BigDecimal y en ningn caso hay que indicar la dimensin. Si lo que se define es un campo de una tabla, dependiendo para qu gestor de bases de datos, puede ser preciso especificar la dimensin con lo cual ser preciso aplicar la semntica de Informix en el momento de la traduccin para aplicar los valores por defecto. Valores por defecto en sentencias SQL. Existen sentencias SQL en las que Informix permite omitir, a la hora de la utilizacin de las mismas, ciertas definiciones, tales como: FETCH [next], SELECT [all], ORDER BY [asc], etc. A la hora de generar cdigo de estas sentencias para otros gestores de bases de datos y con objeto de garantizar el correcto funcionamiento, sobre ellos, se aplica semntica y se aade la accin que por defecto que aplica Informix en el caso de que se omita esta en la declaracin de la sentencia. En la inicializacin de variables en el cdigo objeto generado. Aunque Informix no obliga a inicializar las variables antes de utilizarlas en el cdigo, JAVA si. Para determinar el valor a asignar se aplican reglas semnticas. El valor asignado depender del tipo de dato que se haya definido. En la asignacin de valores a variables. La sentencia LET de Informix permite asignar valores a variables de programa, en ciertos casos, a la hora de realizar la traduccin, esta no se puede hacer de forma directa debido a que la expresin resultante no es reconocida por JAVA. En estos casos se precisa hacer alguna conversin de la expresin original. Los casos ms destacados son los relativos al procesamiento de fechas, as una expresin que devuelve una fecha en Informix-4GL se le deben aplicar reglas semnticas para convertirla a formato JAVA (java.sql.Date o java.sql.Timestamp), Ej.: Codito fuente Informix-4GL: Cdigo objeto JAVA: let fecha = today fecha = new Date(new java.util.Date().getTime()) ;

Al tratar las expresiones 4GL. Al igual que ocurre con las expresiones SQL las operaciones sobre alguna expresin 4GL no siempre pueden ser traducidas directamente sin aplicar reglas semnticas de conversin o casting sobre algn operando, ya que aunque el lenguaje original (Informix) lo permita el final (JAVA) puede que no.

54 Tratamiento de las expresiones SQL. Si las expresiones que aparecen en el cdigo fuente se aplicasen sobre un gestor de bases de datos Informix no sera necesario hacer nada, pero como se pretende aplicarlas sobre otros gestores es preciso saber el tipo de dato de los operados para: Saber si la operacin es permitida por el gestor de bases de datos destino. Hay que hacer algn tipo de casting o conversin. Hay que redefinir la forma en que se aplica el operador.

As, por ejemplo, Informix permite realizar operaciones aritmticas sobre fechas (sumas y restas). Para el resto de gestores, si lo permiten, se necesita aplicar alguna regla semntica que permita definir la operacin de tal forma que sea valida para el gestor de bases de datos destino. Ej.: Cdigo fuente Informix-4GL: Cdigo objeto JAVA para SqlServer: '"+fecha+" '} ) from prueba1 "); select fecha - campo4 into dos from prueba1 executeQuery("select datediff(dd,campo4 ,{d

Otro caso es la interpretacin de los das de la semana ya que cada gestor de bases de datos y, dependiendo del lenguaje, puede utilizar su propia codificacin numrica para el da de la semana la cual puede no tener el mismo significado que la codificacin que realiza Informix. Por, al menos, las razones indicadas es preciso detectar, mantener, y propagar los tipos de datos de las constantes, variables y expresiones dentro del analizador con objeto de poder aplicar las reglas semnticas.

TABLA DE SIMBOLOS
En la tabla de smbolos se almacenan la informacin necesaria para poder aplicar las reglas semnticas durante el proceso de traduccin. La estructura de la tabla de smbolos es la de una tabla HASH donde el elemento clave es el nombre del identificador y el campo de informacin esta formado por una clase que contiene: Nombre, identificador del elemento. Tipo, contiene el tipo de dato del elemento. mbito. Indica el mbito del elemento. Los mbitos de las variables pueden ser: GLOBAL. Si la variable esta definida en el mdulo globals lo cual indica que puede ser referenciada desde cualquier el mdulo de los que conforman el programa multimdulo. MDULO. Solo puede ser referenciada desde el mdulo en el cual es declarada. LOCAL. Su mbito es solo el mtodo en el cual se declara.

A la hora de buscar un elemento en la tabla de smbolos primero se mira si esta definida en el mtodo actual, seguidamente si esta definida a nivel de mdulo y en caso de no ser as se comprueba si esta definida en la seccin globals Mdulo. Indica en que mdulo se defini el elemento. Como se indic en el semntico es preciso saber el tipo de dato del que son las variables definidas en el cdigo fuente y por aadidura es tambin el mbito ya que una variable con igual nombre de identificador puede estar definida en dos puntos del programa y ser de diferente tipo y/o mbito. Los valores se almacenan en la tabla de smbolos en el momento de su declaracin. Informix-4GL es bastante restrictivo en cuanto a los puntos en los cuales se pueden definir variables lo cual facilita el manejo de la tabla de smbolos. Solo se pueden definir variables en la seccin globals (mbito Global), al principio del programa antes de la sentencia MAIN (mbito mdulo) y dentro del MAIN y en las funciones y reports justo al principio de los mismos (mbito local). Las variables de mbito global o tipo mdulo se mantienen en la tabla de smbolos durante todo el proceso de

55 traduccin, del mdulo en curso, sin embargo las variables locales solo durante el trozo de cdigo en el que pueden ser utilizadas. La tabla de smbolos puede ser accedida dentro del analizador en cualquier momento siendo los puntos ms comunes en las operaciones sobre expresiones y a la hora de hacer asignaciones de valores a variables. No toda la informacin es mantenida en la tabla de smbolos, cuando es preciso saber el tipo de dato de un campo de una tabla de la base de datos puede ser preciso hacer una consulta directamente al gestor ya que se puede estar accediendo a una tabla que no fue creada en el mismo fichero que se esta procesando.

MANEJO DE ERRORES
El manejo de errores se utiliza dentro del proceso de traduccin para indicar al usuario aquellos warnings o errores que se pueden producir como consecuencia de la ejecucin del cdigo objeto generado. Si el cdigo generado va ser ejecutado sobre un gestor de bases de datos Informix no se contempla que se pueda producir ningn error ya que todas las sentencias ya han sido escritas para ser ejecutadas sobre el mismo. En cambio como se puede generar cdigo para ser ejecutado sobre otros gestores de bases de datos y no todas las sentencias SQL de Informix son totalmente compatibles con las que proporcionan estos se avisa de las limitaciones o problemas que pueden aparecer. Estos avisos estn orientados a indicarle al usuario que revise el cdigo objeto generado para que tome las acciones que considere oportunas. Algunos ejemplos de errores que se pueden mostrar son: Warning: Sentencia create audit no generada Warning: Sentencia PREPARE, revisar sintaxis SQL

Se han aadido mensajes adicionales para contemplar problemas en el cdigo fuente debido a algn error de sintaxis. Estos errores no se deberan producir ya que se parte de programas sintcticamente correctos.

GENERACIN DE CDIGO
El generador de cdigo se encarga de generar las sentencias JAVA correspondientes a cada sentencia 4GL que aparece en el cdigo fuente. El diseo del generador de cdigo tiene dos caractersticas relevantes: Fcilmente ampliable sin que para ello sea preciso modificar el resto de mdulos del traductor. Siguiendo la filosofa de PATRON ESTRATEGIA se han creado mdulos independientes y cada mdulo procesa las sentencias especficas asociadas a cada gestor de bases de datos. En funcin de para que gestor se este ejecutando el traductor instanciar uno u otro mdulo. Si a futuro se plantease la traduccin del cdigo fuente para un nuevo gestor de bases de datos sera suficiente con crear el mdulo que procese las sentencias SQL de dicho lenguaje. Utilizacin de buffers intermedios entre el generador de cdigo y el fichero de cdigo objeto generado. Dicho de otra forma la generacin de cdigo asociado a una sentencia se va haciendo por trozos no produciendo un resultado final sobre el fichero destino hasta que se haya procesado sta en su totalidad. Esta forma de operar del generador de cdigo permite una versatibilidad necesaria a la hora de generar cdigo objeto. Seguidamente se muestran un par de ejemplos, simplificados, con objeto de entender mejor el concepto:

EJEMPLO1: TRATAMIENTO DE EXPRESIONES


Cdigo fuente: select fecha - today from prueba1 Cdigo objeto: ResultSet ASG_r8 = ASG_st8.executeQuery("select datediff(dd,dateadd(dd,0, datediff(dd,0,getdate())) ,{d '"+ fecha +"'} ) from prueba1 ");

56 Pasos en la traduccin: Paso1: Se Inicializa buffer y elige el primero Paso2: Se guardar en el primer buffer: select Paso3: Pasar al buffer siguiente y almacenar: fecha Se determina que el operando es de tipo fecha Paso4: Se obtiene el tipo de operador Pasar al buffer siguiente y almacenar : today Se determina que es una constante tipo fecha Paso5: Se pasa al buffer siguiente y se almacena en l: from prueba1 Paso6: Se genera la sentencia objeto en funcin de la informacin guardada en los buffers. La generacin de cdigo resultante, en este caso para SqlServer, se basa en la sentencia original, dividida por secciones, y en la informacin sobre los operadores para generar una instruccin valida para el gestor de bases de datos destino. Como se puede ver el aplicar el operador sobre los operandos implica aadir cdigo especfico para el gestor de bases de datos SqlServer y reorganizar los operandos lo cual si fuese una traduccin lineal y directa no se podra hacer. Por otro lado, y como es de suponer, se aplican reglas semnticas para determinar los tipos de datos de los operandos y si el operador se puede aplicar sobre stos.

EJEMPLO 2: TRATAMIENTO DE CONSTRAINTS


Cdigo fuente: alter table tabla1 add constraint unique (campo1,campo2) constraint constr4 Cdigo objeto: ASGdb.exeUpdate("alter table tabla1 add constraint constr4 unique ( campo1 , campo2) ); Pasos en la traduccin: Paso1: Inicializar buffer y elegir el primero Paso2: Almacenar en buffer = alter table tabla1 add constraint Paso3: Pasar al buffer siguiente y almacenar = unique (campo1,campo2) Paso4: Coger el siguiente buffer y guardar en l = constr4 Paso5: Pasar la informacin de los bufferes al fichero que mantiene el cdigo objeto, para ello: Se enva a fichero buffer 1 Se comprueba si ha definido el nombre del constraint, en tal caso se enva a fichero el contenido del buffer 3 Se enva a fichero el contenido del buffer2 Este es un ejemplo simplificado y permite ejemplificar el tratamiento por partes de las sentencias a la hora de genera cdigo, el hacerlo as permite trasformar la sentencia llegando a reorganizar parte de la misma como ocurre en este caso con el nombre del constraint que en la sentencia original aparece al final y sin embargo en la generada en medio de la misma. Este sistema que se ha planteado para la generacin de cdigo tiene mltiples ventajas: Se desvincula la generacin de la sentencia objeto del procesamiento del fichero que contendr el cdigo objeto. Al final del tratamiento de una sentencia se tendr en un nico buffer la sentencia objeto completa siendo los mtodos diseados para el tratamiento del

57 fichero objeto los encargados de: pasar el contenido del buffer a disco, aplicar las indentaciones y saltos de lnea precisos y liberar los bufferes utilizados. Se aade un alto nivel de abstraccin y ocultacin ya que en punto de programa obtenemos el cdigo generado de los elementos de la sentencia sin tener que preocuparnos de cmo se obtienen estos.

TRATAMIENTO DE SENTENCIAS DE INFORMIX4GL

En este apartado se analizarn las sentencias de programa, y se indicar la solucin adoptada para pasar de cdigo fuente 4GL a objeto JAVA. El enfoque es diferente al que se hace para el tratamiento de las sentencias SQL ya que la traduccin de las sentencias 4GL ser siempre la misma independientemente del gestor de bases de datos. Las sentencias que se tratan en este proceso son: De definicin del mdulo principal de programa. De manejo de funciones. De control de flujo. De definicin y uso de variables. De definicin de mens.

SENTENCIAS DE DEFINICIN DEL MDULO PRINCIPAL DE PROGRAMA


Informix-4GL permite realizar programas monomdulo y multimdulo y aparte permite definir un mdulo especial de definicin de variables globales. Un programa monomdulo esta formado por un nico fichero de cdigo fuente, puede constar de los bloques indicados en la figura que se muestra a continuacin, y como mnimo contendr el bloque MAIN. Un programa multimdulo estar formado por varios ficheros de cdigo fuente. Entre ellos habr un nico fichero que contenga el bloque MAIN. El resto de los ficheros que forman parte del programa pueden estar formados por todas las secciones de un mdulo de programa a excepcin del bloque MAIN. La seccin GLOBALS permite definir variables globales a todos los mdulos. El cdigo asociado a esta seccin se puede definir en cada uno de los mdulos que tenga que acceder a las variables globales o bien en un mdulo independiente y ser referenciado desde esta seccin. El esquema bsico de un mdulo de programa se muestra en la siguiente figura:

58

SECCION DATABASE SECCION GLOBALS DEFINICION VARIABLES BLOQUE MAIN

FUNCIONES y REPORTS

Figura 6: Estructura bsica de un mdulo de programa Con la idea bsica de las secciones de un mdulo de programa, la posibilidad de que un programa puede estar constituido por ms de un mdulo y el valor aadido, que se quiere aportar en este proyecto, de proporcionar un interface grfico, estilo WINDOWS, a los programas generados, el estudio de la traduccin del mdulo principal de programa se enfoca desde dos puntos de vista: Generacin cdigo modo texto o modo grafico. Tratar programas monomdulo o multimdulo.

El mdulo MAIN es el nico que es obligatorio en un programa. En el momento de traducir esta seccin a cdigo objeto JAVA ya se est definiendo el mdulo principal del mismo lo que implica definir un programa con todas sus secciones: imports, definicin de clase principal, mtodo MAIN, extents, etc. A nivel esquemtico el bloque MAIN de un programa escrito en Informix-4GL tiene la estructura: MAIN <SENTENCIAS> END MAIN Con este simple cdigo se define el mdulo mnimo de programa principal. Pasar esta sentencia a cdigo objeto JAVA es ms complejo debido a que JAVA es un lenguaje orientado a objetos y es necesario definir una clase en la que crear los mtodos. A nivel esquemtico ser: <seccin imports> public class NOMBRE_CLASE <seccin extents> { <definiciones aadidas> public static void main(String argv[]) throws Exception { <sentencias aadidas> <SENTENCIAS> } }

59 Viendo esta traduccin, la cual no mantiene correspondencia entre las sentencias de cdigo fuente y sentencias de cdigo objeto, cabe aclarar varios puntos: La sentencia MAIN END MAIN se transforma en: public static void main(String argv[]) throws Exception {} Esta transformacin es lgica ya que es la forma en la que JAVA define el mtodo principal. Cabe destacar: Este mtodo se define con un argumento para la recepcin de los parmetros. Informix4GL aunque no defina ningn argumento en el MAIN si los puede recibir, utiliza para ellos funciones propias del lenguaje como: arg_val(). Se aade a la definicin del MAIN: throws Exception con objeto de indicar que aquellas excepciones que no se controlan se manden a consola. Informix-4GL viene preparado para el manejo de errores sobre todo en lo relacionado con el manejo de sentencias SQL pero como JAVA es mucho ms potente, en este aspecto, es preciso adaptar los programas generados al uso de excepciones.

La seccin imports que contiene las clases necesarios se aaden justo al principio. Los imports que podrn llegar a utilizarse sern conocidos de antemano y variarn dependiendo del tipo de programa que se este generando. Evidentemente, y al no poder controlar de antemano todas las situaciones y requerimientos del cdigo fuente, es probable que se importen clases que no se usen. Se define el nombre de la clase principal. El nombre de la clase coincidir con el nombre del fichero fuente (sin extensin) y ste mismo nombre tambin se utilizar para el fichero de cdigo objeto. Definicin de variables de mdulo. Puede ser necesario definir alguna variable esttica nueva y accesible desde cualquier parte del programa para mantener la equivalencia entre cdigo fuente y objeto. Un caso bastante claro es definir una variable que mantendr, durante todo el programa, la conexin con la base de datos. Se aaden llamadas a mtodos antes del inicio de las sentencias de programa. Al igual que la definicin de variables de tipo mdulo son mtodos aadidos que permiten la ejecucin de los programas generados. Los ms tpicos son los encargados de establecer la conexin con la bases de datos como: ASGcondb.cargaparamcon(), que se encarga de cargar en memoria los parmetros de conexin con la base de datos. ASGcondb = new AccesDB("datos") que establece la conexin con la base de datos.

GENERACIN DE CDIGO MODO TEXTO O GRFICO


A continuacin se muestra, con un ejemplo, las principales variantes a la hora de generar cdigo objeto JAVA dependiendo de si el programa final va o no a proporcionar interface grafico. En ambos casos se muestran los elementos bsicos y mnimos para generar un programa en JAVA equivalente a uno escrito en Informix-4GL. hola.4gl
main display "hola mundo" end main

Cuadro 1: Cdigo fuente mnimo de un programa Informix-4GL

60 hola.java
import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*; import import import import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*; javax.swing.*; java.awt.*; ASGgrafico.Console;

public class hola { static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGarea.append("hola mundo" +"\n"); }

public class hola extends JApplet { private static AccesDB ASGcondb = null; private static JTextArea ASGarea = new JTextArea(33,70); public static void main(String argv[]) throws Exception { Console.run(new hola(),800,600); } public void init() { Container ASGcp = getContentPane(); ASGcp.setLayout(new FlowLayout()); ASGarea.setEditable(false); ASGcp.add(new JScrollPane(ASGarea)); ASGarea.setText(""); try{ ASGmain(); } catch (Exception e ) {} } public void ASGmain () throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGarea.append("hola mundo" +"\n"); } }

Cuadro 2: Relacin entre cdigo objeto modo texto y modo grfico Observando la figura anterior, cuyo cdigo es el resultado de aplicar el traductor creado bien para generar cdigo texto o grfico, se pueden observar varias diferencias en el modo grafico respecto al modo texto: La clase principal extiende la clase JApplet. Se extiende sta y no otra debido a que los programas, grficos, generados estn pensados para poder ejecutarse como una aplicacin independiente o bien como un Applet desde un explorador Web. Se define una variable esttica ASGarea que ser el contenedor sobre el cual se muestren todos los elementos, grficos o no, de la aplicacin. El mtodo principal, main, solo tiene una instruccin que se encarga de llamar al mtodo run de la clase Console. La clase Console definida en el paquete ASGgrafico es la que permite que un mismo programa pueda se lanzado como aplicacin independiente o como un Applet. El mtodo init inicializa todos los elementos del entorno grfico inicial. El mtodo ASGmain es el equivalente al mtodo main de los programas diseados para ser ejecutados en modo texto y contendr todas las sentencias, del mdulo main, traducidas del programa original.

El resultado de la ejecucin del programa hola, tanto el original en Informix-4GL como los generados, a partir del traductor creado, se muestra en las siguientes figuras:

61

Figura 7: Ejecucin de la aplicacin hola.4gl sobre Informix

Figura 8: Resultado de la ejecucin del programa hola.java como aplicacin modo texto

62

Figura 9: Ejecucin del programa hola.java como aplicacin grfica

Figura 10: Ejecucin del programa hola.java como aplicacin Web

63

PROGRAMAS MULTIMDULO
Las principales diferencias, a la hora de aplicar el proceso de traduccin, multimdulo con respecto a los monomdulo, son: de un programa

Definicin de las variables aadidas en el proceso de traduccin. Las variables ASGcondb y ASGarea deben de estar accesibles desde cualquiera de los mdulos del programa con lo cual no pueden estar definidas en el mdulo MAIN (monomdulo). La solucin adoptada es definir este tipo de variables en un mdulo independiente y accesible desde todo aquellos que conforman el programa. Se crear un mdulo llamado: ASGglobals_<nombre_mdulo> con estas variables, de tipo esttico, garantizando as que mantengan el valor y la accesibilidad entre mdulos. El acceso a las mismas ser: Monomdulo. Multimdulo: ASGcondb.<mtodo> ASGglobal_<nombre_mdulo>.Asgcondb.<mtodo>

Acceso a mtodos definidos en otros mdulos. Para ello ser preciso indicar antes del nombre de mtodo el nombre de mdulo, Ej.: mdulo1.fx1 () en lugar de fx1(). Para poder saber el nombre del mdulo en el que esta definido un mtodo ser preciso aplicar un proceso previo que identifique en que mdulo est definida cada funcin. Habr que simular algo parecido a la definicin del makefile y el proceso make en Informix-4GL. makefile .SUFFIXES:
.4go .4gl .4gl.4go: @(echo 'Compilando $*' ; cd `dirname $<` ; fglpc $< ) PACTINV= mbuscom.4go\ mbuscoma.4go\ mcar.4go\ mcript.4go\ mdichlp.4go\ mf2.4go\ mfgl.4go\ mhelp.4go\ mimpre.4go\ uactinv.4go pactinv.4gi: $(PACTINV) makefile @echo 'Linkando pactinv.4gi' ; cat $(PACTINV) > pactinv.4gi

ASGmakefile
multi1= multi2.4gl multi3.4gl multi4.4gl multi5.4gl exe:multi1

multi21= multi11.4gl multi12.4gl multi13.4gl multi14.4gl exe:multi21

PCALPME=mblosem.4go\ mcalemp.4go\ mcar.4go\ mcript.4go\ mf2.4go\ mfgl.4go\ mhelp.4go\ mhlpte1.4go\ mlinque.4go\ mlispan.4go\ mlog.4go\ msanque.4go\ mbloext.4go\ mcalpme.4go\ ucalpme.4go\ pcalpme.4gi: $(PCALPME) makefile @echo 'Linkando pcalpme.4gi' ; cat $(PCALPME) > pcalpme.4gi

Cuadro 3: Makefile y ASGmakefile

64 Siguiendo el caso mostrado en el cuadro anterior, el cual mantiene una similitud con la forma en que Informix trata los programas multimdulo, por cada programa multimdulo JAVA que se quiere generar se han de aadir varias entradas al fichero ASGmakefile. Estas entradas son: Primero el nombre del mdulo principal del programa multimdulo seguido del smbolo igual (=). El mdulo principal es aquel que contiene el MAIN. Tantas lneas como mdulos que formen parte del programa excluyendo el mdulo principal. Y por ltimo el TAG "exe:" seguido del mdulo principal del programa. Este nombre ser el utilizado para crear el mdulo principal del programa JAVA.

Por cada mdulo 4GL se crear un mdulo JAVA. Se crear, tambin, un mdulo adicional que contenga las variables a las cuales se puede hacer referencia desde cualquiera de los mdulos del programa. El fichero ASGmakefile multimdulo. puede contener informacin relativa a mltiples programas

La nica restriccin que tienen todos los mdulos que forman parte de un programa multimdulo es que no puede haber ms de una funcin con el mismo nombre aunque sea en mdulos diferentes. Esto no causa ninguna pega en el proceso de traduccin ya que esta misma restriccin tambin la impone Informix-4GL. El proceso de traduccin de programas multimdulo sigue los siguientes pasos: Localiza, del fichero ASGmakefile, todos los mdulos de los que consta el programa y dentro de cada uno de estos todas las funciones. Las funciones son aadidas a la tabla de Smbolos. Recorre todos los mdulos indicados en el ASGmakefile y comprueba si es preciso aplicar el proceso de traduccin. Es preciso retraducir el mdulo si la fecha del fichero JAVA es anterior a la del fichero 4GL. Aplica el proceso de traduccin sobre los mdulos. El ltimo mdulo que se procesa es el que contiene el bloque MAIN.

El ltimo paso, para poder ejecutar el programa es compilar el mdulo principal (javac mdulo_ppal.java) y luego lanzar su ejecucin (java mdulo_ppal). Al compilar el mdulo principal sern automticamente compilados todos aquellos otros mdulos precisos (segn el comportamiento general de JAVA). En el siguiente cuadro se muestran un ejemplo completo de programa multimdulo tanto en cdigo fuente, Informix-4GL, como en cdigo objeto, JAVA, generado. Estos mdulos estn definidos en el fichero ASGmakefile anterior y corresponden al programa: multi1.

65

multi1.4gl
database datos define uno smallint main define uno smallint let uno = 1 message "En main: " , uno call fx(uno) call fx2(uno) message "En main tras vuelta funcion: " , uno end main function fx(dos) define dos smallint, tres integer let uno = 2 let tres = uno + dos; display "En funcion fx: " ,uno display "Parametro recibido fx: ",dos end function

multi1.java
import java.sql.*; import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class multi1 { static int uno ; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGglobal_multi1.ASGcondb = new AccesDB("datos"); ASGglobal_multi1.ASGcondb.HayTransac(); int uno ; uno = 0; uno = 1 ; System.out.println("En main: " + uno ); fx ( uno ) ; multi2.fx2 ( uno ) ; System.out.println("En main tras vuelta funcion: " + uno ); } static void fx(int dos) { int tres; uno = 2 ; tres = uno + dos ; System.out.println("En funcion fx: " + uno ); System.out.println("Parametro recibido fx: " + dos ); } }

Cuadro 4: Ejemplo mdulo principal de programa multimdulo multi2.4gl


function fx2(dos) define dos, bis smallint, bix2 char(20), tres, cuatro char(20) , cinco decimal(2,0) define dosbis integer let dosbis = 3 + fx3(dos) display "En funcion fx2: " ,dosbis display "Parametro recibido fx2: ",dos end function

multi2.java
import java.sql.*; import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class multi2 { static void fx2(int dos) { int bis; String bix2; String tres; String cuatro; double cinco; int dosbis ; dosbis = 3 + multi3.fx3 ( dos ) ; System.out.println("En funcion fx2: " + dosbis ); System.out.println("Parametro recibido fx2: " + dos ); } }

Cuadro 5: Ejemplo de mdulo de programa multimdulo

66

multi3.4gl
function fx3(tres) define tres smallint define tresbis integer let tresbis = 3; display "En funcion fx3: " ,tresbis display "Parametro recibido fx3: ",tres return tresbis end function

multi3.java
import java.sql.*; import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class multi3 { static int fx3(int tres) { int tresbis ; tresbis = 3 ; System.out.println("En funcion fx3: " + tresbis ); System.out.println("Parametro recibido fx3: " + tres ); return tresbis ; } }

Cuadro 6: Ejemplo de mdulo de programa multimdulo Adems de estos mdulos se crea un 4 mdulo con cdigo JAVA llamado: ASGglobal_multi1.java con el siguiente cdigo: import ASGdb.*; class ASGglobal_multi1 { static AccesDB ASGcondb = null; } Este mdulo contiene todas aquellas variables que pueden ser accedidas desde cualquiera de los mdulos de programa.

EL MDULO GLOBALS
A travs de la sentencia GLOBALS se pueden definir variables que son accesibles desde cualquiera de los mdulos que conforman el programa y tienen mbito global. Esta sentencia tiene dos posibles formas de definicin: explicita de las variables o bien hacer referencia a un mdulo (4GL) que contenga su definicin. A continuacin se muestra un ejemplo de cada una. Definicin explicita: globals define valid impre nimp end globals char(1), char(50), decimal(2,0)

Definicin haciendo referencia a un fichero: globals "globales.4gl" Donde el fichero tendr una sentencia GLOBALS utilizando la definicin explcita. La forma de traducir esta sentencia de tal forma que se garantice que la definicin de las variables es accesible desde cualquier mdulo del programa es a travs de otro mdulo el cual contenga la declaracin. Las variables dentro de este mdulo se definirn de tipo esttico consiguiendo as tengan el comportamiento de variables globales a todos los mdulos. A continuacin se muestran dos ejemplos de la traduccin de un programa Informix-4GL a JAVA. En el primero se utiliza la definicin explicita y en el segundo haciendo referencia a un fichero.

67

modglobal.4gl
database datos globals define uno, dos, tres integer, cuatro decimal(2,0) define cinco char(20) end globals define uno integer main define uno integer let uno = 1 let dos = 2 display "MAIN= Variable ambito mdulo(uno): ",uno call fx() call fx2(uno) end main function fx() let uno = 3 display "FX= Variable ambito mdulo(uno): ",uno display "FX= Variable ambito global(dos): ",dos end function function fx2(dos) define dos integer display "FX2= parametro(variable uno tipo mdulo; uno): ",dos display "FX2= valor de variable tipo mdulo(uno): ", uno end function import import import import

modglobal.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class modglobal { static int uno ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); uno = 0; uno = 1 ; ASGglobals_modglobal.dos = 2 ; System.out.println("MAIN= Variable ambito mdulo(uno): " + uno ); fx ( ) ; fx2 ( uno ) ; } static void fx() { uno = 3 ; System.out.println("FX= Variable ambito mdulo(uno): " + uno ); System.out.println("FX= Variable ambito global(dos): " + ASGglobals_modglobal.dos ); } static void fx2(int dos) { System.out.println("FX2= parametro(variable uno tipo mdulo; uno): " + dos ); System.out.println("FX2= valor de variable tipo mdulo(uno): " + uno );

ASGglobals_modglobal.java
class ASGglobals_modglobal{ static int uno , dos , tres; static double cuatro; static String cinco; }

Cuadro 7: Ejemplo de bloque de programa globals En este caso el nombre del mdulo se crea en funcin del nombre del mdulo MAIN con un prefijo: ASGglobals. El acceso a las variables globales en el cdigo objeto JAVA se hace utilizando como prefijo el nombre del mdulo en el cual estn definidas. Para determinar, en tiempo de traduccin, si se trata de una variable global o bien una tipo mdulo o local se utiliza la tabla de smbolos.

68

modglobal2.4gl
database datos globals globals.4gl define uno integer main define uno integer let uno = 1 let dos = 2 display "MAIN= Variable ambito mdulo(uno): ",uno call fx() call fx2(uno) end main function fx() let uno = 3 display "FX= Variable ambito mdulo(uno): ",uno display "FX= Variable ambito global(dos): ",dos end function function fx2(dos) define dos integer display "FX2= parametro(variable uno tipo mdulo; uno): ",dos display "FX2= valor de variable tipo mdulo(uno): ", uno end function import import import import

modglobal2.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class modglobal2 { static int uno ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); uno = 0; uno = 1 ; globals.dos = 2 ; System.out.println("MAIN= Variable ambito mdulo(uno): " + uno ); fx ( ) ; fx2 ( uno ) ; } static void fx() { uno = 3 ; System.out.println("FX= Variable ambito mdulo(uno): " + uno ); System.out.println("FX= Variable ambito global(dos): " + globals.dos ); } static void fx2(int dos) { System.out.println("FX2= parametro(variable uno tipo mdulo; uno): " + dos ); System.out.println("FX2= valor de variable tipo mdulo(uno): " + uno ); } }

globals.java
class globals{ static double cuatro; static String cinco; static int dos; static int uno; static int tres; }

Cuadro 8: Ejemplo mdulo de programa globals

En este caso como se hace referencia a un nombre de fichero de forma explicita se crear un mdulo JAVA que se nombre de igual forma que el mdulo original. En la seccin: mbito de variables, se explicar con ms detalle traduccin de este tipo de variables. la definicin, utilizacin y

En el caso de que se este utilizando la seccin globals con programas multimdulo se han de tener en cuenta varias cosas: Cada mdulo que quiera acceder a las variables globales debe indicarlo a travs de la sentencia GLOBALS, bien de forma explicita o travs de un fichero (implcita).

69 La seccin de memoria global es la misma para todos los mdulos. Esto quiere decir que si diferentes mdulos hacen referencia a una variable X todos estarn accediendo a la misma instancia de X. Si un mdulo no utiliza la sentencia GLOBALS no podr acceder al rea de memoria global aunque otro mdulo del mismo programa si tenga acceso.

Debido a que el rea de memoria al que se accede desde cada uno de los mdulos ha de ser la misma no se puede seguir el criterio de generacin de ficheros de variables globales indicado anteriormente, el cual es valido para programas monomdulo, ya que dos ficheros diferentes en JAVA harn referencia a variables diferentes. La solucin consiste en utilizar un nico mdulo que contenga las variables globales y este ser el mismo que se utiliza para guardar las variables globales creadas durante el proceso de traduccin: ASGglobal_<nombremdulo> multi12.4gl
database datos globals define dos, tres integer, cuatro decimal(2,0) define cinco char(20) end globals define uno smallint main define uno smallint let uno = 1 let dos = 2 let tres= 3 message "En main: " , message "En main: " , message "En main: " , call fx(uno) call fx2(uno) message "En main tras uno message "En main tras dos message "En main tras tres end main function fx(dos) define dos smallint, tres integer let uno = 2 let tres = uno + dos; display "En funcion fx: " ,uno display "Parametro recibido fx: ",dos end functionend function uno dos tres vuelta funcion: " , vuelta funcion: " , vuelta funcion: " , import import import import

multi12.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class multi12 { static int uno ; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGglobal_multi12.ASGcondb = new AccesDB("datos"); ASGglobal_multi12.ASGcondb.HayTransac(); int uno ; uno = 0; uno = 1 ; ASGglobal_multi12.dos = 2 ; ASGglobal_multi12.tres = 3 ; System.out.println("En main: " + uno ); System.out.println("En main: " + ASGglobal_multi12.dos ); System.out.println("En main: " + ASGglobal_multi12.tres ); fx ( uno ) ; multi22.fx2 ( uno ) ; System.out.println("En main tras vuelta funcion: " + uno ); System.out.println("En main tras vuelta funcion: " + ASGglobal_multi12.dos ); System.out.println("En main tras vuelta funcion: " + ASGglobal_multi12.tres ); } static void fx(int dos) { int tres; uno = 2 ; tres = uno + dos ; System.out.println("En funcion fx: " + uno ); System.out.println("Parametro recibido fx: " + dos ); }

70

multi22.4gl
globals "globals.4gl" function fx2(dos) define dos, bis smallint, bix2 char(20), tres, cuatro char(20) , cinco decimal(2,0) define dosbis integer let seis = 3 + fx3(dos); display "En funcion fx2: " , seis display "Parametro recibido fx2: ",dos end function import import import import

multi22.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class multi22 { static void fx2(int dos) { int bis; String bix2; String tres; String cuatro; double cinco; int dosbis ; ASGglobal_multi12.seis = 3 + multi32.fx3 ( dos ); System.out.println("En funcion fx2: " + ASGglobal_multi12.seis ); System.out.println("Parametro recibido fx2: " + dos ); } }

multi32.4gl
function fx3(tres) define tres smallint define tresbis integer let tresbis = 3; display "En funcion fx3: " ,tresbis display "Parametro recibido fx3: ",tres return tresbis end function import import import import

multi32.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class multi32 { static int fx3(int tres) { int tresbis ; tresbis = 3 ; System.out.println("En funcion fx3: " + tresbis ); System.out.println("Parametro recibido fx3: " + tres ); return tresbis ; } }

ASGmakefile
multi1= multi2.4gl multi3.4gl exe:multi1 multi12= multi22.4gl multi32.4gl exe:multi12

ASGglobal_multi12.java
import ASGdb.*; class ASGglobal_multi12{ static AccesDB ASGcondb = null; static int dos; static int tres; static int uno; static int seis; static double cuatro; static String cinco; }

Cuadro 9: Programa multimdulo completo con seccin globals

SENTENCIAS DE MANEJO DE FUNCIONES


Las sentencias de manejo de funciones son: Sentencias de definicin de funcin.

71 Sentencia de llamada a funcin. Dentro de estas hay dos mtodos de realizar la llamada: Sentencia CALL Dentro de una sentencia o expresin (LET, etc.)

SENTENCIA DE DEFINICIN DE FUNCIONES


Esta sentencia tiene la siguiente estructura en Informix-4GL: FUNCTION <nombre_funcion> (<parmetros>) DECLARACION DE ARGUMENTOS DECLARACION DE VARIABLES DE LA FUNCION <SENTENCIAS> END FUNCTION Donde, cabe destacar: La lista de argumentos solo contiene el nombre de estos. Los el tipo de datos de los argumentos se definen dentro del cuerpo de la funcin, como primera sentencia de la misma, utilizando la sentencia DEFINE. La funcin puede retornar ms de un valor utilizando para ello la sentencia RETURN. private static <valor_retorno> <nombre_fundion> (<parmetros_con_tipo> ) { <DECLARACION DE VARIABLES DE LA FUNCION> <SENTENCIAS> } La principal diferencia con el cdigo original es el hecho de que para JAVA los parmetros de las funciones se definen como: tipo identificador a diferencia de Informix-4GL que es una lista de identificadores y dentro del cdigo de la funcin ha de haber una sentencia DEFINE para declarar los parmetros de la misma. Para poder generar el cdigo de la definicin de la funcin en JAVA ser, por tanto, preciso procesar el cdigo fuente hasta la sentencia DEFINE previamente por parte del analizador sintctico. Otro tema a considerar es como definir los mtodos en JAVA: static o tipo class. En este punto se podra hacer mucha discusiones filosficas sobre las ventaja o inconvenientes de cada forma, pero por: sencillez, semejanza con respecto al cdigo original, y para evitar problemas con el cdigo generado, como en el caso de intentar acceder desde un mtodo esttico a otro que no lo es (Ej.: main), se utilizarn mtodos estticos. En el siguiente cuadro se muestra un ejemplo:

Este cdigo se transformar en una sentencia JAVA como la que sigue:

72

funcion1.4gl
database datos define uno smallint main define uno smallint let uno = 1 message "En main: " , uno call fx(uno) message "En main tras vuelta funcion: " , uno end main function fx(dos) define dos smallint, tres integer let tres = uno + dos; display "En funcion fx: " ,uno display "Parametro recibido fx: ",dos end function

import java.sql.*; import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class funcion1 { private static AccesDB ASGdb = null; static short uno ; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGdb = new AccesDB("datos"); ASGdb.HayTransac(); short uno ; uno = 0; uno = 1 ; System.out.println("En main: " + uno ); fx ( uno ) ; System.out.println("En main tras vuelta funcion: " + uno ); } static void fx(short dos) { int tres; tres = uno + dos ; System.out.println("En funcion fx: " + uno ); System.out.println("Parametro recibido fx: " + dos ); } }

funcion1.java

Cuadro 10: Ejemplo de definicin de funciones

En caso de que la funcin retorne algn valor la ltima instruccin de la definicin de la misma ser la sentencia RETURN la cual tiene una traduccin directa a JAVA. Un problema que se encuentra al traducir la sentencia FUNCTION es que en caso de que esta devuelva un valor no se sabr el tipo de dato hasta procesar la sentencia RETURN del cdigo fuente y este ya se debe pasar en la definicin de la misma al generar el cdigo objeto. static int funcion ( Para solventar esta situacin se ha de aplicar semntica, que nos permita determinar el valor de retorno y, por otro lado, aprovechar las caractersticas del diseo del generador de cdigo las cuales nos permiten almacenar sentencias en bufferes intermedios antes de pasarlas al fichero objeto final. As una funcin con valores de retorno ser procesada como sigue: Paso1: Inicializar buffer y elegir el primero Paso2: Almacenar en buffer = <nombre_de_funcion> Paso3: Pasar al buffer siguiente y almacenar = <argumentos> Paso4: Coger el siguiente buffer y guardar en l = <sentencias> Paso5: Procesar sentencia RETURN: almacenar el tipo de valor de retorno y guardar en buffer el identificador del valor a devolver. Paso6: Pasar la informacin de los bufferes al fichero que mantiene el cdigo objeto, para ello: Se enva a fichero, tomando la informacin del buffer1, buffer2 retorno: y el tipo de

private static <tipo_retorno> <nombre_funcion> (<argumentos_con_tipo>) {

73 Se envan a fichero las sentencias que forman el cuerpo e la funcin, incluida la sentencia RETURN Se enva a fichero la llave de cierre de funcin.

En el siguiente cuadro de cdigo se muestra un ejemplo de llamada a funcin desde una expresin y con valores de retorno de la misma. funcion2.4gl
define uno smallint main define uno smallint let uno = 1 message "En main: " , uno let uno = fx1(uno) message "valor devuelte por funcion fx2: " , uno end main function fx1(dos) define dos smallint, tres integer let tres = uno + dos; display "En funcion fx: " ,uno display "Parametro recibido fx: ",dos return tres end function

import java.sql.*; import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class funcion2 { private static AccesDB ASGdb = null; static int uno ; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGdb = new AccesDB("datos"); ASGdb.HayTransac(); int uno ; uno = 0; uno = 1 ; System.out.println("En main: " + uno ); uno = fx1 ( uno ) ; System.out.println("valor devuelte por funcion fx2: " + uno ); } static int fx1(int dos) { int tres; tres = uno + dos ; System.out.println("En funcion fx: " + uno ); System.out.println("Parametro recibido fx: " + dos ); return tres ; } }

funcion2.java

Cuadro 11: Ejemplo de funcin con valores de retorno Si se esta procesando un programa multimdulo la llamada a las funciones definidas en otro mdulo se realizar: NombreMdulo.metodo ( ...)

SENTENCIAS DE LLAMADA A FUCION


Una funcin puede ser llamada utilizando la sentencia CALL o bien formando parte de una expresin. Esquemticamente la sentencia CALL es: CALL <nombre_funcion> ( <lista_id_parametros>) [ RETURNING <lista_id> ] Y se transformar en una sentencia JAVA con la siguiente estructura: [<metodo> . ] <nombre_funcion> (<lista_parametros> ) Un ejemplo del uso de esta sentencia se puede ver en el cuadro anterior: Ejemplo de definicin de funciones. Si la llamada a funcin se encuentra embebida en una expresin la sintaxis original es:

74 <nombre_funcion> ( <lista_id_parametros>) Y se transformar en una sentencia JAVA con la siguiente estructura: [<metodo> . ] <nombre_funcion> (<lista_parametros> ) Como se ve la transformacin en cdigo JAVA ser la misma. La utilizacin de estas dos formas de llamada a funcin se ejemplifica en los cuadros anteriores. Dentro del manejo de funciones se ha limitado, la operativa del traductor, a permitir retornar solo un valor simple.

SENTENCIAS DE CONTROL DEL FLUJO


Como cualquier lenguaje de programacin procedural Informix-4GL contempla un grupo de sentencias de control de flujo de programa. Las sentencias definidas por Informix-4GL son: case, continue, exit, for, foreach, if-else, y while.

SENTENCIA CASE
La sentencia CASE permite especificar bloques de cdigo que son ejecutados condicionalmente, dependiendo del valor de una expresin. A diferencia de la sentencia IF, la sentencia CASE no limita el flujo lgico del programa a slo dos opciones. Esta sentencia tiene dos variantes: Criterio de seleccin simple. S la clusula: CASE (expresin) precede el primer bloque WHEN. Una expresin: INTEGER, SMALLINT, DECIMAL, CHAR(1), o VARCHAR(1) debe de seguir cada palabra WHEN. Si la expresin del WHEN casa con el valor de la expresin del CASE se ejecuta el bloque de sentencias y se sale de la sentencia CASE. Esquemticamente: case ( expresion) when <expresion1> <sentencias> when <expresion2> <sentencias> otherwise <sentencias_default> end case Criterio de seleccin mltiple. En caso de que ninguna expresin sigue la palabra CASE. Informix-4GL trata las expresiones de cada bloque WHEN como expresiones booleanas. Si una expresin del WHEN es evaluada como TRUE se ejecuta el bloque de sentencias correspondiente. Si ms de una clusula WHEN satisface la condicin slo la primera provoca se ejecute el bloque de sentencias asociado a la misma. case when <condicion_bool1> <sentencias> when <condicion_bool2> <sentencias> otherwise <sentencias_default> end case La traduccin de la sentencia CASE a JAVA se har de forma diferente en funcin del criterio de seleccin utilizado en la sentencia CASE. La forma de traducir la sentencia de CASE cuando se usa el criterio de seleccin simple ser utilizando la sentencia SWITCH de JAVA, como se ejemplifica a continuacin: switch ( expresion) { case <expresion1> : <sentencias> break; case <expresion2> : <sentencias> break; otherwise : <sentencias_default> break; }

75 Si la sentencia CASE original utiliza el criterio de seleccin mltiple la traduccin a JAVA se realiza utilizando sentencias IF-ELSE encadenadas como se ejemplifica a continuacin: if ( condicion_bool1) { <sentencias> } else if ( condicion_bool2) { <sentencias> } else { [ <sentencias_default> ] }

SENTENCIA CONTINUE
Esta sentencia transfiere el control de ejecucin a la siguiente sentencia al grupo de sentencias que constituyen el bloque. Esta sentencia puede utilizarse dentro de las sentencias: CONSTRUCT, FOR, FOREACH, INPUT, MENU, y WHILE. Su sintaxis es: continue [ construct | for | foreach | input | menu | while ] La traduccin a JAVA, para el caso de las sentencias: FOR, FOREACH, y WHILE es directa solo ser necesario eliminar la palabra reservada que va detrs del CONTINUE, quedando: continue; En caso de que se este tratando una sentencia men la sentencia CONTINUE significa que desde el punto en que aparece hasta el final del grupo de sentencias que se ejecutan, cuando se selecciona la opcin de men, son ignoradas. A la hora de traducir este caso se ignorarn dichas sentencias. Ejemplo: Cdigo fuente: command "Continue menu" "Ejemplo de continue menu" clear screen display "Ejemplo continue menu" continue menu call ejemplowhile() Cdigo objeto: ASGmenu.add("Continue menu" , "Ejemplo de continue menu" ); ASGmenu.getItem("Continue menu").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo continue menu" +"\n"); } } ); Aunque an no se haya explicado el tratamiento de la sentencia men observando el ejemplo se puede ver que no se ha traducido la sentencia que aparece justo detrs del CONTINUE en el cdigo fuente.

SENTENCIA EXIT
Esta sentencia transfiere el control del flujo del programa fuera de bloque de programa actual o del propio programa.

76 Esta sentencia tiene dos posibles variantes y cada una de ellas trae consigo una traduccin diferente. Finalizacin del programa actual. exit program [ <codigo_salida> ] exit main exit menu System.exit (<codigo_salida>); System.exit (0); System.exit (0);

Finalizacin del bloque de programa actual. Sintaxis original: exit [ case | construct | display | for | foreach | input | report | while ] Traduccin: break;

SENTENCIA FOR
Permite ejecutar un bloque de sentencias de programa un nmero de veces. La sintaxis original es: for <contador> = <valor_incial> to <valor_final> [step <inc>] <sentencias> end for Para traducir esta sentencia a JAVA se utiliza la sentencia FOR definida por JAVA adaptando para ello la sentencia original a la sintaxis de JAVA, la cual es: for ( <contador> = <valor_inicial> ; <contador> <= <valor_vinal> ; contador += <inc> ) { <sentencias> } Se ha de tener en cuenta a la hora de traducir esta sentencia: Si la clusula STEP se omite se entiende que el valor de incremento es 1. En caso de que el valor de <inc> sea negativo se tratara de un contador descendente con lo que el operador de comparacin ser >= en lugar de <=.

SENTENCIA FOREACH
Esta sentencia de control de flujo de programa no es propia de un lenguaje procedimental, es aadida por Informix-4GL y tienen el objetivo de recorrer todos los elementos de un cursor. Esquemticamente la sintaxis de esta sentencia es: foreach c1 into <lista_de_variables> <sentencias> end foreach Donde c1 es un cursor creado a travs de la sentencia: DECLARE CURSOR, tal como: declare c1 cursor for select * from tabla La forma de traducir esta sentencia es utilizando la sentencia WHILE de JAVA que permite aportar el mismo significado que la sentencia original: recorrer todas las filas resultado de una consulta a la base de datos. De forma genrica el cdigo generado ser: while ( ASG_rsp_c1.next() ) try { <sentencias de recuperacion de lista_de_variables> <sentencias> } catch (SQLException e) {}

77 ASG_rsp_c1.close(); Donde ASG_rsp_c1 es una variable tipo ResultSet declarada de la siguiente forma: ResultSet ASG_rsp_c1 = ASG_sp_c1.executeQuery("select * from tabla"); La lista de variables que aparece en la sentencia original de Informix-4GL se procesa dentro de la sentencia WHILE del cdigo JAVA, justo al principio de la misma, y estar formada por sentencias del tipo: vble1 = ASG_rsp_c1.getXXX(1); vble2 = ASG_rsp_c1.getXXX(2); vbleN = ASG_rsp_c1.getXXX(N); El nmero de sentencias depender del nmero de elementos de la lista de variables que constituyen la sentencia original. El tipo de mtodo de recuperacin de datos depender del tipo de variable en la que se espera recepcionar dicho dato.

SENTENCIA IF-ELSE
Est sentencia permite ejecutar un grupo u otro de sentencias de forma condicional. La sintaxis de Informix-4GL es muy similar a la de JAVA lo que facilita su traduccin. De forma esquemtica es: if <expresin_boolena> then <sentencias> else <sentencias> end if De forma general la traduccin a JAVA ser: if ( <expresin_booleana> ) { <sentencias> } else { <sentencias> }

SENTENCIA WHILE
Esta sentencia permite ejecutar un bloque de sentencias mientras la condicin, especificada a travs de una expresin booleana, se cumpla. De forma esquemtica su sintaxis es: while <expresin_boolena> <sentencias> end while La traduccin a JAVA se har pasando la estructura anterior a la propia del lenguaje, que es: while (<expresin_boolena> ) { <sentencias> } A continuacin se muestra un ejemplo de la utilizacin de todas las sentencias de control de flujo a excepcin de la sentencia FOREACH el cual se muestra dentro del tratamiento de las sentencias SQL en el apartado: Sentencias de control de flujo.

78

sentctrlflujo.4gl
main define opc integer while true display "Opciones: " display "1.- Ejemplo for" display "2.- Ejemplo for con CONTINUE y EXIT" display "3.- Ejemplo while" display "Opcion: " input by name opc case opc when 1 display "Ejemplo de sentencia for" call ejemplofor() when 2 display "Ejemplo de sentencia for con CONTINUE y EXIT" call ejemploforc() when 3 display "Ejemplo de sentencia while" call ejemplowhile() otherwise display "Fin de programa" exit program end case end while

import import import import

sentctrlflujo.java
java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

end main
function ejemplofor () define i integer for i = 0 to 100 display "nmero iteracion: ",i end for for i = 100 to 0 step -1 display "nmero iteracion: ",i end for end function function ejemploforc () define i integer display "CONTINUE en 10, EXIT en 20" for i = 0 to 100 if i = 10 then continue for else if i = 20 then exit for end if end if display "nmero iteracion: ",i end for for i = 100 to 0 step -1 if i = 80 then exit for end if if i = 90 then continue for end if display "nmero iteracion: ",i end for end function

public class sentctrlflujo { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int opc ; opc = 0; while ( true ) { System.out.println("Opciones: " ); System.out.println("1.- Ejemplo for" ); System.out.println("2.- Ejemplo for con CONTINUE y EXIT" ); System.out.println("3.- Ejemplo while" ); System.out.println("Opcion: " ); opc = System.in.read() -48; System.in.read(); System.in.read(); switch ( opc ) { case 1 : System.out.println("Ejemplo de sentencia for" ); ejemplofor ( ) ; break; case 2 : System.out.println("Ejemplo de sentencia for con CONTINUE y EXIT" ); ejemploforc ( ) ; break; case 3 : System.out.println("Ejemplo de ejemplowhile ( ) ; break; default : System.out.println("Fin de System.exit(0); break;

sentencia while" );

programa" ); }

+ i );

static void ejemplofor() { int i ; for(i = 0 ;i <= 100 ;i += 1) { System.out.println("nmero iteracion: " } for(i = 100 ;i >= 0 ;i += - 1 ) { System.out.println("nmero iteracion: " } }

+ i );

79

function ejemplowhile() define i integer let i = 0 while true let i = i + 1 if i == 10 then continue while end if display "Valor de interacion: ", i if i == 20 then exit while end if end while end function

static void ejemploforc() { int i ; System.out.println("CONTINUE en 10+ EXIT en 20" ); for(i = 0 ;i <= 100 ;i += 1) { if ( i == 10 ) { continue; } else { if ( i == 20 ) { break; } } System.out.println("nmero iteracion: " + i ); } for(i = 100 ;i >= 0 ;i += - 1 ) { if ( i == 80 ) { break; } if ( i == 90 ) { continue; } System.out.println("nmero iteracion: " + i ); } } static void ejemplowhile() { int i ; i=0; while ( true ) { i=i+1; if ( i == 10 ) { continue; } System.out.println("Valor de interacion: " + i if ( i == 20 ) { break; }

);

Cuadro 12: Sentencias de control de flujo

SENTENCIA DE DEFINICIN DE MENS


Una sentencia MENU proporciona una estructura en la cual situar sentencias que realizan acciones descritas a travs del nombre de la opcin de men. Esquemticamente una sentencia men se define en Informix-4GL como: Menu nombre menu Command opcin de menu [ ayuda opcin de menu] <sentencias> [continue menu]

80 [next option opcin de menu] [exit menu] Command opcin de menu [ayuda opcin de mnu] <sentencias> End menu Esta sentencia se traduce a JAVA como la creacin de un men al estilo Windows y con tantos submens, que aparecen al desplegarlo, como clusulas COMMAND aparecen en el cuerpo de la sentencia. Todas las sentencias que aparecen dentro del cuerpo de cada opcin de men, COMMAND, se colocarn, a la hora de generar cdigo objeto, en el cuerpo del listener asociado al elemento de men creado. As por cada sentencia COMMAND como la que sigue: command "Ejemplo1" "Ejemplo sentencia for" clear screen display "Ejemplo de sentencia for" call ejemplofor() Se transforma en un sentencia JAVA tal como: <JMenuItem>.add("Ejemplo1" , "Ejemplo sentencia for" ); <JMenuItem>.addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo de sentencia for" +"\n"); ejemplofor ( ) ;

} );

Como se muestra en el caso anterior por cada opcin de men de Informix-4GL se crea una Item de men JAVA y se aade un listener a ste. Dentro de las sentencias que pueden ir asociada a cada opcin de men hay destacar: Continue menu. Se encarga de saltar la ejecucin que hay desde el punto en que aparece hasta el final de la opcin de men. Ej.: command "Continue menu" "Ejemplo de continue menu" clear screen display "Ejemplo continue menu" continue menu call ejemplowhile() En este caso la llamada a la funcin ejemplowhile() no se producir. La traduccin lgica a JAVA del comando CONTINUE MENU sera con la sentencia RETURN, pero esto producira un error al compilar el programa JAVA ya que la llamada a la funcin no es alcanzada. Para evitar este error de compilacin lo que se har ser omitir la traduccin de toda sentencia que haya a continuacin del CONTINUE MENU omitiendo la generacin de cdigo objeto asociado a las mismas. Exit menu. Finaliza la ejecucin del men y por consiguiente del programa. La traduccin a JAVA ser utilizando la sentencia: Sytem.exit(0);

81 Next option. Esta subsentencia del MENU permite indicar que opcin del men quedar seleccionada despus de ejecutar esta. En el estilo Windows de mens no tiene sentido la traduccin de esta opcin.

Esta sentencia solo es procesada si se est generando cdigo objeto para un entorno grfico. A continuacin se muestra un ejemplo de un programa conteniendo la sentencia men: sentmenu.4gl
main define opc integer menu "Opciones" command "Ejemplo1" "Ejemplo sentencia for" clear screen display "Ejemplo de sentencia for" call ejemplofor() command key(J) "eJemplo2" "Ejemplo for con CONTINUE y EXIT" clear screen display "Ejemplo de sentencia for con CONTINUE y EXIT" call ejemploforc() command key(W) "ejemplo While" "Ejemplo de sentencia While" clear screen display "Ejemplo de sentencia while" call ejemplowhile() command "Continue menu" "Ejemplo de continue menu" clear screen display "Ejemplo continue menu" continue menu call ejemplowhile() command "Salir" "Abandonar el programa" exit menu end menu

import import import import import import import import

sentmenu.java

java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*; javax.swing.*; java.awt.*; ASGgrafico.*; java.awt.event.*;

public class sentmenu extends JApplet { private static AccesDB ASGcondb = null; private static JTextArea ASGarea = new JTextArea(33,70); static ASGMenu ASGmenu; public static void main(String argv[]) throws Exception { Console.run(new sentmenu(),800,600); } public void init() { Container ASGcp = getContentPane(); ASGcp.setLayout(new FlowLayout()); ASGarea.setEditable(false); ASGcp.add(new JScrollPane(ASGarea)); ASGarea.setText(""); try{ ASGmain(); } catch (Exception e ) {} } public void ASGmain () throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int opc ; opc = 0; ASGmenu = new ASGMenu("Opciones" ); ASGmenu.add("Ejemplo1" , "Ejemplo sentencia for" );

82

ASGmenu.getItem("Ejemplo1").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo de sentencia for" +"\n"); ejemplofor ( ) ;

sentmenu.java (2)

} } ); ASGmenu.add('j' , "eJemplo2" , "Ejemplo for con CONTINUE y EXIT" ); ASGmenu.getItem("eJemplo2").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo de sentencia for con CONTINUE y ejemploforc ( ) ;

EXIT" +"\n") ; }

} ); ASGmenu.add('w' , "ejemplo While" , "Ejemplo de sentencia While" ); ASGmenu.getItem("ejemplo While").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo de sentencia while" +"\n"); ejemplowhile ( ) ;

} } ); ASGmenu.add("Continue menu" , "Ejemplo de continue menu" ); ASGmenu.getItem("Continue menu").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { ASGarea.setText(""); ASGarea.append("Ejemplo continue menu" +"\n");

} } ); ASGmenu.add("Salir" , "Abandonar el programa" ); ASGmenu.getItem("Salir").addActionListener( new ActionListener () { public void actionPerformed(ActionEvent e) { System.exit(0); } } ); setJMenuBar(ASGmenu.get());

Cuadro 13: Ejemplo sentencias men

83 El programa resultante de la ejecucin de los ejemplos anteriores tanto l fuente de Informix-4GL como l objeto en JAVA se muestra en las siguientes figuras:

Figura 11: Resultado de ejecucin de un programa con men en Informix

Figura 12: Resultado de ejecucin de un programa con men en Java

SENTENCIAS DE DECLARACIN Y UTILIZACIN DE VARIABLES


La sentencia de declaracin de variables que proporciona Informix-4GL es DEFINE, la cual tiene la siguiente estructura: define <lista de identificadores> <tipo de dato> [ , <lista de identificadores> <tipo de dato> ] [, .. n] Dentro de una sentencia DEFINE se pueden declarar ms de una variable y de ms de un tipo de datos. En un bloque de declaracin de variables puede haber ms de una sentencia DEFINE. Dentro de un programa Informix-4GL se puede declarar variables en tres puntos:

84 Al principio del mismo dentro del bloque GLOBALS. Despus de la sentencia GLOBALS y antes del bloque MAIN. Dentro de los bloques de programa: MAIN, FUNCTION y REPORT justo al principio de los mismos antes de cualquier otra sentencia de programa.

JAVA es mucho ms libre en cuanto los puntos de programa en los cuales se pueden definir variables, esto aporta sencillez en este aspecto de la traduccin. Esquemticamente su sintaxis es: <tipo de dato> <lista de identificadores> ; La traduccin de esta sentencia tiene varias peculiaridades: Por cada tupla <lista de identificadores> <tipo de dato> de la sentencia original se genera una sentencia (lnea) distinta de cdigo objeto. Ejemplo: Cdigo fuente: define uno, dos, tres integer, cuatro cinco char(1) define seis, siete double Cdigo objeto: integer uno, dos, tres; String cuatro, cinco; double seis, siete; En la sentencia objeto el tipo de dato se sita antes de los identificadores, esto se puede implementar gracias a las caractersticas del generador de cdigo que permite almacenar en bufferes intermedios partes de la sentencia a generar y luego procesar estos. En este caso se tendr en un buffer el tipo de dato y otro las variables a definir y se mandaran al fichero objeto en el orden adecuado. Otro tema a considerar es el tipo de dato JAVA a utilizar en funcin del tipo de dato Informix4GL del cdigo fuente. Para ello se utiliza la siguiente tabla: Tipo de dato Informix-4GL CHAR, CHARACTER VARCHAR TEXT NUMERIC | DECIMAL | DEC SMALLINT INTEGER | INT REAL | SMALLFLOAT FLOAT | DOUBLE BYTE DATE TIMESTAMP String String String java.math.BigDecimal | double short int float double byte[] java.sql.Date java.sql.Timestamp Tipo de dato Java

Tabla 8: Mapeo entre tipos de datos Informix-4GL y JAVA

85

UTILIZACIN DE VARIABLES
Informix-4GL recomienda la inicializacin de las variables antes de su uso aunque no obliga a ello. JAVA por el contrario si obliga a inicializar las variables antes de su utilizacin. Dentro del proceso de traduccin y justo a continuacin de las sentencias de declaracin de variables se aadir un cdigo para la inicializacin de las mismas evitando as problemas a la hora de compilar el programa JAVA generado. El criterio que se seguir, para inicializar variables en funcin del tipo de dato, se muestra en la siguiente tabla: Tipo de dato JAVA String Short, int Flota, double Date, Timestamp Byte Bigdecimal Valor inicial (espacio en blanco) 0 0,0 null null null

Tabla 9: Valor de inicializacin de variables Para la asignacin de valores a una variable Informix-4GL utiliza la sentencia LET con la siguiente sintaxis: let variable = <expresin> La traduccin a JAVA es directa, en principio, es suficiente con quitar el token LET. El problema que puede plantear es la compatibilidad entre el tipo de valor a asignar y la variable, por ejemplo: si queremos asignar la constante today a la una variable tipo java.sql.date habr que hacer una procesamiento de la constante today ya que JAVA no la reconoce. Este problema se plantea bsicamente con el tipo de dato DATE y DATETIME de Informix-4GL y se soluciona durante el proceso de traduccin realizando la conversin adecuada. La solucin planteada para hacer estas asignaciones es definir mtodos auxiliares que se puedan lanzar en tiempo de ejecucin y se encarguen de pasar el formato Informix-4GL a JAVA. Se debe tener en cuenta que JAVA, a diferencia de Informix, interpreta las fechas como el nmero de milisegundos desde el 1 de enero de 1970. En las siguientes tablas se muestra la traduccin de las expresiones de Informix-4GL a JAVA utilizadas, al menos, en la sentencia LET: Informix-4GL today 22/07/2007 4000 date (<fecha> ) mdy (<mes>, <dia>, <ao> ) Conversin a JAVA new Date(new java.util.Date().getTime()) ; ASGfaux.fecha("22/07/2007") ; ASGfaux.cteIntToFechaJ(40000) ; ASGfaux.fecha ( <fecha> ) ; ASGfaux.mdy (<mes>, <dia>, <ao> ) ;

Tabla 10: Asigacin de expresiones tipo fecha

Informix-4GL current 2007-07-22 12:33:20.444

Conversin a JAVA new Timestamp(new java.util.Date().getTime()) ; ASGfaux.fechahora("2007-07-22 12:33:20.444") ;

86 datetime (2007-07-22 12:33:20.444) year ASGfaux.fechahora("2007-07-22 12:33:20.444") ; to fraction Tabla 11: Asignacin de expresiones tipo fecha/hora

Informix-4GL day( <fecha> ) moth ( <fecha> ) year ( <fecha> ) weekday ( <fecha> )

Conversin a JAVA ASGfaux.day( <fecha> ) ; ASGfaux.month ( <fecha> ) ; ASGfaux.year ( <fecha> ) ; ASGfaux.dayweek ( <fecha> ) ;

Tabla 12: Asignacin de expresiones tipo fecha a entero Todas estas funciones estn definidas en el paquete ASGutil el cual es importado en todos los programas generados.

MBITO DE VARIABLES

Como se explic en el punto: Caractersticas bsicas del Lenguaje dentro del apartado: Estudio del lenguaje Informix-4GL ste maneja tres tipos de variables: globales, de mdulo y locales y cada una con su mbito. En este apartado se presentar la forma de afrontar el problema durante el proceso de traduccin de tal forma que mantenga los mismos mbitos de variables y con la misma visibilidad en el cdigo objeto. A la hora de pasar los mbitos a JAVA se puede pensar que no hay que tener nada en cuenta ya que se mantienen los mismos nombres de identificadores, pero si habr que realizar un estudio detallado con objeto de mantener el mismo significado y visibilidad de los mismos como se ver a continuacin: Las variables locales, que tienen significado solo dentro del bloque (main, funcin o report) en el cual son declaradas, no plantean ningn problema. Al pasar esta variables a JAVA se definirn dentro del mtodo correspondiente (main, funcin) y el propio JAVA garantiza que tengan la misma visibilidad que en el programa original. Las variables tipo mdulo, que tienen significado en todos los bloques de programa que estn localizados en el mismos fichero fuente, no plantean ningn problema siempre y cuando se definan el punto adecuado dentro del programa JAVA. En Informix-4GL se definen al principio del mdulo (antes de el bloque de programa main), y en JAVA se declararn dentro de la clase principal y fuera de cualquier mtodo y antes de la aparicin de ninguno de ellos as se garantizar que sean visibles a toda la clase. Las variables globales son visibles y mantienen su valor en cualquier parte de los programas multimdulo. Esta caracterstica implica que la traduccin a JAVA no es tan directa como en los casos anteriores. En Informix-4Gl las variables globales son declaradas en la seccin GLOBALS la cual debe de aparecer al principio de cada mdulo que desee utilizarlas. Una vez declaradas son accesibles desde cualquier mdulo y mantienen su valor. La forma de implementar este tipo de variables en JAVA es definindolas en un mdulo independiente, de tal forma que puedan ser referenciadas desde cualquiera de los mdulos que conforman el programa, y de tipo esttico, garantizando as la persistencia de su valor. El acceso a este tipo de variable, en los programas JAVA, ser diferente a como se realiza en el cdigo fuente debido a que se ha de especificar como prefijo el nombre del mdulo en el cual estn declaradas: <mdulo>.<variable>

87 Hasta ahora queda claro que las variables locales y de tipo mdulo segn se traducen a JAVA mantienen su sintaxis y visibilidad, pero no ocurre lo mismo con las variables globales. Como las variables globales son referenciadas con un prefijo se ha de saber, en tiempo de traduccin, cuando se esta haciendo referencia a una de ellas para as colocar ste. La forma de poder saber si se ha de generar la variable con prefijo es a travs de la utilizacin de la tabla de smbolos durante el proceso de traduccin, de tal forma que si se determina que la variable es de tipo global lo llevar y en caso contrario no. En este punto es donde mayor se demuestra la necesidad de la tabla de smbolos durante el proceso de traduccin. La tabla de smbolos utilizada guarda 4 valores: identificador, tipo, mbito y mdulo. A continuacin se muestra un ejemplo: cinco$1 cuatro$1 uno$2 dos$3 uno$1 tres$1 dos$1 fx$2 fx2$2 6 2 3 3 3 3 3 15 15 1 1 2 3 1 1 1 2 2 ASGglobals_modglobal ASGglobals_modglobal modglobal modglobal ASGglobals_modglobal ASGglobals_modglobal ASGglobals_modglobal modglobal modglobal

Con esta definicin y las caractersticas de funcionamiento que se le han definido al tratar una variable en un mdulo se podr determinar si es de tipo: local, mdulo, o global. En la seccin: Sentencias de definicin del mdulo principal de programa, a la hora de tratar el mdulo globals se pueden ver dos casos en los que se ejemplifica la utilizacin del mbito de variables. Estos casos son: Ejemplo de bloque de programa globals y Ejemplo mdulo de programa globals.

ESTUDIO DEL SQL DE INFORMIX

89

PLANTEAMIENTO SQL

El planteamiento que se realiza dentro del estudio del SQL de Informix es muy ambicioso: Por un lado se pretende traducir todas las sentencias SQL que define Informix a sentencias JAVA que puedan ser ejecutadas, a travs del Driver JDBC, sobre el gestor de bases datos. Por otro que las sentencias SQL creadas para ser ejecutada en Informix SE, y por consiguiente especficas del mismo, puedan ser ejecutadas sobre cualquier gestor de bases de datos. Este segundo objetivo es altamente complicado debido a que no todas las sentencias SQL definidas por Informix siguen los estndares SQL y a que existen notables diferencias entre la definicin sintctica que hace Informix de las mismas con respecto a la que hacen el resto de gestores de bases de datos. El anlisis se centra en los gestores de bases de datos destino: Informix SE, SqlServer, Oracle y Db2. Informix OL,

Dentro de esta seccin no solo se estudian con total detalle todas las sentencias SQL de InformixSQL con el objetivo de conseguir generar cdigo objeto valido y equivalente para otros gestores sino que se llega ms all analizando: Los tipos de datos soportados por Informix, sus equivalentes en el resto de gestores, los validos para el JDBC JAVA y las compatibilidades con los tipos de datos del lenguaje de programacin. Las conversiones entre tipos de datos. Las operaciones sobre expresiones. El propietario y forma de acceso a tablas. Etc.

Como resultado de todo este estudio se conseguirn programas equivalentes a los originales y que se puedan ejecutar sobre diferentes gestores de bases de datos.

ENFOQUE

Para cumplir el objetivo marcado se debe enfocar el problema desde dos puntos de vista: El estudio de la sintaxis de las sentencias SQL de Informix y de las equivalentes en el resto de gestores de bases de datos con objeto de ver la compatibilidad de las mismas. Se empezara estudiando las sentencias SQL que suministra Informix-SQL, si estas cumplen el estndar SQL89 sern directamente ejecutables sobre cualquiera de los otros gestores de bases de datos. Los problemas surgen en aquellas sentencias definidas por el gestor de base de datos Informix que amplan dicho estndar. En esos casos se har un estudio detallado de las mismas para ver como, si es posible, traducirlas para que puedan ser ejecutadas en el resto de gestores de bases de datos. Y la traduccin de la sentencia a un cdigo objeto que permita la ejecucin de la misma sobre cualquier gestor de bases de datos de los aqu estudiados. En un este punto se ha de ver como se har la traduccin de la sentencia SQL a cdigo objeto de tal forma que se garantice que dicha sentencia se pueda lanzar contra los distintos gestores de bases de datos. JAVA ha definido un API de bajo nivel que soporta las funcionalidades SQL, llamada: API JDBC. Este API permite desarrollar aplicaciones de acceso a bases de datos de alto nivel y si se dispone del Driver adecuado para el gestor de bases de datos pueden ser ejecutadas sobre ste. Ante toda sentencia que proporciona Informix-SQL se seguirn varias pautas:

90 1.- Ver si el resto de gestores la interpretan de igual forma, en caso afirmativo no plantean ningn problema. 2.- En otro caso buscar soluciones alternativas, como: Necesidad o no de traducir esas sentencias. Algunas sentencias son puras de administracin y es muy raro el caso en el cual aparecen en un programa. Ante una de estas se sugerir que el administrador las ejecute directamente sobre la herramienta de administracin de la base de datos. Como Ejemplo tenemos la sentencia: drop database. Buscar posibles variantes de la sentencia inicial en el gestor de bases de datos destino. Ejemplo: la palabra reservada constraint en Informix va detrs de la definicin de las restricciones, sin embargo en SqlServer va delante. Dividir la sentencia original en varias subsentencias de tal forma que a travs de estas se pueda representar el comportamiento de la sentencia original. Ej.: sentencia alter tabla Ver si el lenguaje de programacin permite alguna posibilidad alternativa. Ejemplo: en Informix existe una sentencia database <nombre base de datos> que permite especificar la base de datos sobre la que se trabaja a partir de su aparicin. Esta sentencia no es soportada por ningn otro gestor de bases de datos. Una posibilidad es entender esta sentencia como la conexin a la base de datos, con lo cual se podr hacer una traduccin a cualquier gestor utilizando las sentencias de la clase Connection de JDBC. Buscar soluciones de implementacin a travs del lenguaje de programacin JAVA. Ejemplo: la sentencia alter table, de Informix, permite aadir campos en cualquier posicin, sin embargo el resto de gestores solo lo permiten al final. Una solucin es hacer cdigo en Java que implemente esta forma de alteracin de tablas de la base de datos. Etc.

Posteriormente se har un estudio detallado de cada sentencia SQL y en cada caso se indicar, en funcin del gestor de bases de datos destino, la forma de proceder.

PRERREQUISITOS

Para llevar a efecto la transformacin de sentencias generadas para Informix-SQL a JAVA se limitar a utilizar las funcionalidades estndar que ofrece el API JDBC 2.0 de JAVA. El cdigo fuente del que se parte para realizar el estudio SQL esta escrito en la versin 4.10 de Informix y por tanto ser la especificacin sintctica de la que se parta. Las versiones mnimas de los gestores de bases de datos sobre los cuales se podr lanza l cdigo objeto generado son: Informix 4.10 o superior SqlServer 2005 o superior. Se podra plantear usar versiones inferiores (SqlServer 7 2000) pero se han encontrado dos problemas que, auque salvables, la versin 2005 ya implementa,Estos son: Definicin de Sinnimos Distincin entre maysculas y minsculas a la hora de tratar cadenas. En versiones anteriores el gestor de base de datos no diferenciaba entre maysculas y minsculas a la hora de hacer comparaciones con campos tipo carcter.

Oracle versin 9i o superior. Esta es la primera versin de Oracle en la que se implementa el tipo de dato TIMESTAMP y este dato es la nica causa que no permite utilizar versiones inferiores. Db2 versin 8 o superior.

91

ESTANDARES SQL

SQL es el lenguaje para definir y manipular datos almacenados en una base de datos. Fue originalmente creado por IBM y pronto surgieron varios dialectos de SQL desarrollados por distintos proveedores. El Instituto Nacional Americano de Estndares (ANSI), en 1980, comienza a desarrollar un lenguaje estndar para bases de datos relacionales. ANSI y la Organizacin Internacional de Estndares (ISO) publican el estndar SQL en 1986 y 1987 respectivamente. Esta versin es conocida como SQL/86. La versin SQL/86 fue en su mayor parte basada en el dialecto original creado por IBM. SQL/89, tambin conocido como SQL1, aade integridad referencial. SQL/89 consta de dos niveles: el nivel 1 es el antiguo SQL/86 y el nivel 2 consiste en el SQL/86 con reglas de integridad. El siguiente estndar sali en 1992 y es llamado SQL/92 o SQL2 e incluye SQL embebido, catlogos y esquemas del sistema, y conversiones entre tipos. Este estndar consta de tres niveles: el nivel 1, o nivel de acceso, consiste en el SQL/89 mas algunos mensajes de error estndar, el segundo nivel, llamado nivel intermedio, define nuevas operaciones, actividades referenciales, y nuevos tipos de datos, el tercer nivel , conocido como nivel completo, aade comandos para sistemas cliente/servidor. El ultimo nivel, es el SQL3 el cual aporta nuevas caractersticas principalmente debido a la inclusin de los conceptos de Orientacin a objetos y en otros aspectos como: nuevos tipos de datos, funciones SQL, procedimientos almacenados, triggers, etc. En la siguiente tabla se muestran todos los estndares y sus caractersticas: Estndar ANSI SQL/89 Nivel 1 Nivel Caractersticas Definicin y manipulacin de datos: seleccin, proyeccin, uniones. SQL embebido Cursores Nivel 2 Reglas de integridad: clusula CHECK, PRIMARY KEY, referencia a columnas (FOREIGN KEY) Mensajes SQLSTATE Lenguajes Ada. Nivel intermedio de errores estndar:

SQL/92

Nivel de acceso

anfitriones

adicionales: C,

Tipos de datos: DATE, TIME Operadores: OUTER JOIN, UNION, INSERT SELECT Dominios Estructuras TABLE Dynamic SQL Acciones referenciales: ON DELTE Intervalos de tiempo: YEAR, MONTH, DAY, HOUR Aritmtica sobre unidades de tiempo. de manipulacin: ALTER OUTER

SQL completo

Establecer conexiones entre cliente y servidor: CONNECT TO, SET

92 CONNECTION, DISCONNECT Acciones referenciales: ON UPDATE Reglas de integridad: CREATE ASSERTION... CHECK, SET CONSTRAINTS ON/OFF, FETCH PRIOR, FETCH RELATIVE Tipos de datos: BIT y STRING HEX SQL3 Orientacin a objetos Triggers Procedimientos almacenados Funciones SQL Polimorfismo Tipos de datos: LIST, ARRAY SET Comandos DML recursivos: RECUSIVE UNION Tabla 13: Estndar SQL Los productos Informix-SQL cumplen el nivel de conformidad con el nivel ANSI SQL89 en los servidores de bases de datos Informix OL (Online) y en los servidores de bases de datos Informix SE (Standard Engine) con las siguientes excepciones: Chequeo de restricciones. Transacciones serializables.

Oracle 8i (y superiores) soporta completamente el nivel SQL92 bsico (o de acceso) y algunas caractersticas de los niveles intermedio o completo. SqlServer 7.0 (y superiores) es compatible con el estndar nivel bsico de SQL92, y con otras muchas funciones de los niveles intermedio y completo. DB2 Versin 7.0 tambin cumple al menos el nivel bsico de compatibilidad SQL92.

CONVENCIONES DE SINTAXIS

Durante todo este documento, a la hora especificar la sintaxis de las sentencia SQL, se seguirn una serie de convenciones que se detallan a continuacin: La sintaxis de las sentencias SQL se especifica en formato BNF extendida. S en la definicin sintctica aparece algn elemento que pueda formar parte de la notacin BNF extendida, este se resaltar en negrita para indicar que forma parte de la sentencia que se est definiendo. A la hora de especificar la sintaxis de las sentencias SQL del resto de gestores de bases solo incluir la parte necesaria que permita garantizar que la sentencia original de Informix-SQL es soportada por los mismos1. Cuando se esta analizando una sentencia SQL para determinar si es compatible con la sentencia original, de Informix-SQL, se resaltan en color azul aquellas partes de la misma que no plantean ningn problema.

Para ver las sentencias completas dirigirse a la documentacin indicada en la bibliografa.

93

CLASIFICACIN DE LAS SENTENCIAS SQL


Las sentencias de Informix-SQL se dividen en los siguientes tipos:

SENTENCIAS SQL DE DEFINICIN DE DATOS


Incluye el grupo de sentencias que soportan la definicin o declaracin de los objetos de la base de datos. En la tabla siguiente se detallan el grupo de sentencias que incluye Informix-SQL en su sintaxis: ALTER INDEX ALTER TABLE CLOSE DATABASE CREATE DATABASE CREATE INDEX CREATE SYNONYM CREATE TABLE CREATE VIEW DATABASE DROP DATABASE DROP INDEX DROP SYNONYM DROP TABLE DROP VIEW RENAME COLUMN RENAME TABLE

Tabla 14: Sentencias de definicin de datos

SENTENCIAS SQL DE MANIPULACIN DE DATOS


Este grupo de sentencias permiten la manipulacin de los datos de la base de datos. En la siguiente tabla se especifican estas: INSERT DELETE LOAD SELECT UNLOAD UPDATE

Tabla 15: Sentencias de manipulacin de datos

SENTENCIAS SQL DE MANIPULACIN DE CURSORES


El grupo de sentencias que permiten la manipulacin de datos a travs de cursores, son: CLOSE DECLARE FETCH FLUSH OPEN PUT

Tabla 16: Sentencias de manipulacin de cursores

SENTENCIAS SQL DE OPTIMIZACIN-INFORMACIN


Lo forman un grupo de sentencias que permiten optimizar los accesos a la base de datos as como obtener informacin para depuracin. Este grupo de sentencias son muy especficas del gestor de bases de datos Informix-SQL lo cual no quiere decir que el resto de gestores aporten sus propias herramientas de optimizacin y depuracin. Lo forman las siguientes sentencias: SET EXPLAIN SET OPTIMIZATION UPDATE STATISTICS Tabla 17: Sentencias de optimizacin-Informacin

SENTENCIAS SQL DE CONTROL DE ACCESO A LOS DATOS


Grupo de sentencias que permiten tratar los bloqueos y los permisos de acceso a los datos y operaciones sobre los mismos: GRANT LOCK TABLE REVOKE UNLOCK TABLE SET LOCK MODE

94 Tabla 18: Sentencias de control de acceso a los datos

SENTENCIAS SQL QUE GARANTIZAN LA INTEGRIDAD DE LOS DATOS


Este grupo de sentencias se encargan de gestionar las transacciones y de auditar tablas en Informix-SQL: BEGIN WORK DROP AUDIT COMMIT WORK ROLLBACK WORK CREATE AUDIT START DATABASE

Tabla 19: Sentencias de integridad de los datos

SENTENCIAS SQL DE MANIPULACIN DINMICA DE DATOS


Sentencias de permitir la preparacin y ejecucin de sentencias SQL de forma dinmica, son: EXECUTE FREE PREPARE Tabla 20: Sentencias de manipulacin dinmica de datos

ESTUDIO DE LAS SENTENCIAS SQL


SENTENCIA ALTER INDEX
Esta sentencia permite alterar un ndice de una tabla existente. La sentencia ALTER INDEX trabaja nicamente sobre ndices que han sido creados con la sentencia CREATE INDEX; esta no afecta a las restricciones (constraints) que han sido creados con la sentencia CREATE TABLE. No se pueden alterar ndices de las tablas temporales.

SINTAXIS DE INFORMIX
<ALTER NDEX> ::= ALTER INDEX nombreindice TO [NOT] CLUSTER La opcin TO CLUSTER causa que las filas en la tabla indexada sean reordenadas en el orden del ndice creado. Esta sentencia no esta contemplada por el SQL89 y tampoco por en el nivel bsico del estndar SQL92, es una extensin que aporta Informix-SQL, y no es soportada en el mismo aspecto que Informix-SQL por ningn otro gestor de bases de datos de los contemplados aqu.

IMPLEMENTACION
La traduccin de esta sentencia al cdigo objeto, JAVA, es inmediata puesto que se trata de una sentencia esttica, ya que el nombreindice es un identificador o una constante cadena. Lo nico que habr que hacer es lanzar la sentencia contra el gestor de bases de datos. Dado que: la utilidad de esta sentencia no es excesiva, su uso a nivel de programas es prcticamente nulo (al ser una sentencia de administracin de la base de datos), no es soportada por el estndar SQL89, y que el resto de gestores de bases de datos no la soportan ser omitida la traduccin de dicha sentencia a JAVA. A la hora de lanzar el proceso de traduccin, si aparece esta sentencia en el cdigo fuente, se notificar la no traduccin de la misma con un mensaje como el que sigue: Mensaje: Warning: Sentencia alter index no generada

95

SENTENCIA ALTER TABLE


Esta sentencia modifica una definicin de tabla al alterar, agregar, o quitar columnas y restricciones o al deshabilitar o habilitar restricciones. Para poder modificar una tabla se deben tener permisos de alteracin sobre la misma. Cuando una columna es aadida, la tabla existente es extendida con la nueva columna, la cual se coloca al final de la definicin de la tabla2. Cuando una columna es alterada es posible cambiar el tipo de dato de la columna que se altera. Si se cambia el tipo de dato el nuevo tipo ha de ser compatible con los datos que ya existen en la columna. Cuando una columna es dropada, esta es borrada de la tabla as como las vistas, restricciones e ndices que hacen referencia al campo borrado.

SINTAXIS DE INFORMIX
<ALTER TABLE> ::= ALTER TABLE nombretabla [ MODIFY ( { nombrecolumna < nuevotipotatos> [NOT NULL] {[UNIQUE | DISTINCT] [CONSTRAINT nombrerestriccion] }[,...n] }[,...n] ) | ADD ( { nombrecolumna <tipodato> [NOT NULL] {[UNIQUE | DISTINCT] [CONSTRAINT nombrerestriccion] }[,...n] [BEFORE nombrecolumna] }[,...n]) | DROP (nombrecolumna[,...n]) | ADD CONSTRAINT {[UNIQUE | DISTINCT] (nombrecolumna[,...n]) [CONSTRAINT nombrerestriccion] }[,...n] | DROP CONSTRAINT (nombrerestriccion [,...n] ) ] {,...n} Esta sentencia no es contemplada por el estndar SQL89, Informix-SQL lo amplia al usarla, aunque si es soportada, en parte, por el estndar bsico SQL92 lo cual facilitar mucho el poder usarla en otros gestores de bases de datos. Observando esta sentencia vemos: La opcin MODIFY no esta contemplada por el estndar bsico SQL92, aunque de una u otra forma la mayora de los gestores de bases de datos lo soportan. La opcin: CONSTRAINT nombrerestriccion es una aplicacin que aporta Informix-SQL a la versin 4.10. Por defecto los campos que se aadan o modifiquen pueden tomar valores nulos en caso contrario se debe de especificar con la clusula NOT NULL. Esto cumple el estndar bsico SQL92, pero en dicho estndar se considera esta clusula como una restriccin y en InformixSQL no. Como restricciones solo admite: UNIQUE y DISTINCT. Ambas restricciones significan lo mismo: que el campo sobre el que se aplica no admitir valores duplicados. DISTINCT no es soportado por el estndar SQL92. Si aparece la palabra CONSTRAINT, como restriccin de una columna, Informix-SQL contempla que se debe de colocar esta detrs de la propia restriccin, sin embargo el estndar SQL92 indica que a de aparecer delante y el resto de gestores de bases de datos estudiados tambin lo entienden as.

A excepcin de Informix-SQL que permite posicionar la nueva columna en cualquier posicin.

96 Si aparece una clusula de restriccin de tabla el estndar SQL92 obliga en el caso de aparecer la palabra CONSTRAINT a que se le de un nombre a la restriccin. Esto lo respetan la mayora de los gestores de bases de datos, pero Informix-SQL no obliga a ello. Al aadir columnas a una tabla ya creada Informix permite especificar en que posicin se colocara el nuevo campo, usando para ello la clusula BEFORE. Esto no es soportado por el estndar SQL92 el cual indica que todo campo se aadir al final. La posicin en la que se coloca el nuevo campo no tiene ninguna trascendencia para el funcionamiento o utilizacin de la tabla. Cuando se aade o borra campos a una tabla Informix-SQL permite hacerlo sobre ms de uno al mismo tiempo, en cambio el estndar bsico SQL92 solo permite hacerlo sobre un campo de por cada sentencia ALTER. Todos los gestores estudiados se ajustan al estndar en esta caracterstica. Cuando se borran restricciones el estndar bsico SQL92 solo permite hacerlo sobre una de cada vez en cambio Informix-SQL permite borrar ms de una por cada sentencia. El resto de gestores estudiados se suelen ajustar al estndar. El estndar bsico SQL92 solo admite una clusula (ADD, MODIFY, o DROP) dentro de la sentencia ALTER TABLE, Informix-SQL admite ms de una separadas por comas, otros gestores lo permiten sin ningn separador, y SqlServer no lo permite.

SINTAXIS DE SQLSERVER
<ALTER TABLE> ::= ALTER TABLE nombretabla [ ALTER COLUMN nombrecolumna { <nuevotipodatos> [ NULL | NOT NULL ] | {ADD | DROP} ROWGUIDCOL } | ADD { <definicion de columna> | nombrecolumna AS <expresioncalculadacolumna> }[,...n] | [WITH CHECK | WITH NOCHECK] ADD { <restricciondetabla> }[,...n] | DROP { [CONSTRAINT] nombrerestriccion | COLUMN nombrecolumna }[,...n] | {CHECK | NOCHECK} CONSTRAINT {ALL | nombrerestriccion [,n]} | {ENABLE | DISABLE} TRIGGER {ALL | nombredesencadenador [,n]} ] <definicion de columna> ::= { nombrecolumna tipodatos } [ [ DEFAULT expresionconstante ] | [ IDENTITY [(inicializacion, incremento ) [NOT FOR REPLICATION] ] ] ] [ ROWGUIDCOL ] [ <restricciondecolumna>] [ ...n] <restricciondecolumna> ::= [CONSTRAINT nombrerestriccion] { [ NULL | NOT NULL ] | [ { PRIMARY KEY | UNIQUE } [CLUSTERED | NONCLUSTERED] [WITH FILLFACTOR = factorrelleno] [ON {grupoarchivos | DEFAULT} ]] ]

97 | [ [FOREIGN KEY] REFERENCES referenciaatabla [(referenciaacolumna) ] [NOT FOR REPLICATION] ] | CHECK [NOT FOR REPLICATION] (<expresionlogica>) } <restricciondetabla> ::= [CONSTRAINT nombrerestriccion] { [ PRIMARY KEY | UNIQUE ] [ CLUSTERED | NONCLUSTERED] { ( columna[,...n] ) } [ WITH FILLFACTOR = factorrelleno] [ON {grupoarchivos | DEFAULT} ] ] | FOREIGN KEY [(columna[,...n])] REFERENCES tablareferencia [(referenciaacolumna[,...n])] [NOT FOR REPLICATION] | DEFAULT <expresionconstante> [FOR columna] | CHECK [NOT FOR REPLICATION] (<expresionlogica>) } Estudiando con detenimiento sta sintaxis proporcionada por SqlServer se puede observar que se debern hacer bastantes modificaciones en la sentencia inicial proporcionada por Informix-SQL para que pueda ejecutarse sobre el gestor de bases de datos SqlServer, estas son: Para cada clusula se ha de crear una sentencia ALTER TALBE distinta. Dentro de cada clusula se admite aadir, borrar o modificar ms de un campo o restriccin. Cada campo que se aada, borre o modifique se separa del resto con el delimitador coma. La clusula MODIFY no aparece en la sentencia SqlServer, pero si hay una equivalente ALTER COLUMN, y dentro de est no permite la restriccin UNIQUE ni asociar un nombre a las restricciones. La clusula DROP es la que ms vara ya que SqlServer obliga a poner a continuacin COLUMN sino entiende que es una restriccin y Informix-SQL lo interpreta al revs.

SqlServer realiza ms control semntico que Informix-SQL al tratar de alterar un campo, por ejemplo: no deja modificar o borrar un campo si este tiene asociado algn constraint. Estos temas semnticas no son controlados.

SINTAXIS DE ORACLE
<ALTER TABLE> ::= ALTER TABLE [ <esquema> .] nombretabla [ MODIFY ( { nombrecolumna < nuevotipotatos> [ DEFAULT <expresin> ] <restrincciondecolumna> [...n] }[,...n] ) | ADD ( { nombrecolumna <tipodato> [ DEFAULT <expresin> ] [ <restricciondecolumna> [...n]] }[,...n]) | DROP [ (nombrecolumna[,...n]) | COLUMN nombrecolumna ] | ADD [ ( <restriccin de tabla> [,...n]) | <restriccin de tabla > [,...n] ] | DROP CONSTRAINT nombrerestriccion ] {...n}

98 <restriccin de columna> ::= [CONSTRAINT nombrerestriccion] { [ NULL | NOT NULL ] | [ PRIMARY KEY | UNIQUE ] | CHECK ( <condicion> ) | REFERENCES <opciones de referencia> } <estado constraint> <restriccin de tabla> ::= [CONSTRAINT nombrerestriccion] { [ [ NULL | NOT NULL ] | [ PRIMARY KEY | UNIQUE ] ] ( nombrecolumna[,...n] ) | <clusula clave ajena> | CHECK ( <condicion> ) | REFERENCES <opciones de referencia> } <estado constraint> Analizando esta sentencia se puede ver que la original de Informix-SQL se podr adaptar al gestor de bases de datos sin mucho problema. Analizndola con detalle vemos: Para cada sentencia ALTER TALE se podrn crear ms de una clusula y estas no irn separadas por el delimitador coma, como en Informix-SQL, sino que por un espacio. Dentro de cada clusula se podrn aadir, borrar o modificar ms de un campo o restriccin, con la excepcin del borrado de restricciones, usando como separador de cada campo la coma. Los campos que se aadan, borren o modifiquen y el aadir restricciones dentro de una misma clusula van entre parntesis.

La parte MODIFY de est clusula aunque sintcticamente permite aadir constraints al campo que se modifica Oracle tiene una restriccin y solo deja aadir o eliminar constraints a un campo en las secciones de est sentencia: aadir columnas y aadir restricciones. Oracle no permite definir dos restricciones iguales sobre un campo, como por ejemplo tratar de fijar que un campo es NOT NULL cuando ya lo es o crear una clave nica sobre un campo que ya tiene definida una clave nica. Estas situacin son irracionales pero el cdigo fuente, Informix-SQL, las puede tener. Durante el proceso de traduccin no se controlar este tipo de reglas semnticas.

SINTAXIS DE DB2
<ALTER TABLE> ::= ALTER TABLE nombretabla [ ALTER [COLUMN] nombrecolumna <modificaciondecolumna> | ADD [COLUMN] nombrecolumna <tipodato> [NOT NULL] [ <restricciondecolumna> [...n]] | ADD <restricciondetabla> | DROP [ PRIMARY KEY | [ FOREIGN KEY | UNIQUE | CHECK | CONSTRAINT ] nombrerestriccion ] {...n} <restricciondecolumna> ::= [CONSTRAINT nombrerestriccion] | [ NULL | NOT NULL ] | [ PRIMARY KEY | UNIQUE ] | CHECK ( <condicin> ) | REFERENCES <opciones de referencia> <restriccin de tabla> ::= [CONSTRAINT nombrerestriccion] | [ PRIMARY KEY | UNIQUE ] ( nombrecolumna[,...n] ) | FOREIGN KEY ( nombrecolumna[,...n] )

99 | | CHECK ( <condicin> ) ] <modificacin de columna> ::= SET DATA TYPE { VARCHAR | CHARACTER VARING | CHAR VARING } ( entero ) Esta sentencia es la ms restrictiva de todas las sentencias ALTER TABLE estudiadas hasta el momento tanto que habr situaciones imposibles de solventar a la hora de traducir cdigo fuente Informix-SQL a Db2. A continuacin se detallan las peculiaridades y problemas encontrados: Dentro de una misma sentencia ALTER TABLE se pueda incluir ms de una clusula utilizando como separador entre clusulas el espacio. La opcin ADD COLUMN tiene varias restricciones a la hora de fijar constraints: Si se usa NOT NULL obliga a fijar un valor por defecto sobre el campo. (uso de la opcin: DEFAULT). Si se utiliza UNIQUE no permite que el campo pueda tener valores nulos con lo que ha de ir acompaado de: NOT NULL y por asociacin utilizar la opcin: DEFAULT.

No permite eliminar columnas de la definicin original de una tabla. La opcin ALTER COLUMN es muy restrictiva, no admite ms que modificar campos tipo VARCHAR y solo para aumentar la longitud de los mismos, y dentro de ella no permite aadir restricciones. No se pueden aadir constraints UNIQUE a una columna si sta no ha sido definida como que no admite valores nulos. Y esta opcin no permite aadir la restriccin NOT NULL.

Para varios de los problemas, irresolubles, que se plantean con Db2 al traducir cdigo fuente Informix-SQL no se propondr solucin prctica. En estos casos se sugiere que se revise el cdigo genera y se adopten soluciones manuales, tales como: Plantearse el definir todos los campos NOT NULL, en la sentencia CREATE TABLE, con objeto de evitar el fallo de las restricciones. Para el caso de modificar o eliminar un campo solo se podra hacer creando una tabla nueva con los campos con el nuevo tipo o sin el campo eliminado y hacer un traspaso de la informacin de una tabla a la otra.

GENERACIOND DE CODIGO
La sentencia ALTER TABLE de Informix-SQL permite que dentro de una misma sentencia se incluya ms de una clusula, separadas por comas, y dentro de cada clusula se pueden alterar ms de un campo. Esto no es soportado por todos los gestores de bases de datos para los que se genera cdigo, ni por el estndar SQL92. SqlServer, solo soportan una clusula por cada sentencia y Oracle y DB2 permiten ms de una usando como delimitador el espacio. Dentro de cada clusula esta puede aplicarse sobre un solo campo o ms e incluir los campos entre parntesis o no. La situacin ms restrictiva que se plantea es que en una sentencia ALTER solo se puede aplicar una clusula y dentro de esta alterar solo un campo. Como este caso ms restrictivo es soportado por todos los gestores de bases de datos se generara cdigo as para todos los gestores no teniendo de este modo que diferenciar, en este aspecto, entre el gestor de bases de datos para el cual se genera el cdigo. Ejemplo: Cdigo fuente: Alter table prueba modify (campo1 integer, campo2 char(2)), add (campo3 smallint, campo4 decimal(5,2)) Cdigo objeto: Alter table prueba modify (campo1 integer) Alter table prueba modify (campo2 char(2) )

100 Alter table prueba add (campo3 smallint) Alter table prueba add (campo4 decimal(5,2) ) A nivel general hay que tener en cuenta que unos gestores utilizan los parntesis para delimitar los campos que se alteran en las tablas y otros no. En este caso no podemos generalizar, a la hora de generar cdigo se tendr en cuenta para que gestor se esta haciendo y se incluirn estos o no. Los nombres de las clusulas no son iguales para cada gestor, habr que poner uno u otro en funcin de para que gestor de bases de datos se genera cdigo. As para Informix y Oracle se usar: ADD, MODIFY, DROP, ADD CONSTRAINT y DROP CONSTRAINT y para SqlServer y Db2 se usar: ADD, ALTER COLUMN, DROP COLUMN, ADD CONSTRAINT, y DROP CONSTRAINT. Otro aspecto para el que tambin habr que tener en cuenta el gestor de bases de datos para el cual se est generando cdigo son las restricciones (constraints). La sintaxis de Informix-SQL es: <restriccin> CONSTRAINT nombrerestriccion sin embargo el resto de gestores de base de datos estudiados tienen la siguiente sintaxis: CONSTRAINT nombrerestriccion <restriccin>. Informix usa como restriccin NOT NULL aunque no lo incluye como parte de una clusula CONSTRAINT, el resto de gestores si la considera. Esto no causa ningn problemas puesto que una clusula CONSTRAINT no obliga a que aparezca el nombre asociado a la restriccin, con lo que el resto de los gestores lo interpretar como una restriccin sin nombre asociado. Particularidades: Clusula MODIFY. Informix-SQL admite como restricciones: NOT NULL y UNIQUE o DISTINCT. SqlServer y Oracle solo admiten NOT NULL, sin permitir para esta restriccin asociarle un nombre, y Db2 ninguna restriccin. Aqu se planteas 3 problemas: Para SqlServer, Oracle y Db2 no permiten aadir la restriccin UNIQUE durante la clusula MODIFY. Como solucin lo que se har es generar una sentencia ALTER TABLE adicional que cree esta restriccin. Ver ejemplo: Ejemplo1: Sentencia original: alter table tabla1 modify(campo1 int not null unique ) Sentencias generadas para SqlServer: alter table tabla1 alter column campo1 integer not null alter table tabla1 add unique (campo1) Sentencias generadas para Oracle: alter table tabla1 modify ( campo1 integer not null ) alter table tabla1 add unique (campo1) Sentencias generadas para Db2: alter table tabla1 modify ( campo1 set data type integer ) alter table tabla1 add unique (campo1) Ejemplo2: Sentencia original: alter table tabla1 modify(campo1 int not null unique constraint constr1) Sentencias generadas para SqlServer: alter table tabla1 alter column campo1 integer not null alter table tabla1 add constraint constr1 unique (campo1)

101 Sentencias generadas para Oracle: alter table tabla1 modify ( campo1 integer not null ) alter table tabla1 add constraint constr1 unique (campo1) Sentencias generadas para Db2: alter table tabla1 modify ( campo1 set data type integer ) alter table tabla1 add constraint constr1 unique (campo1) Generando esta sentencia adicional se consigue que el cdigo generado tenga el mismo efecto, sobre el gestor de bases de datos destino, que el cdigo original sobre Informix. En el caso de que se este generando cdigo para Db2 se mostrarn dos mensajes por pantalla: uno indicando que se revise esta sentencia ya que al ser tan restrictiva es probable que falle, y otro indicando que se revise la restriccin unique ya que dependiendo como haya sido definida la columna, en la sentencia CREATE TABLE, puede fallar. Mensajes: Warning: Revisar clusula modify de sentencia alter table Warning: Revisar constraints UNIQUE en clusula modify de alter table Db2 no admite aadir ninguna restriccin dentro de esta clusula. Para el caso de UNIQUE se adopta la opcin de aadir una sentencia adicional, como se indico en el punto anterior, para el caso de NOT NULL se omitir la generacin de cdigo de esta parte indicndolo, a travs de un mensaje, durante el proceso de traduccin. Mensaje: Warning: NOT NULL no generado en clusula modify de alter table

Db2 no permite eliminar campos. Para este gestor no se generar esta clusula y se avisar por pantalla de tal hecho. Mensaje: Warning: Sentencia alter table drop <campo> no generada La palabra reservada DISTINCT no es soportada por ningn otro gestor ni por el estndar SQL92, aunque si la palabra UNIQUE, por tanto si aparece DISTINCT se sustituir por UNIQUE durante el proceso de traduccin. La clusula ADD CONSTRAINT vara sintcticamente entre unos gestores y otros. La sintaxis de la sentencia proporcionada por Informix-SQL en caso de etiquetar las constraints lo hace al final de la misma en cambio el resto de gestores lo hace al principio, por otro lado el resto de gestores en caso de aparecer la palabra CONSTRAINTS obliga a darle un nombre a la restriccin. Por tanto la solucin adoptada se ejemplifica a continuacin: Sentencia original de Informix-SQL es: alter table tabla add constraint unique (campo1, campo2) Se transformara para el resto de gestores como: alter table tabla add unique (campo1, campo2) Pero si la sentencia original es: alter table tabla add constraint distincit (campo1, campo2) constraint restriccion1 Se transformara para el resto de gestores como: alter table tabla1 add constraint restriccion1 unique (campo1, campo2) Adicionalmente si se genera cdigo para DB2 se tendr en cuenta que esta sentencia puede fallar si no se ha definido el campo original como que no admite valores nulos. Al traducir el cdigo fuente se notificar esta situacin. Mensaje: Warning: Revisar clusula ADD CONSTRAINT de la sentencia alter table

102 Clusula DROP CONSTRAINT: todo gestor menos Informix-SQL admite borrar una sola restriccin por clusula y no colocan el nombre de la clusula entre parntesis. En esta sentencia se modifican y/o crean campos lo que implica especificar el tipo de dato del mismo. La compatibilidad de los distintos tipos de datos entre los diferentes gestores de bases de datos se estudia en la seccin: Estudio de Tipos de datos.

En el anexo I, en el punto: Ejemplo sentencia alter table, se muestran ejemplos de traduccin de la sentencia ALTER TABLE de Informix-SQL a JAVA para cada uno de los gestores de bases de datos estuciados.

SENTENCIA BEGIN WORK


Esta sentencia marca el comienzo de una transaccin. Si se producen errores, se pueden deshacer todas las modificaciones realizadas en los datos despus de BEGIN para devolver los datos al ltimo estado conocido de coherencia. Cada transaccin dura hasta que se completa sin errores y se emite COMMIT, para hacer que las modificaciones sean una parte permanente de la base de datos, o hasta que se producen errores y se borran todas las modificaciones con la instruccin ROLLBACK. Se puede incorporar una instruccin BEGIN WORK solo si no hay ninguna transaccin en progreso, en caso contrario se producir un error. Esta sentencia no es incorporada ni por el estndar SQL89 ni por el estndar bsico SQL92, aunque de una forma u otra todos los gestores de bases de datos la incorporan, incluido Informix-SQL, razn por la cual se incorpora a la hora de traducir el cdigo fuente. Las bases de datos Informix pueden ser creadas con o sin soporte de transacciones. Informix OL soporta varios niveles de asilamiento en las transacciones: REPETEABLE READ, CURSOR STABILITY, COMMITED READ, DIRTY READ. La versin de que se parte en este estudio: Informix SE solo soporta los niveles de aislamiento: COMMITTED READ y DIRTY READ. Si la base de datos no tiene habilitado el soporte para transacciones no se puede fijar el nivel de aislamiento.

SINTAXIS DE INFORMIX
<BEGINWORK> ::= BEGIN WORK Cada fila que es afectada por un UPDATE, DELETE o INSERT durante una transaccin es bloqueada y permanece bloqueada mientras permanezca activa la transaccin.

SINTAXIS DE SQLSERVER
<BEGINWORK> ::= BEGIN [ TRAN | TRANSACTION ] BEGIN TRANSACTION inicia una transaccin local. La transaccin local aumenta al nivel de transaccin distribuida si se realizan una de las siguientes acciones antes de confirmarla o deshacerla: Se ejecuta una instruccin INSERT DELETE o UPDATE que hace referencia a una tabla remota de un servidor vinculado. Se realiza una llamada a un procedimiento almacenado remoto.

SINTAXIS DE ORACLE
Oracle no define la sentencia BEGIN WORK entiende que toda sentencia lleva implcito este comando. Oracle realiza un autocommit antes y despus de todas las sentencias DDL (Data Definition Language) las cuales son: ALTER, CREATE, DROP, GRANT, RENAME, REVOKE, TRUNCATE, etc. Las sentencias DML (Data Manipulacin Lenguaje) no llevan implcito el autocommit, estas son: DELETE, INSERT, LOCK TABLE, SELECT, UPDATE, etc.

103 Si no se utiliza la sentencia COMMIT o ROLLBACK y se finaliza la conexin de forma adecuada (se cierra esta) el sistema realiza automticamente el COMMIT, por el contrario si se finaliza la conexin sin cerrar esta se ejecuta la sentencia ROLLBACK.

SINTAXIS DE DB2
Db2 tampoco define la sentencia BEGIN WORK y tiene un comportamiento similar al Oracle. Cuando se ejecuta COMMIT una unidad de trabajo es procesada, los cambios son pasados a la base de datos, y otra es inicializada. Las sentencias afectadas por transacciones son: ALTER, CREATE, DELETE, DROP, GRANT, INSERT, LOCK TABLE, REVOKE, UPDTA, etc.

GENERACION DE CODIGO
De todos los gestores estudiados aqu todos ellos admiten transacciones aunque unos de forma implcita y otros explcita. Oracle, SqlServer y DB2 admiten transacciones sin hacer para ello nada especial en la base de datos sobre la cual se ejecutan las transacciones, sin embargo Informix, por defecto, considera que todas las bases de datos estn en modo no transaccional. A la hora de generar cdigo java no se traducir la instruccin de forma directa sino que se utilizaran las sentencias que proporciona el JDBC de JAVA para el control de transacciones. Las instrucciones a utilizar sern las siguientes: Connection.setTransactionIsolation, que fija el nivel de asilamiento de las transacciones. JAVA soporta los siguientes niveles: Connection.TRANSACTION_NONE . Indica que no hay transacciones. Connection.TRANSACTION_READ_COMMITTED. Especifica que se mantengan los bloqueos compartidos mientras se leen datos para evitar lecturas no confirmadas, pero se pueden modificar los datos antes del final de la transaccin, lo que provoca lecturas repetibles o datos fantasmas. Se ven solo las modificaciones ya guardadas hechas por otras transacciones. Nivel de aislamiento predeterminado. Connection.TRANSACTION_READ_UNCOMMITTED. Implementa las lecturas no confirmadas o el bloqueo de nivel de aislamiento 0, lo que significa que no hay bloqueos compartidos y que los bloqueos exclusivos no estn garantizados. Cuando se establece esta opcin, es posible leer datos no confirmados, los valores pueden cambiar y pueden aparecer y desaparecer filas en el conjunto de datos antes del final de la transaccin. Esta opcin tiene el mismo efecto que establecer NOLOCK en todas las tablas y en todas las instrucciones SELECT de una transaccin. Se trata del menos restrictivo de los cuatro niveles de aislamiento. Connection.TRANSACTION_REPEATABLE_READ. Se establecen bloqueos para todos los datos utilizados en la consulta, lo que impide que otros usuarios los actualicen, aunque es posible insertar nuevas filas fantasmas en los datos que otro usuario establezca, de modo que se incluyan en lecturas posteriores de la misma transaccin. Como la simultaneidad es inferior que el nivel de aislamiento predeterminado, slo se debe usar esta opcin cuando sea necesario. Connection.TRANSACTION_SERIALIZABLE. Se establece un bloqueo de intervalo en el conjunto de datos, lo que impide que otros usuarios actualicen o inserten filas en el conjunto de datos hasta que finalice la transaccin. Es el ms restrictivo de los cuatro niveles de aislamiento. Al ser menor la simultaneidad, slo se debe utilizar esta opcin cuando sea necesario.

Connection.setAutoCommit( false ). Marca el inicio de una transaccin. Connection.setAutoCommit( true ). Marca el fin de una transaccin. Connection.rollback(). Deshace los cambios y regresa hasta la ltima situacin estable conocida de la base de datos. Connection.commit(). Ejecuta los cambios sobre la base de datos.

104 Hay que tener en consideracin que aunque JDBC permite seleccionar un nivel de aislamiento hacer esto no tendr ningn efecto a no ser que el driver del controlador de la base de datos lo soporte. Informix, SqlServer y Db2 admite todos los niveles de aislamiento, sin embargo Oracle solo admite READ_COMMITTED y SERIALIZABLE. El comportamiento general de los programas es que cada sentencia individual se trate como una transaccin y est ser pasada al gestor de bases de datos nada ms ser ejecutada. Si se pretende que dos o ms sentencias sean agrupadas en una transaccin se deben de utilizar las sentencias de manejo de transacciones: BEGIN WORK, COMMIT y ROLLBACK. El nivel de aislamiento que se establece por defecto en los gestores de bases de datos es READ_COMMITTED. Para reflejar el comportamiento por defecto de los gestores al principio de cada programa generado, durante del proceso de traduccin, se fijar el nivel de aislamiento y se activar el modo auto-entrega (autocommit) de tal forma que cada sentencia sea considerada una transaccin. Esto se realizar dentro del mtodo: HayTransac() justo despus de establecer la conexin con la base de datos, esta mtodo contendr bsicamente las instrucciones JAVA: Conection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); Conection.setAutoCommit (true); Esta sentencia, para el caso que el gestor de bases de datos sea Informix puede producir un error si la base de datos no esta en modo transaccional y en este caso las sentencia ROLLBACK Y COMMIT no tienen sentido. Para este gestor no se omitir la generacin de cdigo de las sentencias que manejan transacciones pero si se desactivar la generacin de errores haciendo que as, que en caso de que el mismo este en modo no transaccional, no se vea afectado el funcionamiento del programa. Cuando se decide por programa utilizar transacciones el flujo de sentencias Informix ser: BEGIN WORK [ sentencias SQL ] COMMIT WORK o ROLLBALLWORK Este se traducir a sentencias JAVA: Connection.setAutoCommit(false); //desactiva el modo auto-commit [ sentencias SQL ] Si la transaccin no se da por correcta: Connection.rollback(); Connection.setAutoCommit (true); Si la transaccin se da por correcta: Connection.commit(); Connection.setAutoCommit (true); En la seccin SENTENCIA COMMIT (Sentencia COMMIT WORK) se muestra un ejemplo del uso de transacciones

SENTENCIA CLOSE
Cierra un cursor abierto liberando el conjunto de resultados actual y todos los bloqueos mantenidos sobre las filas en las que estaba colocado el cursor. Esta sentencia esta soportada por el estndar SQL89 y por consiguiente por el SQL92.

105

SINTAXIS DE INFORMIX
<CLOSE> ::= CLOSE nombredecursor

SINTAXIS DE SQLSERVER
<CLOSE> ::= CLOSE { { [GLOBAL] nombrecursor } | nombrevariablecursor}

SINTAXIS DE ORACLE
<CLOSE> ::= CLOSE nombredecursor | <variablecursor>

SINTAXIS DE DB2
<CLOSE> ::= CLOSE nombredecursor [ WITH RELEASE ]

GENERACIN DE CDIGO
Como se ve esta sentencia es definida, con igual sintaxis que Informix-SQL, por el resto de gestores. En la seccin: Sentencias de manipulacin dinmica de datos y cursores se mostrarn ejemplos de esta sentencia, junto con el resto de sentencias de manejo de cursores, as como las peculiaridades de su traduccin a cdigo objeto.

SENTENCIA CLOSE DATABASE


Esta sentencia cierra la conexin con la base de datos. Esta sentencia no es soportada por el estndar SQL89 y tampoco por el SQL92 y es una ampliacin que Informix-SQL aade a su versin 4.10 y el resto de gestores de bases de datos estudiados, de una u otra forma, implementan algn sistema de desconexin con la base de datos aunque no se ajustan en ningn caso a la sentencia de Informix-SQL.

SINTAXIS DE INFORMIX
<CLOSE DATABASE> ::= CLOSE DATABASE

GENERACIN DE CODIGO
Dado que el cdigo que se genera es JAVA , el cual permite establecer conexiones con las bases de datos, y que no existe una traduccin directa de la sentencia original al resto de gestores de bases de datos se interpretar esta sentencia como el cerrar la conexin que, hasta el momento, haba abierta con la base de datos. Las conexiones se establecen con la base de datos usando el JDBC de java que posibilita una forma de acceso a una base de datos va JDBC y ODBC. La clase que controla esto es: Connection del paquete java.sql y suministra un mtodo que permite cerrar las conexiones: java.sql.Connection.close(). Por tanto cuando en el cdigo fuente encontremos una sentencia CLOSE DATABASE se traducir en cerrar la conexin actual a la base de datos. En el Anexo I, en el punto: Ejemplo sentencias conexin/desconexin se muestra el cdigo fuente y objeto de un programa en el que se tratan las sentencias de conexin y desconexin con la base de datos. Al tratarse de sentencias basadas en los estndares de conexin/desconexin definidos por el API JDBC de JAVA el cdigo objeto ser igual independientemente del gestor de bases de datos destino. Si se observa el cdigo objeto generado se puede ver que no se hace referencia directamente a la clase java.sql.Connection. Se han embebido todas las funciones de conexin a la base de datos en una clase propia llamada: AccesDB y dentro de esta se han definido las funciones:

106 new AccesDB("datos") se encarga de establecer la conexin por primera vez a la base de datos al tiempo que inicializa la clase. ASGdb.iniConexionDB("datos2") establece la conexin con la base de datos. ASGdb.finConexionDB() finaliza la conexin actual con la base de datos.

SENTENCIA COMMIT WORK


Esta sentencia marca el fin de una transaccin correcta y hace que todas las modificaciones efectuadas sobre los datos desde el inicio de la transaccin pasen a formar parte permanente de la base de datos. Esta sentencia no es incorporada ni por el estndar SQL89 ni por el estndar bsico SQL92 aunque todos los gestores de bases de datos la incorporan, incluido Informix-SQL, razn por la cual se incorpora a la hora de traducir el cdigo fuente. Al igual que ocurra con la sentencia BEGIN WORK cada gestor incorpora su propia sentencia pero la solucin que se adoptar a la hora de generar cdigo es independiente del gestor y se basa en las posibilidades que aporta el JDBC de JAVA. Por esta razn no nos pararemos a estudiar en detalle la sentencia del resto de gestores.

SINTAXIS DE INFORMIX
<COMMIT WORK> ::= COMMIT WORK

GENERACIN DE CODIGO
La generacin de cdigo, al igual que con la sentencia BEGIN WORK, se hace de forma independiente al gestor de base de datos para el cual se este traduciendo. La traduccin ser la siguiente: Connection.commit() Connection.setAutoCommit( true ) Este cdigo hace dos acciones, primero hace que la modificaciones efectuadas, en la base de datos, desde el inicio de la transaccin pasen a forma parte de la base de datos de forma permanente; y segundo cierra la transaccin. El cdigo objeto obtenido de las sentencias de tratamiento de transacciones no ser dependiente del gestor de bases de datos ya que se utilizan funcionalidades propias del API JDBC. En el punto: Ejemplo sentencias de tratamiento de transacciones, perteneciente al Anexo I se muestran ejemplos prcticos.

SENTENCIA CREATE AUDIT


Permite crear un log para una tabla de la base de datos. Esta sentencia no es soportada, de igual modo que Informix-SQL, por ningn otro gestor de bases de datos aunque de una forma u otra todo gestor de bases de datos mantiene un log de las operaciones que se hacen sobre la base de datos. El estndar SQL89 no la contempla e InformixSQL tampoco en su versin 4.10, la incorpora como una ampliacin.

SINTAXIS DE INFORMIX
<CREATEAUDIT>::= CREATE AUDIT FOR [ nombretabla | nombresinonimo] ON path

GENERACIN DE CDIGO
Esta es una sentencia de administracin la cual se suele ejecutar directamente sobre la herramienta de administracin, su uso dentro de un programa es nulo, no es soportada por ningn otro gestor de base de datos, y tampoco por ningn estndar por esta razn no se traducir a

107 cdigo objeto. Si aparece en el cdigo fuente se indicar por pantalla, durante el proceso de traduccin, el no procesamiento de la misma con el siguiente mensaje: Mensaje: Warning: Sentencia crate audit. no generada

SENTENCIA CREATE DATABASE


Esta sentencia permite crear una base de datos. El nombre de la base de datos debe de ser nico dentro del gestor de base de datos en el que se crea. El gestor de base de datos crea el catalogo del sistema el cual contiene el diccionario de datos. Una cosa a tener en cuenta, a nivel de programacin, es que para crear una base de datos nueva primero a de haber una conexin con el gestor de bases de datos (lo que implica con otra base de datos existente). Una vez creada la base de datos esta pasa a ser la base de datos actual. Para poder crear la base de datos en necesario tener los privilegios suficientes y al tiempo de hacer esto, en algunos gestores, ser preciso crear: usuarios, esquemas, etc. Esta sentencia no es contemplada por el estndar SQL89, Informix-SQL lo amplia al usarla, tampoco es soportada por el SQL92 aunque de una forma u otra todo gestor de bases de datos la implementa.

SINTAXIS DE INFORMIX
<CREATE DATABASE> ::= CREATE DATABASE nombrebasedatos [ WITH LOG IN nombrearchivo [ MODE ANSI] ] La opcin WITH NO LOG permite crear una base de dates en modo transaccional. El archivo: nombrearchivo es usado para guardar las transacciones mientras estas no forman parte de forma definitiva de la base de datos.

SINTAXIS DE SQLSERVER
<CREATEDATABASE> ::= CREATE DATABASE nombrebasedatos [ ON [PRIMARY] [ <ficheroespecificaciones> [,n] ] [, <grupoarchivos> [,n] ] ] [ LOG ON { <ficheroespecificaciones> [,n]} ] [ FOR LOAD | FOR ATTACH ] <ficheroespecificaciones> ::= ( [ NAME = nombrearchivolgico, ] FILENAME = 'nombrearchivo' [, SIZE = tamao] [, MAXSIZE = { tamaomximo | UNLIMITED } ] [, FILEGROWTH = incrementocrecimiento] ) [,n] <grupoarchivos>::= FILEGROUP nombregrupoarchivos <ficheroespecificaciones> [,n] En la sintaxis de SqlServer admite especificar muchas ms opciones que la original, de InformixSQL, de la que partimos. El propio gestor de base de datos es capaz de crear la base de datos indicndole exclusivamente el nombre de la base de datos, el resto de valores se inicializan con los valores predeterminados.

SINTAXIS DE ORACLE
<CREATEDATABASE> ::= CREATE DATABASE nombrebasedatos [DATABASE_ID nmeroentero] [DATABASE_SIZE nmeromegas] [EXTENT_SIZE nmerokbs ]

108 La sentencia de Oracle soporta muchos ms parmetros que Informix. Pero si estos no se ponen, como ser el caso, tomar los valores prefijados por defecto para el gestor de bases de datos.

SINTAXIS DE DB2
<CREATEDATABASE> ::= CREATE [DATABASE | DB] nombrebasedatos [ [AT NODE ] | [ <createdatabaseoptions>] ] <createdatabaseoptions> ::= ON [camino | unidad ] | ALIAS aliasdebasededatos | USING CODESET codeset TERRITRY territorio | COLLATE USING [ SYSTEM | COMPATIBILITY IDENTITY ] | NUMREGS nmeroregistros | DFT_EXTENT_SZ defaulextencion | CATALOG TABLESPACE tablespacedefinicion | USER TABLESPACE tablespacedeusuario | TEMPORALY TABLESPACE tablespacetemporal | WITH cadenacaracteres Al igual que ocurra con los gestores de bases de datos SqlServer y Oracle, Db2 admite una sintaxis mucho mas completa que la que admite Informix-SQL.

GENERACION DE CODIGO
Esta es una sentencia de administracin que no se ejecuta desde un programa y en algunos casos incluso ni siquiera es posible, siempre se crean las bases de datos a travs de la herramienta de administracin ya que cada gestor tienes sus peculiaridades. Si se observa con detenimiento la sentencia de Informix-SQL podemos considerar dos partes diferenciadas, la primera que la subsentencia que crea la base de datos propiamente dicha, y la segunda, la cual es exclusiva de Informix-SQL y de su motor SE, que permite especificar que la base de datos que se crea va a admitir transacciones. Por tanto a la hora de traducir la sentencia se pueden dar dos situaciones: 1.- Que la sentencia original sea: CREATE DATABASE nombrebasedatos. La traduccin a los gestores destino sera inmediata, aunque debe tenerse en cuenta que hay gestores que no admiten lanzar esta sentencia desde una conexin JDBC, como es el caso de: Oracle y Db2. 2.- Que la sentencia original incluya la clusula : WITH LOG IN ..... En este caso esta segunda parte ser omitida a la hora de traducir la sentencia a no ser que el cdigo destino se vaya a ejecutar contra el gestor de bases de datos de Informix-SQL (motor SE), debido a que el restos de gestores estudiados al crear las bases de datos ya la entiende como transaccionales. Se ha de tener en cuenta que para que esta sentencia se ejecute sobre el gestor de bases de datos destino se ha de tener suficientes privilegios sobre el mismo, a continuacin se muestran algunos detalles a tener en cuenta si se pretende incluir esta sentencia dentro de un programa: Informix. El usuario que lanza la sentencia a de administrador de la bases de datos: informix u otro perteneciente al grupo Informix-Admin. Por defecto se crea la base de datos en modo no transaccional. SqlSever. El usuario ha de ser sysadm. Para este gestor hay que tener en cuenta que tras crear la base de datos no se conecta automticamente a ella como ocurre con Informix, esto se tendr en cuenta al generar cdigo aadiendo la sentencia de conexin a la nueva base de datos en el mismo. Oracle. Aunque es posible la sentencia a generar debe incluir mucha informacin adicional como: lugar de los tablespaces de datos, de log, etc. Informacin que no se extrae del cdigo fuente con lo cual es altamente recomendable no usarla. Db2. Aunque admite la sentencia obliga a que para ser ejecutada no se este conectado a la ninguna base de datos lo cual impide de todas formas el lanzar la sentencia desde un programa JAVA.

109

SENTENCIA CREATE INDEX


Esta sentencia permite crear un ndice para una o ms columnas de una tabla determinada. Slo el propietario de la tabla, o un usuario con suficientes privilegios, puede crear ndices en ella. El propietario de una tabla puede crear un ndice en cualquier momento, independientemente de que haya datos en la tabla o no.

SITAXIS DE INFORMIX
<CREATEINDEX> ::= CREATE [UNIQUE|DISTINCT] [CLUSTER] INDEX nombreindice ON nombretabla ( {nombrecolumna [ASC| DESC]} [,...n] ) UNIQUE y DISTINCT son sinnimos y en caso de especificar uno de ellos no se permitirn valores duplicados para las columnas que se indexan. La opcin CLUSTER obliga a que las filas de la tabla se ordenen en funcin de los valores de las columnas indexadas. ASC/DESC permite especificar una restriccin de los valores que tome la columna indexada, obligando a que tengan valores ascendentes (por defecto) o descendentes. Esta sentencia no cumple el estndar SQL92 aunque todos los gestores aqu estudiados la incorporan con sus propias particularidades.

SINTAXIS DE SQLSERVER

<CREATEINDEX> ::= CREATE [UNIQUE] [ CLUSTERED | NONCLUSTERED ] INDEX nombreindice ON nombretabla ( nombrecolumna [ASC |DESC ] [,n]) [ INCLUDE ( nombrecolumna [ ,...n ] ) ] [ WITH ( <indice_relacional_opcional> [ ,...n ] ) ] [ ON { nombreesquema ( nombrecolumna ) | Nombregrupoficheros | default } ]

SINTAXIS DE ORACLE

<CREATEINDEX> ::= CREATE [UNIQUE] INDEX [<esquema>] nombreindice ON [<esquema>] nombretabla ( {nombrecolumna [ASC|DESC]} [,...n] ) Esquema representa el nombre de una coleccin de objetos de la base de datos.

SINTAXIS DE DB2
<CREATEINDEX> ::= CREATE [UNIQUE] INDEX nombreindice ON nombretabla ( {nombrecolumna [ASC|DESC]} [,...n] ) [SPECIFICATION ONLY] [ INCLUDE ( {columna [ASC|DESC]} [,...n] ) ] [CLUSTER | EXTED USING nombreextensionindice [ ( {expresionconstante [,...n] ) ] ] [PCTFREEE [10|nmeroentero] ] [MINPCTUSED nmeroentero] [ DISALLON REVERSE SCANS | ALLOW REVERSE SCANS ]

GENERACIN DE CODIGO
Si se observa la sentencia original de Informix-SQL y aquellas a las que se trata de traducir se puede ver que todos los gestores estudiados la soportan casi en su totalidad adems aportan sus propias funcionalidades. Los nicos problemas que se plantean estn en las opciones CLUSTER, UNIQUE/DISTINCT. CLUSTER no es soportada por ningn otro gestor y se omitir su traduccin. La opcin DISTINCT que incorpora Informix-SQL no existe para el resto de gestores pero al ser equivalente a UNIQUE, que si es incorporada por todos los gestores, se sustituir por esta. El omitir el parmetro CLUSTER no plantea ningn problema en el funcionamiento normal de cada gestor de bases de datos solo se ocasionan pequeas variaciones en la eficiencia de las bsquedas.

110 En el Anexo I se muestra un ejemplo de la traduccin de esta sentencia, ver: Ejemplo sentencia creacion indice-

SENTENCIA CREATE SYNONYM


Crea un sinnimo para una tabla o vista. Esta sentencia no es soportada por el estndar SQL89 y tampoco por el SQL92, aunque InformixSQL la incorpora como una aplicacin a su versin 4.10. Todos los gestores en las versiones mnimas indicadas la contemplan. SqlServer la incorpora por primera vez en la versin 2005.

SINTAXIS DE INFORMIX
<CREATESYNONYM> ::= CREATE SYNONYM nombresinonimo FOR [nombretabla | nombrevista ] Informix-SQL define los sinnimos como pblicos lo que implica que dicho sinnimo puede ser utilizado por cualquier usuario de la base de datos. Si desaparece el objeto sobre el que se creo el sinnimo de la base de datos ste desaparece tambin. Informix no permite crear dos sinnimos con el mismo nombre aunque sea sobre distinto objeto.

SINTAXIS DE SQLSERVER
<CREATESYNONYM> ::= CREATE SYNONYM [ esquema . ] nombresinonimo FOR nombreobjeto Donde nombreobjeto: procedimiento almacenado, funcin, vista o tabla definida por el usuario. No es necesario que el objeto base exista en el momento de crear el sinnimo. SQL Server comprueba la existencia del objeto base en tiempo de ejecucin. No se necesitan permisos en el objeto base para compilar correctamente la instruccin CREATE SYNONYM, porque la comprobacin de los permisos para el objeto base no se realiza hasta el momento de la ejecucin. La definicin del sinnimo persiste aunque la tabla sobre el que se defini desaparezca. Si se crea un sinnimo con igual nombre a otro ya existente permanece la definicin del ltimo.

SINTAXIS DE ORACLE
<CREATESYNONYM> ::= CREATE [ PUBLIC ] SYNONYM [ <esquema> ] nombresinonimo FOR [ <esquema> ] <nombreobjeto> <nombreobjeto> ::= nombretabla | nombrevista | secuencia | sinnimo En caso de no poner explcitamente la opcin PUBLIC se entiende que es privado. Un sinnimo privado solo podr ser utilizado por el usuario que lo defini. La definicin del sinnimo persiste aunque desparezca el objeto inicial al que haca referencia. En caso de que se defina dos sinnimos con igual nombre, aunque sea sobre distinto objeto, no se produce ningn error y ser valida la ltima definicin del sinnimo.

SINTAXIS DE DB2
<CREATESYNONYM> ::= CREATE [ ALIAS | SYNONYM ] nombresinonimo FOR <nombreobjeto> <nombreobjeto> ::= nombretabla

111 | nombrevista | nickname | sinnimo Un nickname es un identificador que hace referencia a una porcin de cdigo fuente. El acceso al sinnimo ser el mismo que el que tenga el objeto del cual se crea el sinnimo. Si se elimina de la base de datos el objeto al que hace referencia el sinnimo ste se mantiene en la misma. Esto puede provocar errores de ejecucin de programas. Si se crea dos sinnimos con igual nombre ser valida la ltima definicin.

GENERACIN DE CDIGO
Esta sentencia es soportada por todos los gestores de bases de datos aqu estudiados. Consideraciones a tener en cuenta: Existe distinto comportamiento entre Informix y el resto de gestores en cuanto a la redefinicin de un sinonino (crear otro sinnimo con el nombre de uno que ya existe). Informes no lo permite y el resto s. Como los programas originales se entiende son correctos para Informix no se plantea ningn problema de consistencia a la hora de ejecutar los programas, traducidos, sobre el resto de gestores, no se podr producir este caso. Debido a la diferente interpretacin que hacen los distintos gestores de bases de datos de la sentencia DROP TABLE (ver pgina 124), se puede estar intentado crear un sinnimo que ya existe. Para solucionar este problema hay varias alternativas: 1. Intentar averiguar los sinnimos asociados a la tabla que se va a borrar y borrar estos. 2. Mantener una estructura suplementaria con los sinnimos que se han creado y sobre que tablas se creado para cuando se borre esta ltima borrar los primeros. 3. Antes de crear un sinnimo hacer, controlando no se generen errores, un DROP del mismo. De las tres soluciones las dos primeras se desechan bien por coste en tiempo de ejecucin o inviabilidad de las misma ya que no todo sinnimo se genera desde un programa. La tercera alternativa es la que ms se ajusta al comportamiento del programa origina sobre el gestor original, ya que s sobre Informix se elimina la tabla la definicin del sinnimo sobre la misma desaparece y por otro lado tampoco permite dos sinnimos con el mismo nombre. Por tanto a la hora de generar cdigo para el resto de gestores se aadir una sentencia DROP SYNONYM antes de la creacin del mismo. En el apartado: Ejemplo sentencia creacion de sinonimo, del Anexo I se muestran ejemplos de la traduccin de esta sentencia para ser ejecutada sobre cada uno de los gestores de bases de datos estudiados.

SENTENCIA CREATE TABLE


Permite definir una tabla en la base de datos. La definicin debe incluir su nombre as como el nombre y atributos de sus columnas. La definicin tambin puede incluir otros atributos de la tabla, tales como: clave primaria y restricciones. Esta sentencia esta soportada por el estndar SQL92. Estudiando en detalle la sentencia que definen los distintos gestores de bases de datos se pude ver que estos no soportan en su totalidad el estndar aunque si se ajustan bastante a l. Esta sentencia tambin permite la creacin de tablas temporales. Las tabla temporales solo pueden ser vistas por el usuario que creo dicha tabla y su vida es la misma que la aplicacin desde la cual se creo. Cuando se sale de la aplicacin, se finaliza la sesin, que creo la tabla temporal esta se elimina automticamente.

112 Las tablas temporales deben tener distinto nombre que una tabla, vista o sinnimo existente en la base de datos actual. Sin embargo pueden tener el mismo nombre que otra tabla temporal creada por otro usuario.

SINTAXIS DE INFORMIX
<CREATETABLE> ::= CREATE [ TEMP ] TABLE nombretabla <lista de elementos de la tabla> [ IN camino ] <lista de elementos de la tabla> ::= ( <elemento de la tabla> [, ... n] ) <elemento de la tabla> ::= <definicin de columna> | <restriccin de tabla> <definicin de columna> ::= nombrecolumna <tipodatosql> [NOT NULL] [<restricciones de columna> ]

<restricciones de columna> ::= [ UNIQUE|DISTINCT] [ CONSTRAINT nombrerestriccion ] <restriccin de tabla> ::= { [UNIQUE|DISTINCT] (nombrecolumna [,n]) } [ CONSTRAINT nombrerestriccion ] La opcin IN camino permite indicar la ubicacin fsica de la tabla, sino se especifica ninguna se crear: las tablas temporales donde indique la variable de entorno DBTEMP y las otras donde este creada la base de datos lo cual viene indicado por la variable de entono DBPATH. Si alguna de estas variables de entorno no estn declaradas las tablas se crearan en el lugar desde el cual se ejecuta la sentencia.

SINTAXIS DE SQLSERVER
<CREATETABLE> ::= CREATE TABLE [ nombrebasedatos. [ propietario.] | propietario. ] nombretabla ( { <definicion de columna> | nombredecolumna AS expresin | <restriccin de tabla> } [, ...n ] ) [ ON { grupodeficheros | DEFAULT } ] [ TEXTIMAGE_ON { grupodeficheros | DEFAULT } ] <definicin de columna> ::= { nombrecolumna tipodatosql } [ COLLATE < nombrecollate > ] [ [ DEFAULT expresioncte ] | [ IDENTITY [ (semilla , incremento) [ NOT FOR REPLICATION ] ] ] ] [ ROWGUIDCOL] [ <restriccin de columna> ] [ ...n ] <restriccindecolumna> ::= [ CONSTRAINT nombrerestriccion ] { [ NULL | NOT NULL ] | [ { PRIMARY KEY | UNIQUE } [ CLUSTERED | NONCLUSTERED ] [WITH FILLFACTOR = nmero] [ON {grupodeficheros| DEFAULT} ] ] ] | [ [ FOREIGN KEY ] REFERENCES tablareferencia [ ( columnareferencia ) ] [ ON DELETE { CASCADE | NO ACTION } ] [ ON UPDATE { CASCADE | NO ACTION } ] [ NOT FOR REPLICATION ]

113 ] | CHECK [ NOT FOR REPLICATION ] ( expression ) } <restriccindetabla> ::= [ CONSTRAINT nombrerestriccion ] { [ { PRIMARY KEY | UNIQUE } [ CLUSTERED | NONCLUSTERED ] { ( columna [ ASC | DESC ] [ ,...n ] ) } [WITH FILLFACTOR = nmero] [ ON { grupodeficheros | DEFAULT } ] ] | FOREIGN KEY [ ( columna [ ,...n ] ) ] REFERENCES tablareferencia [ ( columnareferencia [ ,...n ] ) ] [ ON DELETE { CASCADE | NO ACTION } ] [ ON UPDATE { CASCADE | NO ACTION } ] [ NOT FOR REPLICATION ] | CHECK [ NOT FOR REPLICATION ] ( expresion ) } SqlServer permite crear tablas temporales locales y globales. Las tablas temporales locales son visibles slo en la sesin actual; las tablas temporales globales son visibles para todas las sesiones. Para definir una tabla temporal se coloca un prefijo de signo numrico simple (#nombretabla) en los nombres de las tablas temporales locales y un prefijo de un signo numrico doble (##nombretabla) en los nombres de las tablas temporales globales. Si se crea una tabla temporal local en un procedimiento almacenado o una aplicacin que varios usuarios pueden ejecutar al mismo tiempo, SqlServer es capaz de distinguir las tablas creadas por los distintos usuarios. SqlServer hace esto al anexar internamente un sufijo numrico a cada nombre de tabla temporal local. El nombre completo de una tabla temporal tal como se almacena en la tabla sysobjects de tempdb consta del nombre de la tabla especificado en la instruccin CREATE TABLE y el sufijo numrico generado por el sistema. Para permitir que se agregue el sufijo, el nombretabla especificado de un nombre temporal local no puede exceder de 116 caracteres. Las tablas temporales se eliminan automticamente cuando estn fuera de mbito. Si no se especifica el usuario por defecto, Sqlserver, crear la tabla con el propietario dbo aunque hayamos iniciado sesin con otro diferente.

SINTAXIS DE ORACLE
<CREATETABLE> ::= CREATE [GLOBAL TEMPORARY] TABLE [ <esquema> . ] nombretabla <lista de elementos de la tabla> <lista de elementos de la tabla> ::= ( <elemento de la tabla> [, ... n] ) [ ON COMMIT {PRESERVER | DELETE } ROWS ] <elemento de la tabla> ::= <definicion de columna> | < restriccin de tabla > <definicion de columna> ::= nombrecolumna <tipodatosql> [DEFAULT expresin] [<restricciones de columna> ]

<restricciones de columna> ::= [ CONSTRAINTS nombrerestriccion ] { [NOT] NULL | [ UNIQUE | PRIMARY KEY ] | <clusula referencia> | <clusula chek> }

114 <clusula referencia> ::= REFERENCES <esquema> nombretabla [ ( nombrecolumna [,n] ) ] [ ON DELETE CASCADE] <clusula check> ::= CHECK ( <condicin> ) < restriccin de tabla > ::= [ CONSTRAINTS nombrerestriccion ] { [NOT] NULL | [ UNIQUE | PRIMARY KEY ] { ( columna [ ,...n ] ) | FOREIGN KEY ( columna [ ,...n ] ) <clusula referencia> | <clusula chek> } En oracle tambin se permite la creacin de tablas temporales, para ello se ha de indicar utilizando las palabras reservadas GLOBAL TEMPORARY. La definicion de la tabla es visible por todas las sesiones del mismo usuario. Los datos de la tabla temporal son solo visibles por la sesin que inserto los datos en la misma. En oracle la definicin de una tabla temporal persiste, de igual modo que las tablas normales, para el usuario que la creo, pero su contenido tiene una vida limita que puede ser mientras dure la transaccin o la sesin. Se especifica la vida de los datos en la tabla temporal con la clusula ON COMMIT. Si es seguida de la opcin PRESERVE la vida de los datos es mientras este activa la sesin en caso contrario, opcin DELETE, la vida es hasta el fin de la transaccin en curso. Sino se especifica explcitamente la clusula ON COMMIT se asume por defecto que los datos se mantienen en la tabla temporal mientras dure la transaccin.

SINTAXIS DE DB2
<CREATETABLE> ::= CREATE [SUMMARY] TABLE nombretabla <lista opciones de la tabla> [ DATA CAPTURE NONE | DATA CAPTURE CHANGES] [ IN nombretablespace [<opciones de talespace>] ] [ PARTITIONING KEY ( nombrecolumna [,n] USING HASHING) | REPLICATED ] [ NOT LOGGED INITIALLY] <lista opciones de la tabla> ::= <lista de elementos de la tabla> | OF nombretipo [ <opcionestipotabla>] | <resumen de definicin de tabla> | LIKE [ nombretabla1 | nombrevista1 | nomnbrenick] [<opcionesdecopia>] <lista de elementos de la tabla> ::= ( <elemento de la tabla> [, ... n] ) <elemento de la tabla> ::= <definicin de columna> | <restriccin de tabla> <definicion de columna> ::= nombrecolumna <tipodatosql> [<restriccin de columna> ]

<restriccin de columna> ::= NOT NULL | [LOGGED|NOT LOGGED] [COMPACT|NOT COMPACT] | CONSTRAINT nombrerestriccion [ [ UNIQUE | PRIMARY KEY ] | <clusula referencia> | <clusula chek> ] <clusula referencia> ::= REFERENCES nombretabla [ ( nombrecolumna [,n] ) ] [<reglasclausula>] <reglasclausula> ::= [ ON DELETE NO ACTION | ON DELETE [RESTRICT|CASCADE|SET NULL] ] [ ON UPDATE NO ACTION | ON UNPDATE RESTRICT]

115 <clusula check> ::= CHECK ( <condicin> ) <restriccindetabla> ::= <restriccin nica> | <restriccin referencial> | <restricciones check> <restriccin nica> ::= [CONSTRAINTS nombrerestriccion] {UNIQUE|PRIMARY KEY} ( nombrecolumna [,n])

<restriccin referencial> ::= CONSTRAINTS nombrerestriccion] FOREIGN KEY ( nombrecolumna [,n]) <clusula referencia> <restriccin check> ::= [CONSTRAINTS nombrerestriccion] CHECK (concidioncheck) La creacin de tablas temporales es admitida pero no con la sentencia CREATE sino con la DECLARE que se especifica a continuacin. <CREATETABLE>::= DECLARE GLOBAL TEMPORARY TABLE nombretabla <lista opciones de la tabla> [WITH REPLACE] [ON COMMIT DELETE ROWS | ON COMMIT PRESERVE ROWS] [NOT LOGGED][IN nombretablespace ] [ PARTITIONING KEY ( nombrecolumna [,n] USING HASHING) ] <lista opciones de la tabla>::= <lista de elementos de la tabla> | LIKE [ nombretabla1 | nombrevista1] [<opcionesdecopia>] | AS ( <sentenciaselectcompleta> ) [<opcionesdecopia>] <lista de elementos de la tabla> ::= ( <elemento de la tabla> [, ...n] ) <elemento de la tabla> ::= nombrecampo <tipodatosql> [<definicin de opciones de columna> ] <definicion de opciones de columna> ::= NOT NULL | [WITH] DEFAULT [valordefecto] La sentencia DECLARE GLOBAL TEMPORARY TABLE define una tabla temporal para la sesin actual. La definicin de la tabla temporal declarada no aparece en el catalogo del sistema no es permanente y no puede ser compartida con otras sesiones. Cada sesin que define una tabla temporal con el mismo nombre tiene su propia y nica descripcin de la tabla temporal. Cuando una sesin termina las filas de la tabla temporal son borradas y la definicin de la tabla temporal es eliminada. Db2 tiene ms limitaciones a la hora de crear las tablas temporales que las normales ya que no admite la definicin de restricciones sobre las mismas a excepcin de NOT NULL.

GENERACIN DE CODIGO
Esta sentencia se puede ver como dos claramente diferenciadas: la creacin de tablas temporales, y la creacin de tablas normales. En la creacin de tablas normales la sentencia original de Informix-SQL es altamente compatible con cualquier otro gestor de bases de datos. A nivel general solo se plantean 2 problemas: La definicin de constraints. Esta definicin es igual a la que haba en la sentencia ALTER TABLE (ver pgina 99) y por lo tanto el estudio realizado en dicha seccin es idnticamente valido para sta. La opcin IN caminio de la sentencia CREATE TABLE no es soportada por ningn otro gestos de bases de datos en el mismo sentido que la entiende Informix-SQL. Como se explic en la definicin de la sentencia camino indica el path en el cual se define la tabla, ste es una direccin fsica dentro del sistema operativo en la cual se crear uno o ms archivos que contendrn la informacin de la tabla de la base de datos. El resto de gestores de bases de datos estudiados contienen administradores ms avanzados a travs de los cuales se indica la ubicacin del espacio de datos en el cual se almacenan todas las tablas.

116 Debido a que ningn otro gestor asocia un nombre de fichero fsico a una tabla y a que a travs de su administrador se especifica un espacio de datos comn para todas las tablas esta opcin: IN camino se omitir para ellos. En caso de informix se atender a la variable de entorno DBPATH. DB2, como se comento al tratar la sentencia ALTER TABLE, no permite aadir una constraint UNIQUE a un campo si este admite valores NULOS. Este problema es difcil de controlar y corregir a la hora de realizar el proceso de traduccin de cdigo ya que por un lado el aadir esta restriccin puede realizarse de forma independiente a la definicin de la columna y por otro el aadir la clusula NOT NULL en la definicin de la columna significa que se est variando la definicin de la tabla realizada en el cdigo fuente original. En el proceso de traduccin, con objeto de intentar evitar errores al ejecutar el programa resultante, se aadir la clusula NOT NULL solo si aparece UNIQUE durante la definicin del campo. Ejemplo: Fuente Informix: create table tabla1 ( campo1 smallint, campo2 char(10) unique, distinct (campo1) constraint constr1, ) Cdigo objeto Db2: create table tabla1 ( campo1 smallint , campo2 char(10) not null unique , constraint constr1 unique ( campo1 ), ) Como se puede observar al definir el campo2 se le aade la condicin NOT NULL debido a que al tratar el campo se puede tomar esa decisin, pero no ocurre lo mismo con el campo1 y posteriormente al intentar crear la restriccin se producir un error sino existe una revisin posterior del cdigo generado. El resto de la sentencia original de Informix-SQL es completamente aceptado por los dems gestores de bases de datos estudiados. Slo queda analizar si los tipos de datos de Informix-SQL son compatibles y/o soportados por el resto de gestores lo cual se estudiar en la seccin: Estudio tipos de datos (ver pgina 154). En el Anexo I, en el punto: Ejemplo sentencia, se muestra un ejemplo del uso del traductor aplicado a esta sentencia. En cuanto a la generacin de tablas temporales hay ms peculiaridades que analizar. Aparte de que sintcticamente se definan de forma distinta algo muy importante a estudiar es la semntica de la definicin. Todos los gestores, y particularmente Informix-SQL, entienden que cuando se finaliza el programa que creo la tabla temporal esta desaparece totalmente: datos y definicin a excepcin de Oracle en el cual la definicin de la tabla perdura en el tiempo, esto plantea un problema bastante difcil de salvar al intentar trasformar la sentencia original de Informix-SQL a Oracle con la misma semntica. Sintcticamente la definicin de Informix-SQL de las tablas temporales es ms simple que la de las tablas normales, como se detalla a continuacin: Incorpora el token TEMP precediendo al token TABLE. El resto de gestores no lo incorporan pero adoptan otra sintaxis que no plantea ningn problema a la hora de traducir la sentencia original como se muestra a continuacin: Sintaxis Informix-SQL: Sintaxis de SqlServer: CREATE TEMP TABLE tablatemporal CRETE TABLE #tablatemporal

117 Sintaxis de Oracle: Sintaxis de DB2: CREATE GLOBAL TEMPORARY TABLE tablatemporal DECLARE GLOBAL TERMPORARY TABLE tablatemporal

La sintaxis que hay hasta el nombre de la tabla temporal es esttica con lo cual en el momento que aparece el nombre de la tabla, a la hora de analizar el cdigo fuente, se genera una sentencia u otra en funcin del gestor de base de datos destino. Tanto en la definicin de restricciones de tabla como de columna no contempla la posibilidad de asociarles un nombre lo que implica que la definicin sintctica de restricciones es equivalente para todos los gestores de bases de datos aqu estudiados. La opcin in CAMINO es igual en la sentencia: CREATE TEMP TABLE que en: CREATE TABLE. La solucin ser la misma, que la planteada en este ltimo caso. Si se est generando cdigo para Informix-SQL se atender a la variable de entorno DBPATH en lugar de DBTEMP.

En cuanto al problema planteado con el gestor de bases de datos oracle se proponen varias soluciones: Mantener en una estructura, en tiempo de ejecucin, la relacin de las tablas temporales creadas y al salir del programa principal eliminarlas. Esto no es tan fcil, puesto que Informix es un lenguaje de programacin multimdulo y habra que mantener la relacin de tablas temporales de cada mdulo para luego eliminarlas en el mdulo principal. No mantener ninguna estructura y cuando se vaya a crear una tabla temporal borrarla primero teniendo en cuenta que en caso de que no exista dicha tabla temporal no se genere ningn error. Esta solucin no es muy limpia puesto que siempre se mantendrn las tablas temporales como parte de la base de datos. La ltima solucin propuesta es generar la tabla temporal controlando que en caso de que ya exista no se genere ningn error. Esta solucin es equivalente a la anterior pero no contempla el caso de que el esquema de la tabla temporal ya definida no coincida con la que el programa en curso trata de crear.

La solucin que se va a adoptar para el caso de las tablas temporales de Oracle es la segunda de las propuestas puesto que ofreciendo todas las misma funcionalidad es las ms simple de implementar manteniendo la ltima estructura de tabla. Como se comento al definir la sintaxis de SqlServer sino se indica explcitamente el usuario por defecto toma como usuario de creacin de la tabla el usuario dbo, y esto puede dar problemas al traducir otras sentencias que en el cuerpo de la misma indiquen el usuario, ejemplo: select usuario.tabla.campo from ..... Para evitar esto a la hora de pasar el cdigo fuente a un cdigo objeto ejecutable sobre SqlServer se especificar el propietario de la tabla, el cual se puede obtener de la cadena de conexin contra la base de datos. El resto de gestores de bases de datos crean la tabla con el propietario igual al usuario que esta conectado a la base de datos. En el caso de Db2 si en la definicin original de la tabla temporal hay restricciones estas no se generarn en el cdigo objeto. Este hecho se notificar en tiempo de traduccin mediante un Warning. Un aspecto que hasta ahora no se ha tenido en cuenta y que empieza a tener relevancia es la definicin de tipos de datos en los distingos gestores de bases de datos estudiados. Este punto lleva un estudio detallado el cual se realiza en el apartado: Tipos de datos (ver pgina 154) En el Anexo I, apartado: Ejemplo sentencias creacion tabla temporal, se muestran ejemplos del uso de esta sentencia.

SENTENCIA CREATE VIEW


Crea una tabla virtual que representa los datos de una o ms tablas de una forma alternativa. Las vistas se pueden utilizar como mecanismos de seguridad al conceder permisos sobre una vista, pero no sobre las tablas subyacentes (base). Esta sentencia es soportada por el estndar SQL92, y todos los gestores de bases de datos aqu estudiados se ajustan al estndar SQL92 y en algunos casos lo extienden.

118 Informix-SQL se ajusta completamente al estndar, la nica limitacin podra venir dada por la definicin de la sentencia SELECT la cual es estudia ms adelante al analizar dicha sentencia (ver pgina 143).

SINTAXIS DE INFORMIX
<CREATEVIEW> ::= CREATE VIEW nombrevista [ ( nombrecolumna [,...n] ) ] AS <sentenciaselect> [ WITH CHECK OPTION ] La opcin WITCH CHECK OPTION indica al gestor de base de datos que cualquier modificacin hecha a travs de la vista en la/s tabla/s o vista/s en las cual se basa sta deben de cumplir las condiciones indicadas en la definicin de la misma (sentencia select).

SINTAXIS DE SQLSERVER
<CREATEVIEW> ::= CREATE VIEW nombrevista [ ( nombrecolumna [,n]) ] [WITH ENCRYPTION] AS <sentenciaselect> [WITH CHECK OPTION]

SINTAXIS DE ORACLE
<CREATEVIEW> ::= CREATE [OR REPLACE] VIEW [<esquema>] nombrevista [ ( nombrecolumna [,...n] ) ] AS <sentenciaselect> [ WITH [ READ ONLY | CHECK OPTION [ CONSTRAINT nombrerestriccion ] ]

SINTAXIS DE DB2
<CREATEVIEW> ::= CREATE [FEDERATED] VIEW nombrevista [ ( nombrecolumna [,...n] ) ] AS [ WITH {<expresion comun> [,n]} | <sentenciaselect> ] [ WITH [ <clusula levels> ] CHECK OPTION ] <clusula levels> ::= CASCADED | LOCAL <expresin comn> ::= nombretabla [ ( nombrecolumna [,n] ) ] AS ( <sentenciaselect> )

GENERACIN DE CODIGO
La generacin de cdigo no plantea ningn problema puesto que la sentencia original de InformixSQL es soportada en su totalidad e interpretada de igual forma por el resto de gestores de bases de datos. Al igual que ocurra con la sentencia CREATE SYNONYM (ver pgina 111) hay que tener en cuenta que la sentencia DROP TABLE (ver pgina 124) se comporta de forma distinta en el resto de gestores de bases de datos. En ese caso la solucin adoptada es la misma, si el gestor destino no es Informix-SQL se borraran primero las vistas antes de crearlas evitando as errores en tiempo de ejecucin. Para ver un caso practico del comportamiento del traductor con esta sentencia dirigirse al punto: Ejemplo sentencia creacion vista, dentro del Anexo I.

SENTENCIA DATABASE
La sentencia DATABASE permite seleccionar una base de datos accesible como la base de datos actual. Esta sentencia no es soportada por el estndar SQL89 y tampoco por el SQL92 y es una ampliacin que Informix-SQL aade a su versin 4.10. El estndar SQL92 y el resto de gestores de bases de datos contemplan la sentencia CONNECT que permite establecer una conexin con una base de datos del gestor de bases de datos.

119 Los comandos: DATABASE, CREATE DATABASE, START DATABASE, y CONNECT TO database provocan un conexin con la base de datos referenciada en los mismos.

SINTAXIS INFORMIX
<DATABASE> ::= DATABASE <nombrebasedatos> [EXCLUSIVE] <nombrebasedatos> ::= nombrebasedatos | espcificacionbd | < variable> Esta sentencia indica, a partir del punto donde aparece, la base de datos sobre la cual se ejecutan el resto de sentencias SQL del programa. EXCLUSIVE indica que la base de datos se abre en modo exclusivo y evita que cualquier otro usuario pueda acceder a la misma.

GENERACIN DE CODIGO
Dado que el cdigo que se genera es JAVA, el cual permite establecer conexiones con las bases de datos, que no existe una traduccin directa de la sentencia original al resto de gestores de bases de datos y que todo gestor de bases de datos permite especificar, de una forma u otra, la base de datos con la cual se esta trabajando se interpretar esta sentencia como el abrir una conexin con la base de datos que recibe como parmetro. En el caso de que ya hubiese una conexin establecida se cerrar previamente esta. En los Fuentes mostrados en el Anexo I: Ejemplo sentencias conexin/desconexin, se puede ver un ejemplo prctico del uso de esta sentencia. Si se observa el cdigo objeto generado se puede ver que no se hace referencia directamente a la clase java.sql.Connection. Las funciones de conexin a la base de datos estn definidas en una clase propia llamada: AccesDB y dentro de sta, para reflejar la sentencia DATABASE se han defino las siguiente sentencias: static AccesDB ASGdb = null, definicin de una variable de la clase AccesDB. new AccesDB("datos") se encarga de establecer la conexin por primera vez a la base de datos al tiempo que inicializa la clase.

SENTENCIA DECLARE CURSOR


Esta sentencia permite definir un cursor el cual representa un conjunto activo de filas indicadas a travs de una sentencia SELECT.

SINTAXIS DE INFORMIX
<DECLARECURSOR> ::= DECLARE nombrecursor [SCROLL] CURSOR [WITH HOLD] FOR [ <senteniaselect> [<opcforupdate>] | <sentenciainsert> | <variablesentenciapreparada> ] <opcforupdate> ::= FOR UPDATE [OF nombrecolumna [, ..n]] La opcin SCROLL CURSOR indica que si durante el tiempo que se esta procesando las filas del cursor otro usuario modifica los datos de la tabla afectada por el cursor estas modificaciones no sern visibles por el primero. Informix, si se usa esta opcin, hace un recorrido inicial de las tablas afectadas en la <sentenciaselect> y los carga en una tabla temporal, tabla con la cual trabaja durante el procesamiento del cursor. La opcin WITH HOLD permite un acceso ininterrumpido al conjunto de filas durante mltiples transacciones. Normalmente todos los cursores son cerrados al final de una transaccin. La clusula FOR UPDATE indica al gestor de bases de datos que es posible se modifiquen datos durante el recorrido del cursor. Para modificar los datos se puede utilizar la sentencia UPDATE o DELETE con la clusula: WHERE CURRENT OF, que indica la fila actual.

120

SINTAXIS DE SQLSERVER
<DECLARECURSOR> ::= DECLARE nombrecursor CURSOR [LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL] [STATIC | KEYSET | DYNAMIC | FAST_FORWARD] [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC] [TYPE_WARNING] FOR <sentenciaselect> [FOR UPDATE [OF nombrecolumna [,...n]] ]

SINTAXIS DE ORACLE
<DECLARECURSOR> ::= DECLARE CURSOR nombrecursor IS <sentenciaselect>

SINTAXIS DE DB2
<DECLARECURSOR> ::= DECLARE nombrecursor CURSOR [WITH HOLD] FOR [ <sentenciaselect> | <variablesentenciapreparada> ]

GENERACIN DE CDIGO
Como se ve al analizar la sintaxis del resto de gestores no todos ellos definen la sentencia al igual que lo hace Informix-SQL, esto no ser relevante ya que la traduccin a cdigo objeto de la misma se realizar basndose en las sentencias que proporciona el API JDBC de JAVA para el manejo de cursores. A la hora de generar cdigo se entender que todas las sentencias utilizan la opcin WITH HOLD aunque en cdigo fuente no se utilice. Esto se hace as debido a que partimos de un gestor de bases de datos no transaccional y pasamos a otros que normalmente lo son y para los cuales por defecto las sentencias son autoentregables (una sentencia una transaccin). En la seccin: Sentencias de manipulacin dinmica de datos y cursores se mostrarn ejemplos de esta sentencia, junto con el resto de sentencias de manejo de cursores, as como las peculiaridades de su traduccin a cdigo objeto.

SENTENCIA DELETE FROM


Esta sentencia permite eliminar filas de una tabla determinada de la base de datos. Los datos borrados se establecen segn el criterio: En funcin del criterio de bsqueda especificado en la condicin. La fila actualmente posicionada por un cursor.

Esta sentencia segn la especfica Informix-SQL es soportada en su totalidad por el estndar SQL92.

SINTAXIS DE INFORMIX
<DELETEFROM> ::= DELETE FROM <elementoaborrar> [ <restosentdeletefrom> ] <elementoaborrar> ::= nombretabla | nombresinonimo | nombrevista <restosentdeletefrom> ::= WHERE [ <condicionsql> | CURRENT OF nombrecursor ]

121

SINTAXIS DE SQLSERVER
<DELETEFROM> ::= DELETE [FROM] <elementoaborrar> [ <restosentdeletefrom> ] <elementoaborrar> ::= nombretabla | nombrevista | nombresinonimo <restosentdeletefrom> ::= WHERE [ CURRENT OF nombrecursor | <condicionsql> ]

SINTAXIS DE ORACLE
<DELETEFROM> ::= DELETE [FROM] <elementoaborrar> [ <restosentdeletefrom> ] <elementoaborrar> ::= nombretabla | nombrevista | nombresinonimo <restosentdeletefrom> ::= WHERE [ CURRENT OF nombrecursor | <condicionsql> ]

SINTAXIS DE DB2
<DELETEFROM> ::= DELETE [FROM] <elementoaborrar> [ <restosentdeletefrom> ] <elementoaborrar> ::= nombretabla | nombrevista | nombresinonimo <restosentdeletefrom> ::= WHERE [ CURRENT OF nombrecursor | <condicionsql> ]

GENERACIN DE CDIGO
La traduccin de esta sentencia de cdigo fuente, Informix-SQL, a cdigo objeto, java, no platea ningn problema ya que dicho cdigo objeto ser el mismo independientemente del gestor para el cual estemos generando cdigo. En esta sentencia aparece un elemento que debe de ser estudiado con detenimiento para garantizar que la sentencia sea ejecutada con xito en cualquier gestor de bases de datos, este elemento es la condicionsql la cual ser analizada en detalle en el apartado: Operaciones sobre expresiones sql. En el Anexo I, apartado: Ejemplo sentencia delete se muestra ejemplo de la traduccin de esta sentencia. Aqu no se contemplo la generacin de cdigo para la clusula: WHERE CURRENT OF, esta se analizar en la seccin: Sentencias de manipulacin dinmica de datos y cursores.

SENTENCIA DROP AUDIT FOR


Esta sentencia permite detener y borrar la generacin de un log para una tabla o vista de la base de datos. Al igual que ocurra en la sentencia: CREATE AUDIT (ver pgina 106) y por los mismos motivos citados no se traducir este cdigo java.

SINTAXIS DE INFORMIX
<DROPAUDITFOR> ::= DROP AUDIT FOR [ nombretabla | nombresinonimo ]

122

SENTENCIA DROP DATABASE


Permite eliminar una base de datos completa incluyendo todas las tablas del catalogo, ndices y datos. Esta sentencia no es contemplada por el estndar SQL89, Informix-SQL lo amplia al usarla, tampoco es soportada por el SQL92 aunque de una forma u otra todo gestor de bases de datos la implementa.

SINTAXIS DE INFORMIX
<DROPDATABASE> ::= DROP DATABASE <nombrebasedatos> <nombrebasedatos> ::= nombrebasedatos | espcificacionbd | <variable>

SINTAXIS DE SQLSERVER
<DROPDATABASE> ::= DROP DATABASE nombrebasedatos [,...n ]

SINTAXIS DE ORACLE
<DROPDATABASE> ::= DROP DATABASE nombrebasedatos

SINTAXIS DE DB2
<DROPDATABASE> ::= DROP [ DATABASE | DB ] nombrebasedatos [ AT NODE ]

GENERACIN DE CDIGO
Esta es una sentencia de administracin que rara vez se ejecuta desde un programa, siempre se crean y borran las bases de datos a travs de la herramienta de administracin proporcionada por cada gestor de bases de datos. Aun as se incorporara la traduccin de la misma a cdigo objeto puesto que su traduccin no plantea ningn problema. La traduccin a java del cdigo fuente es directa puesto que, aunque el resto de gestores admite ms posibilidades, soportan sin ninguna limitacin la sintaxis original de Informix-SQL.

SENTENCIA DROP INDEX


La sentencia DROP INDEX permite eliminar un ndice de la base de datos. El usuario que borra el ndice debe de ser propietario del mismo o tener privilegios de DBA. El estndar SQL92 no la contempla, Informix-SQL la incorpora como una ampliacin en su versin 4.10. El resto de gestores tambin proporciona una sentencia que permite borrar ndices de la base de datos.

SINTAXIS DE INFORMIX
<DROPINDEX> ::= DROP INDEX nombreindice

SINTAXIS DE SQLSERVER
<DROPINDEX> ::= DROP INDEX { tabla.nombreindice | vista.nombreindice } [ ,...n ]

123

SINTAXIS DE ORACLE
<DROPINDEX> ::= DROP INDEX [ <esquema> . ] nombreindice

SINTAXIS DE DB2
<DROPINDEX> ::= DROP INDEX nombreindice

GENERACIN DE CDIGO
Como se observa en la definicin de la sentencia por los distintos gestores de bases de datos y la sentencia definida por Informix-SQL, sta es admitida sin ninguna limitacin. An as SQLSERVER exige que se especifique la tabla de la cual se va a borrar el ndice. Para todos los gestores, exceptuando SQLSERVER, se transcribe la sentencia original segn aparece en el cdigo fuente. Para el caso de SQLSERVER es preciso localizar la tabla (o vista) de la cual se trata de borrar el ndice, para ello se lanzar la siguiente sentencia al gestor de bases de datos: select name from sys.tables where object_id = ( select object_id from sys.indexes where name = 'indice1') Una vez obtenido el nombre de la tabla (o vista) se concatenar este con el nombre del ndice y se lanzar la sentencia contra el gestor de bases de datos. Tener en cuenta que este dato se ha de obtener en tiempo de ejecucin, ya que en tiempo de compilacin puede an no existen la tabla o vista en la base de datos. El nico problema que planteara esta bsqueda es que hubiera dos ndices nombrados igual aunque sobre distinta tabla. Esto no se produca ya que el gestor de bases de datos original no lo permite y se entiende que los programas lanzados sobre el gestor de bases de datos destino fueron diseados para Informix-SQL. Dentro del Anexo I, en el epgrafe: Ejemplo sentencia drop index, se muestra caso prctico de la traduccin de esta sentencia para cada gestor de bases datos.

SENTENCIA DROP SYNONYM


Esta sentencia permite borrar un sinnimo de la base de datos. El estndar SQL89 no la contempla y tampoco el SQL92, Informix-SQL la soporta como una aplicacin al estndar. Todos los gestores de bases de datos aqu estudiados soportan esta sentencia.

SINTAXIS DE INFORMIX
<DROPSYNONYM> ::= DROP SYNONYM nombresinonimo

SINTAXIS DE ORACLE
<DROPSYNONYM> ::= DROP [ PUBLIC ] SYNONYM [ <esquema> ] nombresinonimo

SINTAXIS DE DB2
<DROPSYNONYM> ::= DROP ALIAS nombresinonimo

124

GENERACIN DE CDIGO
Para todos los gestores de base de datos la traduccin de la sentencia original de Informix-SQL no plantea ningn problema aunque habr que atender a la sintaxis de esta para cada gestor de bases de datos. Dentro del Anexo I, en el apartado: Ejemplo sentencia drop, se muestra caso prctico de la traduccin de esta sentencia para cada uno de los gestores de bases de datos estudiados.

SENTENCIA DROP TABLE


Esta sentencia permite eliminar una tabla de la base de datos junto con sus ndices, restricciones y datos asociados. Tambin son eliminados todos los sinnimos, triggers y vistas asociados a la tabla. No son eliminados los sinnimos creados en bases de datos externas. Esta sentencia se ajusta al estndar SQL92, aunque ste tiene una sintaxis ms amplia.

SINTAXIS DE INFORMIX
<DROPTABLE> ::= DROP TABLE nombretabla

SINTAXIS DE SQLSERVER
<DROPTABLE> ::= DROP TABLE nombretabla

SINTAXIS DE ORACLE
<DROPTABLE> ::= DROP TABLE [<esquema>] nombretabla [ CASCASDE CONSTRAINT ] La opcin CASCADE CONSTRAINTS aplica la integridad referencial y borra todos los constraints que hacen referencia a las claves primarias y claves nicas de la tabla que se borra.

SINTAXIS DE DB2
<DROPTABLE> ::= DROP TABLE nombretabla

GENERACIN DE CDIGO
La generacin de cdigo no plantea ningn problema puesto que la sintaxis de la sentencia original de Informix-SQL es plenamente soportada por el resto de gestores de bases de datos. El eliminar una tabla de la base de datos para Informix-SQL significa que se eliminan todos los sinnimos, triggers y vistas creados sobre ella, sin embargo para el resto de los gestores estos persisten. Esta distinta interpretacin de la sentencia DROP TABLE para el resto gestores trae el problema de que en ellos se puede estar intentando crear una vista, sinnimo o trigger que ya existe. En el ejemplo siguiente se muestra el problema: Sentencia: create table tabla1; create table tabla2; create view vista1 on select * from tabla1; drop table tabla1; create view vista1 on select * from tabla2; En este ejemplo funcionara sin ningn problema para el Informix-SQL, para el cual se escribi la misma, sin embargo para el resto de gestores, sobre el que se trata se pueda ejecutar, dara un error puesto que en ellos la vista: vista1 an existe. En el momento donde se analiz cada una de las sentencias CREATE se propusieron soluciones para evitar la persistencia de las vistas y sinnimos tras la desaparicin de la tabla en el resto de gestores de bases de datos.

125 Dentro del Anexo I, en el apartado: Ejemplo sentencia drop, se muestra caso prctico de la traduccin de esta sentencia para cada uno de los gestores de bases de datos estudiados.

SENTENCIA DROP VIEW


Esta sentencia permite borrar una vista de la base de datos. La sentencia es contemplada por el estndar SQL92 y lo hace de una forma ms amplia que Informix-SQL pero cubriendo la sintaxis de ste por completo.

SINTAXIS DE INFORMIX
<DROPTABLE> ::= DROP VIEW nombrevista

SINTAXIS DE SQLSERVER
<DROPVIEW> ::= DROP VIEW nombrevista [,n]

SINTAXIS DE ORACLE
<DROPVIEW> ::= DROP VIEW [<esquema>] nombrevista

SINTAXIS DE DB2
<DROPVIEW> ::= DROP VIEW nombrevista

GENERACIN DE CDIGO
Al igual que ocurra con la sentencia DROP TABLE la sentencia original de Informix-SQL se puede ejecutar, sin ninguna modificacin, sobre cualquier gestor de bases de datos. En los ejemplos mostrados en el cuadro anterior, Sentencia DROP TABLE, se puede ver tambin el uso de esta sentencia.

SENTENCIA EXECUTE
Esta sentencia permite ejecutar una sentencia o conjunto de sentencias previamente preparadas. Su utilizacin esta siempre ligado al uso de la sentencia PREPARE.

SINTAXIS DE INFORMIX
<EXECUTE> ::= EXECUTE nombresentenciapreparada [ USING <variable> [,n] ] La clusula USING especifica los valores que reemplazarn el smbolo ? dentro de la sentencia preparada. El siguiente ejemplo de cdigo fuente permitir aclarar el funcionamiento de esta sentencia: LET stm_1 = "UPDATE orders SET order_date = ? WHERE po_num = ?" PREPARE statement_1 FROM stm_1 EXECUTE statement_1 USING x_o_date, x_po_num

SINTAXIS DE SQLSERVER
<EXECUTE> ::= EXECUTE nombresentenciapreparada [USING DESCRIPTOR <estructuradevariables> | USING <variable> [,...]]

126

SINTAXIS DE ORACLE
<EXECUTE> ::= EXECUTE nombre_sentencia [ USING variable [, n] ]

SINTAXIS DE DB2
<EXECUTE> ::= EXECUTE nombresentenciapreparada [ INTO variableresulado [, n] | DESCRIPTOR nombredescriptor ] [ USING variable [, n] | DESCRIPTOR nombredescriptor ]

GENERACION DE CDIGO
Esta sentencia aunque es soportada por todos los gestores, junto con la sentencia PREPARE, tendr una traduccin ms compatible con todos ellos utilizando las sentencias preparadas del JDBC de JAVA. Ver el siguiente ejemplo: integer campo; PreparedStatement x = conn.prepareStatement x.setInt(1, campo); x.executeUpdate(); As la sentencia PREPARE de Informix-SQL se traducir a prepareStatement del JDBC de JAVA y la EXECUTE a una combinacin de las sentencias setXXXX para realizar la parte USING, y executeUpdate para realizar el EXECUTE propiamente dicho. Vase dentro del Anexo I los ejemplos prcticos de traduccin de cdigo fuente a cdigo objeto ejecutable sobre cada gestor en el punto: Ejemplo sentencia prepare/execute prepare/declare. A la hora de fijar los valores de las sentencia SQL se utilizan variables de programa, en funcin del tipo de estas se utilizar una funcin setXXXX u otra. ("insert into tabla values(?)");

SENTENCIA FETCH
Esta sentencia se utiliza para posicionar el cursor dentro del conjunto en curso y para retornar los valores de la posicin indicada en la memoria para ser usados por el programa.

SINTAXIS DE INFORMIX
<FETCH> ::= FETCH [ <fetch orientacion> ] nombredecursor INTO <lista de variables> <fetch orientacion> ::= NEXT | PRIOR | PREVIOUS | FIRST | LAST | CURRENT | { ABSOLUTE | RELATIVE } <especificacin de valor> <especificacin de valor> ::= nombredevariable | nmerodefila <lista de variables> ::= nombredevariable [ nombredevariable [,n] ] Devuelve los valores de un conjunto activo y especifica las variables en las que se guardara el resultado. El cursor ha debido ser previamente declarado y abierto.

127

SINTAXIS DE SQLSERVER
<FETCH> ::= FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE { nmerofila | nombrevariable } | RELATIVE { nmerofila | nombrevariable } ] FROM ] { { [ GLOBAL ] nombrecursor } | nombredevariable_cursor } [ INTO nombredevariable [ ,n ] ] Como se ve esta sentencia es totalmente compatible con la de Informix-SQL, puesto que PRIOR es equivalente PREVIOUS y CURRENT es lo mismo a no poner nada.

SINTAXIS DE ORACLE
<FETCH> ::= FETCH nombredecursor [ INTO <variable> [,n] | USING DESCRIPTOR nombredescriptor ] Esta sentencia retorna las filas del conjunto de resultados una de cada vez. Cada FETCH retorna la fila actual y avanza el cursor a la fila siguiente dentro del conjunto de resultados.

SINTASIX DE DB2
<FETCH> ::= FETCH [ FROM ] nombredecursor [ INTO <variable> [,n] | USING DESCRIPTOR nombredescriptor ] Al igual que la sentencia proporcionada por Oracle sta no soporta la ubicacin relativa del cursor, siempre retornara el siguiente.

GENERACIN DE CDIGO
Al igual que para con el resto de sentencias de manejo de cursores no ser importante que la sintaxis original de Informix-SQL no sea soportada por el resto ya que se utilizarn la funciones estndar del JDBC de JAVA para realizar la traduccin de cdigo fuente a cdigo objeto. La generacin de cdigo de esta sentencia se ver en el apartado: Sentencias de manipulacin dinmica de datos y cursores

SETENCIA FLUSH
Esta sentencia fuerza que las filas que fueron puestas en memoria por la sentencia PUT pasen a la base de datos. <FLUSH> ::= FLUSH nombre_cursor El conjunto PUT/FLUSH hace el mismo trabajo que la sentencia FETCH. Si se finaliza el programa sin hacer un FLUSH o en su defecto cerrar el cursor los datos puestos en memoria se pierden sin ser pasados a base de datos. Ejemplo: DECLARE c1 CURSOR FOR INSERT INTO tabla1 VALUES (cdigo, nombre) OPEN c1 LET code = "AS" LET sname = "Asturias" PUT c1 FLUSH c1 CLOSE c1

La transformacin de esta sentencia sera:

128 PREPARE s1 FROM INSERT INTO tabla1 VALUES (?,?) DECLARE c1 for s1 OPEN c1 LET code = "AS" LET sname = "Asturias" PUT c1 FROM code, sname FLUSH c1 CLOSE c1

El conjunto de sentencias FLUSH/FREE/PUT no es soportada por ninguno de los otros gestores de bases de datos estudiado pero, al igual que con el resto de sentencias de manejo de cursores, esto no plantea problema ya que generar cdigo objeto utilizando los mtodos estndar del JDBC de JAVA soportados por cada proveedor de bases de datos.

SENTENCIA FREE
Esta sentencia libera los recursos que estn reservados para una sentencia preparada o un cursor.

SENTENCIA FREE
<FREE> ::= FREE nombre_cursor

SENTENCIA GRANT
Esta sentencia permite: Autorizar a otros usuarios distintos del creador de la base de datos a: usarla, desarrollar sobre ella, o administrarla. Posibilitar a otros usuarios distintos del creador ver, alterar o eliminar una tabla, vista o sinnimo.

El estndar SQL92 contempla esta sentencia aunque la versin de ella que define Informix-SQL no se ajusta al mismo en varios aspectos. El estndar solo contempla en esta sentencia el dar permisos sobre objetos de la base de datos.

SINTAXIS DE INFORMIX
<GRANT>::= GRANT <PRIVILEGIOS> TO [ PUBLIC | usuario[, ...n] ] <PRIVILEGIOS> ::= <PRIVILEGIOSDEBASEDEDATOS> | <PRIVILEGIOSDETABLAS> <PRIVILEGIOSDEBASEDEDATOS> ::= CONNECT | RESOURCE | DBA <PRIVILEGIOSDETABLAS> ::= { ALL [PRIVILEGES] | <PRIVILEGIOSTABLA> [, ...n] } ON [TABLE] { nombretabla | nombrevista | nombresinonimo } <PRIVILEGIOSTABLA> ::= INSERT | DELETE | SELECT [ ( nombrecolumna [, ...n] ) ] | UPDATE [ ( nombrecolumna [, ...n] ) ] | ALTER | INDEX Los permisos sobre la base de datos son:

129 CONNECT. Un usuario con este tipo de privilegios puede realizar las siguientes tareas: Establecer una conexin a la base de datos. Ejecutar sentencias SELECT, UPDATE, INSERT, y DELETE sobre tablas en las cuales el usuario tenga suficientes privilegios. Crear vistas sobre tablas sobre las que el usuario tenga suficientes privilegios. Crear sinnimos. Crear tablas temporales y crear ndices sobre las tablas temporales.

RESOURCE. Proporciona la posibilidad de variar la estructura de la base de datos. Adems de las tareas que puede realizar un usuario con privilegios Connect. Un usuario que posee en nivel de privilegios Resource puede realizar: Crear nuevas tablas. Crear nuevos ndices. Crear nuevas rutinas. Crear nuevas bases de datos. Dar cualquier privilegio a nivel de bases de datos incluso el DBA sobre cualquier usuario. Dar cualquier privilegio a nivel de tabla sobre cualquier usuario. Quitar privilegios sobre cualquier objeto independientemente de que sea o no suyo. Crear tablas, vistas, o ndices e indicar como propietario a otro usuario. Ejecutar la sentencia DROP DATABASE. insertar, modificar o borrar filas sobre cualquier tabla del sistema a excepcin de systables, sobre esta solo puede actuar el usuario informix.

DBA. Tiene todas las capacidades del privilegio Resource y adems la posibilidad de:

Los permisos sobre tablas son: INSERT. Permite al poseedor de este privilegio insertar filas en la tabla, vista, o sinnimo. DELETE. Permite al poseedor de este privilegio eliminar filas de la tabla, vista, o sinnimo. SELECT. El usuario con este privilegio puede seleccionar y ver datos. Se puede limitar los columnas con este privilegio indicando en esta sentencia las columnas a las cuales puede acceder, sino se indica ninguna se entiende que tiene acceso a todas. UPDATE. El poseedor de este privilegio puede modificar datos. Se puede especificar aquellas columnas sobre las cuales se tiene este privilegio. INDEX. Permite al poseedor de este privilegio el crear ndices permanentes sobre una tabla. Este privilegio no tendr efecto a menos que el usuario posea tambin privilegios Resource sobre la base de datos. ALTER. Permite al usuario realizar todas las funciones proporcionadas por la sentencia ALTER TABLE. Este privilegio no tendr efecto a menos que el poseedor de este privilegio posea tambin el privilegio a nivel de bases de datos: Resource.

SINTAXIS DE SQLSERVER
<GRANT> ::= GRANT {ALL | instruccin[,n]} TO cuentaseguridad[,n] | GRANT

130 {ALL [PRIVILEGES] | <permiso>[,n]} { [(columna[,n])] ON {tabla | vista} | ON {tabla | vista}[(columna[,n])] | ON {procedimientoalmacenado | procedimientoextendido} } TO cuentaseguridad[,n] [WITH GRANT OPTION] [AS {grupo | funcin}] <permiso> ::= INSERT | UPDATE | SELECT | DELETE | ALTER | REFERENCES | EXECUTE Con esta sentencia se permite a un usuario de la base de datos actual trabajar con datos de la base de datos actual (permisos de objeto) o ejecutar instrucciones SQL especficas (permisos de la instruccin). Es la instruccin para la que se concede el permiso. La lista de instrucciones puede contener: CREATE DATABASE CREATE DEFAULT CREATE PROCEDURE CREATE RULE CREATE TABLE CREATE VIEW BACKUP DATABASE BACKUP LOG

Las instrucciones que requieren permisos son las que agregan objetos a la base de datos o realizan actividades administrativas en ella. Cada instruccin que requiere permisos tiene un conjunto de funciones determinado que automticamente tiene permiso para ejecutarla. Por ejemplo, de forma predeterminada tienen permiso sobre CREATE TABLE los miembros de las funciones sysadmin, db_owner y db_ddladmin. De forma predeterminada, tienen permisos para ejecutar la instruccin SELECT en una tabla las funciones sysadmin y db_owner, y tambin el propietario del objeto. Cada objeto de una base de datos de SQLSERVER tiene un propietario, normalmente el identificador del usuario activo en la conexin en que se cre el objeto. Otros usuarios no pueden tener acceso a ese objeto hasta que el propietario autorice a sus identificadores de usuario para que tengan acceso al objeto. Ciertas instrucciones de SQL tambin estn limitadas a determinados identificadores de usuario. Por ejemplo, la instruccin CREATE DATABASE est limitada a los miembros de las funciones fijas de servidor sysadmin y dbcreator. Los permisos que se pueden conceder a los objetos son: SELECT. Permite a un usuario emitir instrucciones SELECT en una tabla o vista. INSERT. Permite a un usuario emitir instrucciones INSERT en una tabla o vista. UPDATE. Permite a un usuario emitir instrucciones UPDATE en una tabla o vista.

131 DELETE. Permite a un usuario emitir instrucciones DELETE en una tabla o vista. REFERENCES. Permite a un usuario insertar una fila en una tabla que tiene una clave externa, que hace referencia a la tabla que se nombra en la instruccin GRANT, DENY y REVOKE. EXECUTE. Permite almacenado. a un usuario emitir instrucciones EXECUTE en un procedimiento

La clusula: WITH GRANT OPTION especfica que se concede a cuentaseguridad la capacidad de conceder el permiso de objeto especificado a otras cuentas de seguridad. La clusula WITH GRANT OPTION slo es vlida con los permisos de objeto.

SINTAXIS DE ORACLE
<GRANT>::= { GRANT <PRIVILEGIOS> ON <OBJETOS> TO <USUARIOS> | GRANT <ROLL> TO <USUARIOS> } [ WITH GRANT OPTION ] <PRIVILEGIOS> ::= { {ALL PRIVILEGES | <PRIVILETIODEOBJETO> } [ ( nombrecolumna [, ...n]) ] } [, ...n] <PRIVILEGIOSDEOBJETO> ::= ALL | ALTER | DELETE | INDEX | INSERT | SELECT | UPDATE | REFERENCES <USUARIOS> ::= PUBLIC | usuario[, ...n] <OBJETOS> ::= { tabla | vista | sinnimo | ... } [ ...n] <ROLL> ::= { ADMIN | DLL } Para conceder roles a usuarios el que lo concede debe haber iniciado sesin en la base de datos como SYSTEM o bien como un usuario con privilegios DLL o ADMIN. El rol ADMIN posibilita al usuario que lo tiene crear otros usuarios y concederles permisos sobre cualquier objeto de la base de datos. El usuario puede ejecutar los siguientes comandos: CREATE SCHEMA, CREATE USER, ALTER USER, DROP, USER, DROP SCHEMA, GRANT, y REVOKE. El rol DDL habilita al usuario a ejecutar las siguientes sentencias: CREATE TABLE, CREATE VIEW, CREATE INDEX, CREATE CONSTRAINTS, ALTER TABLE, ALTER VIEW, ALTER INDEX, ALTER CONSTRAINT, DROP TABLE, DROP VIEW, DROP INDEX, y DROP CONSTRAINT. Si al especificar los privilegios sobre objetos concedidos a un usuario se pone ALL el usuario podr: alterar la estructura, crear ndices, crear restricciones y ejecutar las sentencias: DELETE, INSERT, SELECT, UPDATE sobre el objeto.

SINTAXIS DE DB2
<GRANT>::= GRANT <PRIVILEGIOS> TO [ PUBLIC | [ USER | GROUP ] idusuariogrupo[, ...n] ] [WITH GRANT OPTION] <PRIVILEGIOS> ::= <PRIVILEGIOSDEBASEDEDATOS> | <PRIVILEGIOSDETABLAS>

132 <PRIVILEGIOSDEBASEDEDATOS> ::= { CONNECT | CREATETABLE | CREATE_NOT_FENCED | BINDADD | IMPLICIT_SCHEMA | BDADM | LOAD } ON DATABASE <PRIVILEGIOSDETABLAS> ::= { ALL [PRIVILEGES] | <PRIVILEGIOSTABLA> [, ...n] } ON [TABLE] { nombretabla | nombrevista | nombresinonimo } <PRIVILEGIOSTABLA> ::= INSERT | DELETE | CONTROL | SELECT [ ( nombrecolumna [, ...n] ) ] | REFERENCES [ ( nombrecolumna [, ...n] ) ] | UPDATE [ ( nombrecolumna [, ...n] ) ] | ALTER | INDEX Permite conceder permisos a la base de datos por completo o bien sobre tablas o vistas. Permisos sobre base de datos: BDADM. Concede los permisos de administrador de la base de datos. El administrador de la base de datos tiene todos los privilegios sobre los objetos de la misma y puede conceder privilegios a otros usuarios. BINDADD, CONNECT, CREATETAB, CREATE_NOT_FENCED e IMPLICIT_SCHEMA automticamente concedidos a un usuario que se le da el permiso DBADM. IMPLICIT_SCHEMA. Concede permisos para crear schemas. BINDADD. Concede permiso para crear paquetes. CONNECT. Concede permiso de acceso a la base de datos. CREATETAB. Concede permiso para crear tablas en la base de datos. El que crea la tabla adquiere automticamente el privilegio CONTROL sobre la tabla el cual mantiene incluso si pierde el permiso CREATETAB. CREATE_NOT_FENCED. Concede permisos para crear funciones que se ejecuten en la base de datos. Una vez que una funcin haya sido registrada esta continuar ejecutndose incluso si se pierde el privilegio CREATE_NOT_FENCED. LOAD. Concede permiso para cargar datos en la base de datos. SYSADM y BDADM tambin tienen este permiso. Sin embargo, si un usuario carece de ellos deber tener permisos a nivel de tabla: INSERT y DELETE. de sentencias sobre tablas o vistas se ha de tener sobre son

Para conceder permisos de ejecucin estas: Privilegio de CONTROL. Privilegios sobre ellas. Autoridad de SYSADM o DBADM.

Para conceder el privilegio CONTROL se requiere autoridad de SYSADM o DBADM.

133 Para conceder privilegios en tablas o vistas del catalogo se ha de poseer autoridad de SYSADM o DBADM. Los permisos que se pueden conceder sobre tablas o vistas son: ALTER. Concede permiso para: Aadir columnas a una tabla de la base de datos. Crear o eliminar claves primarias o restricciones nicas sobre las tablas. Crear o eliminar claves ajenas sobre las tablas. Crear triggers. Crear check constraints. Ejecutar ALTER, CONTROL, DELETE, INSERT, INDEX, REFERENCES, SELECT, y UPTATE sobre tablas de la base de datos. Permitir conceder los privilegios citados en el punto anterior, excepto CONTROL, a otros usuarios. Ejecutar la sentencia DROP sobre tablas o vistas de la base de datos

CONTROL. Concede todos los privilegios necesarios para:

DELETE. Concede privilegio para borrar filas de las tablas de la base de datos o actualizar vistas. INDEX. Concede privilegio para crear ndices sobre tablas. INSERT. Concede el privilegio para inserta filas en tablas, actualizar vistas y ejecutar la utilidad IMPORT. REFERENCES. Concede el privilegio para crear y eliminar claves ajenas. SELECT. Concede privilegios para: Retornar filas de una tabla o vista. Crear vistas sobre una tabla. Ejecutar la utilidad EXPORT a travs de una tabla o vista.

UPDATE. Concede privilegio para ejecutar la sentencia UPDATE sobre una tabla o vista.

La opcin: WITH GRANT OPTION de la sentencia GRANT posibilita a los usuarios que reciben un privilegio conceder este sobre otros usuarios.

GENERACIN DE CDIGO
La sentencia GRANT consta de dos subsentencias diferenciadas: una que da permisos sobre la base de datos, y otra que da permiso sobre tablas, vistas y/o sinnimos de la base de datos. En el caso de permisos sobre la base de datos las diferencias conceptuales entre la definicin que aporta Informix-SQL y el resto de gestores de bases de datos hace su traduccin prcticamente imposible. En el caso de concesin de permisos sobre tablas la interpretacin de los distintos gestores es muy similar, conceder la ejecucin de la sentencia a la que hace referencia, lo que facilitar su traduccin a estos. No hay que olvidar que la sentencia GRANT es una sentencia pura de administracin y que es muy inusual que esta sentencia forme parte del cdigo fuente de un programa de Informix-4GL . Lo ms normal es ejecutar la sentencia en la herramienta de administracin que proporciona cada gestor de bases de datos. La solucin planteada ser no hacer ser diferenciar la sentencia original en dos partes: una primera relativa a conceder permisos a nivel de base de datos y otra a nivel de objeto. En el

134 primer caso si aparece en el cdigo fuente, a pantalla con el siguiente mensaje: la hora de procesar el cdigo, se indicar por

Lnea: 4 Warning: Sentencia grant no generada Para la concesin de permisos a nivel de objeto se generar cdigo objeto sin limitaciones. En el apartado: Ejemplo sentencia grant, dentro del Anexo I se muestra un ejemplo del uso del traductor.

SENTENCIA INSERT INTO


Esta sentencia permite insertar filas en una tabla o vista. Esta sentencia es soportada por el estndar SQL89 y por lo tanto tambin por el SQL92. Todos los gestores de bases de datos, aqu estudiados, la contemplan.

SINTAXIS DE INFORMIX
<SENTENCIAINSERT> ::= INSERT INTO { tabla | vista } [ ( <listacolumnas> ) ] <valoresdatos> <listacolumnas> ::= nombercolumna [,...n] <valoresdatos> ::= VALUES ( <valor> [,...] ) | <sentenciaselect> <valor> ::= <variable> | NULL | <expresioncte> Esta sentencia permite una simple fila o un grupo de ellas si los datos son solucionados de otras tablas. Para insertar valores en una tabla se debe de ser propietario de la misma o tener privilegios de insercin sobre la misma.

SINTAXIS DE SQLSERVER
<SENTENCIAINSERT> ::= INSERT [INTO] {tabla | vista } [ ( <listacolumnas> ) ] <valoresdatos> <listacolumnas> ::= nombercolumna [,...n] <valoresdatos> ::= VALUES ( <expresin> [,...] ) | <sentenciaselect>

SINTAXIS DE ORACLE
<SENTENCIAINSERT> ::= INSERT INTO [ <esquema> ] { tabla | vista } [ ( <listacolumnas> ) ] <valoresdatos> <listacolumnas> ::= nombercolumna [,...n] <valoresdatos> ::= VALUES ( <expresin> [,...n] ) | <sentenciaselect>

SINTAXIS DE DB2
<SENTENCIAINSERT> ::= INSERT INTO { tabla | vista } [ ( <listacolumnas> ) ] <valoresdatos>

135 <listacolumnas> ::= nombercolumna [,...n] <valoresdatos> ::= VALUES { ( <valor> [,...] ) | <valor> [,...] } | [ WITH <expresioncomun> [,...n] ] <sentenciaselect> <valor> ::= <expresin> | NULL | DEFAULT

GENERACIN DE CDIGO
La sentencia original de Informix-SQL se puede lanzar contra cualquier otro gestor de bases de datos, de los aqu estudiados, ya que su sintaxis es totalmente compatible. Los nicos puntos a considerar son: la compatibilidad de la sentencia SELECT con el resto de gestores de bases de datos la cual se tratara mas adelante (ver pgina 143), y la tolerancia de los valores de tipos de datos definidos por Informix-SQL por el resto de gestores (ver pgina 154). En el Anexo I, punto: Ejemplo sentencia insert, se puede ver un caso del uso del traductor para esta sentencia.

SENTENCIA LOAD FROM


Esta sentencia permite cargar datos desde un fichero del sistema operativo en una tabla, vista o sinnimo de la base de datos. Esta sentencia no es soportada por el estndar SQL89 ni tampoco por el SQL92.

SINTAXIS DE INFORMIX
<SENTENCIALOAD> ::= LOAD FROM <nombrefichero> [ DELIMITER <caracter> ] INSERT INTO { tabla | vista | sinnimo } [ ( <listacolumnas> ) ] Esta sentencia aade nuevas lneas a la tabla. No sobrescribe datos existentes. El fichero que se especifica en la sentencia LOAD contiene los datos a aadir a la tabla. Si no se incluye la lista de columnas en la clusula INSERT INTO, los campos en el fichero deben de coincidir con las columnas de la tabla en nmero, orden y tipo de datos. Cada lnea del fichero debe de tener el mismo nmero de campos y estos deben de estar separados por el carcter indicado en la clusula DELIMITER. En caso de omitirse sta el delimitador por defecto es la barra vertical |.

GENERACION DE CODIGO
Esta sentencia no es soportada por ningn otro gestor de bases de datos con una sintaxis similar a la de Informix-SQL, adems no todo gestor implementa esta funcionalidad. Como es importante el proporcionar una forma de hacer carga de datos desde el sistema operativo a una tabla de la base de datos de una forma sencilla e independiente del gestor de bases de datos se define un mtodo en JAVA que implementa la sentencia original de Informix-SQL y que podr ser utilizado para cualquier gestor de bases de datos. Este mtodo ser accesible desde la conexin a la base de datos que haya creada en el programa generado y se llama: load. Recibe 2 3 parmetros que se detallan a continuacin: 1. Nombre del fichero del cual se recogen los datos. 2. Delimitador de campos. Es opcional en caso de no ponerse se considerar el delimitador por defecto: | 3. Parte insert de la sentencia load.

136 Para conseguir que el mtodo tenga el comportamiento esperado, en cdigo java, se realizan las siguientes tareas: Leer del fichero fuente cada lnea (fila). Trocear los campos de cada fila utilizando para ello el delimitador. Generar una sentencia insert a partir del valor que se recibe como tercer parmetro y los valores troceados ledos del fichero. Ej. Parmetro: insert into tabla1 Lnea del fichero: 1|prueba|23.3 Sentencia generada: insert into tabla1 values (1,prueba,23.3) Para generar la sentencia se ha de tener en cuenta el tipo de dato que recibir , en base de datos, el valor ledo del fichero y en funcin a l formatear el valor. ste tipo de dato se obtendr realizando una consulta a la base de datos. Ejecutar la sentencia generada sobre el gestor destino. De esta forma, al utilizar como puente intermedio entre el fichero fuente y el gestor de bases de datos la tecnologa JDBC, la sentencia podr ser ejecutada sobre cualquier gestor de bases de datos. En el apartado: Ejemplo sentencia load/unload, dentro del Anexo I se plasma un caso del cdigo genrado para esta sentencia.

SENTENCIA LOCK TABLE


Esta sentencia permite controlar el acceso una tabla por parte otros procesos/usuarios.

SINTAXIS DE INFORMIX
<SENTENCIALOCK> ::= LOCK TABLE nombretabla IN { SHARE | EXCLUSIVE } MODE Un usuario puede bloquear una tabla si es el propietario o tiene privilegios de seleccin sobre la misma o sobre algn campo. La sentencia LOCK TABLE falla si esta ya esta bloqueada en modo exclusivo por otro proceso. La palabra SHARE indica que la tabla se bloquea en modo compartido. Esto permite que otros procesos tengan acceso de lectura sobre la tabla pero no de escritura. Otros procesos no pueden alterar o borrar datos si la tabla esta bloqueada en modo compartido. La palabra EXCLUSIVE bloquea la tabla en modo exclusivo. Este modo no permite a otros procesos ni leer ni escribir sobre la tabla bloqueada. Este bloqueo se produce, tambin de forma automtica, cuando se ejecuta una sentencia: ALTER INDEX, CREATE INDEX, DROP INDEX, RENAME COLUMN, RENAME TABLE, y ALTER TABLE. Informix-SE no permite que ms de un usuario bloquee en tabla en modo SHARED.

SINTAXIS DE SQLSERVER
Hay tres tipos de bloqueos en SqlServer: Shared, Update, y Exclusive. El motor de bases de datos SqlSever gestiona de forma automtica los bloqueos necesarios a la hora de lanzar las transacciones sin que el usuario necesite aadir ninguna instruccin especifica para el tratamiento de las mismas, an as el sistema proporciona la posibilidad de que el usuario trate de influir en las decisiones que el servidor toma utilizando para ello la clusula WITH en las sentencias: SELECT, UPDATE, DELETE, e INSERT. SqlServer recomienda que se deje en manos del propio gestor el manejo de los bloqueos ya que los mismos pueden influir mucho en el rendimiento del gestor de bases de datos y la intervencin de un usuario inexperto puede afectar negativamente.

137 La forma en que SqlSever adquiere y libera los bloqueos esta directamente relacionada con el nivel de aislamiento fijado (TRANSACTION ISOLATION LEVEL) y por la granularidad. SqlServer tiene varios niveles de granularidad: una nica fila, pginas, extents (grupos de pginas contiguos), o una tabla completa. A nivel de cdigo se puede influir en el modo en que el servidor se comporta a la hora de realizar los bloqueos utilizando las sugerencias de bloqueos. Sqlserver no admite ms de una sugerencia de bloqueo por tabla. Los tipos de sugerencias de bloqueo son: De granularidad: PAGLOCK, NOLOCK, ROWLOCK, TABLOCK, or TABLOCKX. De nivel de asilamiento: SERIALIZABLE. HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD,

SqlSever tiene limitaciones en el uso de algunas sugerencias de bloqueo, tales como no permite el uso de: NOLOCK, READUNCOMMITTED, o READPAST en las sentencias: DELETE, INSERT o UPDATE, etc. La definicin sintctica de las sugerencias de bloqueos es: <sugerencia_de_bloqueos> ::= WITH ( <sugerencia> [, .. n] )

<sugerencia> ::= { INDEX ( index_val [ ,...n ] ) | FASTFIRSTROW | HOLDLOCK | NOLOCK | PAGLOCK | READCOMMITTED | READPAST | READUNCOMMITTED | REPEATABLEREAD | ROWLOCK | SERIALIZABLE | TABLOCK | TABLOCKX | UPDLOCK | XLOCK } El uso de las sugerencias de bloqueos dentro de las sentencias SQL: SELECT, INSERT, UPDATE, y DELETE se define a continuacin de forma resumida: <sentencia SELECT> ::= SELECT <valores_selecion> FROM tabla <sugerencia_de_bloqueos> . <sentencia INSERT> ::= INSERT INTO tabla <sugerencia_de_bloqueos> <sentencia UPDATE> ::= UPDATE tabla <sugerencia_de_bloqueos> SET <sentencia DELETE> ::= DELETE FROM tabla <sugerencia_de_bloqueos> WHERE .

SINTAXIS DE ORACLE
La sentencia LOCK sobrescribe el bloqueo automtico, que gestiona el propio gestor de bases de datos, y permite o deniega el acceso al objeto bloqueado a otros usuarios durante la duracin del mismo. <SENTENCIALOCK> ::= LOCK TABLE [ <esquema> . ] nombretabla IN <lockmode> MODE [ NOWAIT ] <lockmode> ::= ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE | SHARE | SHARE ROW EXCLUSIVE

138 | EXCLUSIVE

SINTAXIS DE DB2
<SENTENCIALOCK> ::= LOCK TABLE nombretabla IN { SHARE | EXCLUSIVE } MODE

GENERACIN DE CODIGO
La generacin de cdigo para esta sentencia es bastante sencilla. La sentencia original de Informix es soportada por el resto de gestores de bases de datos a excepcin de SqlServer el cual gestiona los bloqueos de forma automtica. Otra forma posible es la utilizacin de transacciones ya que todas las sentencias que forman parte de una transaccin se ejecutada como una unidad. Si un controlador de bases de datos soporta transacciones, y casi todos lo hacen, proporcionar algn nivel de proteccin contra conflictos que puedan surgir cuando los usuarios acceden a los datos a la misma vez. Para evitar conflictos durante una transaccin, un controlador de base de datos utiliza bloqueos: mecanismos para bloquear el acceso de otros a los datos que estn siendo accedidos por una transaccin. La forma en que se configuran los bloqueos est determinada por lo que se llama nivel de aislamiento de transaccin. Teniendo en cuenta, como se ver en la sentencia UNLOCK, que: para el resto de gestores el bloqueo de una tabla finaliza cuando se termina la transaccin en la cual la misma esta implicada y que las transacciones aportan por s mismas un nivel de bloqueo las sentencias que estn, en cdigo fuente, entre la sentencia LOCK y UNLOCK formarn parte de una transaccin siempre y cuando el gestor de bases de datos lo permita. Ejemplo: Cdigo fuente: LOCK TABLE tabla1 IN SHARE MODE INSERT INTO tabla1 VALUES (1, 2,tres) UPDATE tabla1 SET campo1 = 3 WHERE campo1 = 2 UNLOCK TABLE Cdigo objeto para el reto de gestores: Connection.setAutoCommit(false); Desactiva el modo autoentrega [ Sent.exeUpdate (LOCK TABLE tabla1 IN SHARE MODE); ] sent. exeUpdate(INSERT INTO tabla1 VALUES (1,2,tres) ); sent. exeUpdate(UPDATE tabla1 SET campo1 = 3 WHERE campo1 = 2 ); Connection.commit(); [ Sent.exeUpdate (UNLOCK TABLE tabla1); ] Connection.setAutoCommit(true); Finaliza la transaccin. La sentencia LOCK se generar para todos los gestores menos SqlServer y la sentencia UNLOCK nicamente para Informix-SQL. En todo caso las sentencias a ejecutar se incluyen dentro de una transaccin. En el Anexo I, apartado: Ejemplo sentencia lock/unlock se pueden ver ejemplos prcticos.

SENTENCIA OPEN
La sentencia OPEN permite activar un cursor, asociado con una sentencia DECALRE o EXECUTE, y por tanto la ejecucin del mismo.

139

SINTAXIS DE INFORMIX
<SENTENCIAOPEN> ::= OPEN nombrecursor [ USING { <variable> [,...n] } ] La parte USING de la sentencia OPEN puede ser requerida cuando el cursor esta asociado con una sentencia preparada. Cada variable se sustituir por cada aparicin del smbolo de interrogacin (?) de la sentencia preparada.

SINTAXIS DE SQLSERVER
<SENTENCIAOPEN> ::= OPEN { { [GLOBAL] nombrecursor } | nombrevariablecursor}

SINTAXIS DE ORACLE
<SENTENCIAOPEN> ::= OPEN nombrecursor [ ( <variable> [,...n] ) ]

SINTAXIS DE DB2
<SENTENCIAOPEN> ::= OPEN nombrecursor [ USING { <variable> [,...n] } | [ USING DESCRIPTOR nombredescriptor ]

GENERACIN DE CODIGO
La generacin de cdigo de esta sentencia se ver en el apartado: Sentencias de manipulacin dinmica de datos y cursores.

SENTENCIA PREPAPRE
Esta sentencia permite analizar, validar, y generar un plan de ejecucin de una sentencia SQL.

SINTAXIS DE INFORMIX
<SENTENCIAPREPARE> ::= PREPARE nombresentpreparada FROM {<variable> | cadena }

SINTAXIS DE SQLSERVER
<SENTENCIAPREPARE> ::= PREPARE nombresentpreparada [INTO sqlca] FROM { <variable> | cadena } [, ..n] Prepara la sentencia SQL deSde la cadena de caracteres que recibe como parmetro para posteriormente ser ejecutada. nombresentpreparada puede posteriormente formar parte de una sentencia EXECUTE, o DECLARE CURSOR.

SINTAXIS DE ORACLE
<SENTENCIAPREPARE> ::= PREPARE nombresentpreparada FROM { cadena | variable }

SINTAXIS DE DB2
<SENTENCIAPREPARE> ::= PREPARE nombresentpreparada [ [OUTPUT] INTO nombre_descriptor ] [ INPUT INTO nombre_descriptor ] FROM <variable>

GENERACIN DE CODIGO
Esta sentencia se usa bien asociada a la sentencia EXECUTE o bien asociada a la sentencia DECLARE dentro del manejo de cursores.

140 A la hora de traducirla a cdigo objeto se utilizar la sentencias propias del JDBC de JAVA consiguiendo as un tratamiento estndar para todos los gestores de bases de datos estudiados y no cindose a la sintaxis que proporcione cada uno de ellos para el tratamiento de las sentencias preparadas y los cursores. La sentencia SQL que se procesa mediante la sentencia PREPARE no ser evaluada. Esta vendr en una constante o una variable tipo cadena caracteres y no se tendr en cuenta si es valida o no para el gestor de bases de datos destino. Esto se indicar durante la generacin de cdigo a travs de un warning: Warning: Sentencia PREPARE, revisar sintaxis SQL En la seccin de generacin de cdigo dentro de la: Sentencia EXECUTE se ve un caso prctico de utilizacin del binomio de sentencias PREPARE-EXECUTE. En la seccin: Sentencias de manipulacin dinmica de datos y cursores se mostrarn ejemplos de esta sentencia junto con la sentencia DECLARE as como las peculiaridades de su traduccin y tratamiento.

SENTENCIA PUT
Esta sentencia guarda una fila en la base de datos cuyos datos fueron almacenados en memoria por la sentencia FLUSH. <PUT>::= PUT nombre_cursor [ FROM <variable> [, .. n] ]

SENTENCIA RENAME COLUMN


Esta sentencia permite cambiar el nombre de una columna de una tabla. Esta sentencia no esta contemplada por SQL92, es una extensin que aporta Informix-SQL, y no es soportada en el mismo aspecto que Informix-SQL por ningn otro gestor de bases de datos de los contemplados aqu.

SINTAXIS DE INFORMIX
<SENTENCIARENAMECOLUMN> ::= RENAME COLUMN nombretabla . nombredecolumna TO nuevonombredecolumna

SINTAXIS DE SQLSERVER
<SENTENCIARENAMECOLUMN> ::= sp_rename nombretabla. Nombredecampo, nombrenuevocampo , 'COLUMN' En SQLSERVER no se contempla ninguna sentencia que permita renombrar un campo de una tabla, pero si existe un procedimiento almacenado que posibilita hacerlo.

SINTAXIS DE ORACLE
Oracle no define la sentencia RENAME pero, a partir de la versin 9i relase 2, s permite modificar el nombre de una columna utilizando para ello la sentencia ALTER TABLE, la sintaxis es: <SENTENCIARENAMECOLUMN> ::= ALTER TABLE nombretabla RENAME COLUMN nombre columna TO nuevonombrecoluma

SINTAXIS DE DB2
El gestor de base de datos DB2 no soporta esta funcionalidad.

GENERACIN DE CODIGO
Aunque la sintaxis original de Informix-SQL no es soportada por ningn otro gestor si se generar esta sentencia, para aquellos que la soportan, utilizando la sintaxis apropiada para el gestor de base de datos destino. Para el caso de DB2 no se generar y se indicar a travs de un warning durante el proceso de traduccin:

141 Warning: Sentencia RENAME no generada Para ver casos prcticos del comportamiento del traductor respecto a esta sentencia dirigirse a: Ejemplo sentencia rename column, dentro del Anexo I.

SENTENCIA RENAME TABLE


Esta sentencia permite cambiar el nombre de una de una tabla de la base de datos actual. Esta sentencia no esta contemplada por SQL92, es una extensin que aporta Informix-SQL, aunque de una forma u otro todos los gestores aqu estudiados la contemplan.

SINTAXIS DE INFORMIX
<SENTENCIARENAMETABLE> ::= RENAME TABLE nombretabla TO nuevonombredetabla

SINTAXIS DE SQLSERVER
<SENTENCIARENAMETABLE> ::= sp_rename nombretabla, nombrenuevotabla En SQLSERVER no se contempla ninguna sentencia que permita renombrar una tabla, pero si existe un procedimiento almacenado que posibilita hacerlo.

SINTAXIS DE ORACLE
<SENTENCIARENAMETABLE> ::= ALTER TABLE nombretabla RENAME TO nuevonombredetabla

SINTAXIS DE DB2
<SENTENCIARENAMETABLE> ::= RENAME TABLE nombretabla TO nuevonombredetabla

GENERACIN DE CODIGO
La generacin de cdigo de esta sentencia no plantea ningn problema solo se a de atender a la sintaxis particular de cada gestor de bases de datos. En el Anexo I, hay un caso prctico de cdigo generado para esta sentencia, dentro del apartado: Ejemplo sentencia rename tabla.

SENTENCIA REVOKE
Quita un permiso otorgado o denegado previamente de un usuario de la base de datos actual. Esta sentencia es contemplada por el estndar SQL92 pero de forma ms limitada a como lo hace el gestor de bases de datos Informix-SQL. Este contempla permisos a nivel de objetos y de bases de datos , el estndar solo a nivel de objetos.

SINTAXIS DE INFORMIX
<SENTENCIAREVOKE> ::= REVOKE [ <privilegiosniveldetabla> ON <tabla> | <privilegiosniveldebasedatos> ] FROM [ PUBLIC | <usuarios> ] <tabla> ::= nombretabla | nombrevista | nombresinonimo <usuarios> ::= usuario [ n]

<privilegiosniveldetabla> ::= ALL [ PRIVILEGES ] | { INSERT | DELETE | SELECT | UPDATE | INDEX | ALTER } [...n]

142 <privilegiosniveldebasedatos> ::= CONNECT | RESOURCE | DBA

SINTAXIS DE SQLSERVER
<SENTENCIAREVOKE> ::= REVOKE [ GRANT OPTION FOR ] { ALL [ PRIVILEGES ] | <permisos> [ ,...n ] } { [ ( columna [ ,...n ] ) ] ON { tabla | vista } | ON { tabla | vista } [ ( columna [ ,...n ] ) ] | ON { procedimientoalmacenado | procedimientoexetendido } | ON { funcionesdefinidasporelusuario } } {TO | FROM} cuentadeseguridad [ ,...n ] [ CASCADE ] [ AS { grupo | rol } ] <permisos> ::= SELECT | INSERT | DELETE | UPDATE | REFERENCES | EXECUTE cuentadeseguridad hace referencia a una cuenta de usuario de la base de datos.

SINTAXIS DE ORACLE
< SENTENCIAREVOKE> ::= REVOKE <privilegios> ON <tabla> FROM <usuarios> <privilegios> ::= ALL | SELECT | INSERT | DELETE | UPDATE ( columna [n] ) <usuarios> ::= usuario [ n]

<tabla> :.= nombretabla | nombrevista | nombresinonimo

SINTAXIS DE DB2
< SENTENCIAREVOKE> ::= REVOKE <privilegios> ON [TABLE] [tabla | vista] FROM <usuarios> <privilegios> ::= ALL [PRIVILEGES] | SELECT | INSERT | DELETE | UPDATE | INDEX | REFERENCES | CONTROL | ALTER <usuarios> ::= { PUBLIC | [USER | GROUP ] cuentadeseguridad } [,n]

143

GENERACIN DE CODIGO
Al igual que ocurra con la sentencia GRANT la solucin planteada ser la misma. Si se trata de quitar permisos a nivel de base de datos, al considerarse esto como una tarea de administracin, no se generar cdigo, pero si se trata de permisos a nivel de objeto s. A la hora de procesar el cdigo fuente se indicar por pantalla, si se trata de permisos a nivel de bases de datos, el siguiente mensaje: Lnea: 4 Warning: Sentencia REVOKE no generada

SENTENCIA ROLLBACK WORK


Esta sentencia marca el fin de una transaccin no correcta y hace que todas las modificaciones efectuadas sobre los datos desde el inicio de la transaccin sean deshechas. Esta sentencia no es incorporada ni por el estndar SQL89 ni por el estndar bsico SQL92 aunque todos los gestores de bases de datos la incorporan, incluido Informix-SQL, razn por la cual se incorpora a la hora de traducir el cdigo fuente. Al igual que ocurra con la sentencia BEGIN WORK cada gestor incorpora su propia sentencia pero la solucin que se adoptar a la hora de generar cdigo es independiente del gestor y se basa en las posibilidades que aporta el JDBC de JAVA. Por esta razn no nos pararemos a estudiar en detalle la sentencia del resto de gestores.

SINTAXIS DE INFORMIX
<ROLLBACK WORK> ::= COMMIT WORK

GENERACIN DE CODIGO
La generacin de cdigo, al igual que con la sentencia BEGIN WORK, se hace de forma independiente al gestor de base de datos para el cual se este traduciendo. La traduccin ser la siguiente: Connection.rollback(); Connection.setAutoCommit (true); Este cdigo hace dos acciones, primero hace que la modificaciones efectuadas desde el inicio de la transaccin no pasen a forma parte de la base de datos de forma permanente; y segundo cierra la transaccin. El cdigo objeto obtenido de las sentencias de tratamiento de transacciones no ser dependiente del gestor de bases de datos ya que se utilizan funcionalidades propias del API JDBC. En el punto: Ejemplo sentencias de tratamiento de transacciones, perteneciente al Anexo I se muestran ejemplos prcticos.

SENTENCIA SELECT
Esta sentencia permite hacer una consulta sobre la base de datos.

SINTAXIS DE INFORMIX
<SENTENCIA SELECT> ::= SELECT [ ALL | DISTINCT | UNIQUE ] <listaselect> [ INTO <listadecampos> ] FROM <tablafuente> [ WHERE <condiciondebusqueda> ] [ GROUP BY <expresiongroupby> ] [ HAVING <condiciondebusqueda> ] [ ORDER BY <expresiondeordenacion> [ ASC | DESC ] ] [ INTO TEMP nombretablatemporal [ WITH NO LOG ] ] <listaselect> ::= { *

144 | { nombretabla | nombrevista | aliasdetabla }.* | { nombrecolumna | expresin | }[ [ AS ] aliasdecolumna ] } [,...n ] <listadecampos> ::= <variable> [,n] <tablafuente>::= <tabla> [ [AS] aliasdetabla ] , <uniondetablas> [,n] <uniontablas> ::= <tabla> [ [AS] aliasdetabla ] | OUTER <tabla> [ [AS] aliasdetabla ] | OUTER ( <tabla> [ [AS] aliasdetabla ] , <uniondetablas> ) <tabla> ::= { tabla | vista | sinnimo } <condiciondebusqueada ::= <condicin> <expresiongroupby> ::= { [ {nombretabla | nombrevista | sinnimo | aliasdetabla } . ] nombrecolumna | nmeroselect } [,...n ] <expresiondeordenacion> ::= { [ {nombretabla | nombrevista | sinnimo | aliasdetabla } . ] nombrecolumna | nmeroselect | aliasdecampo | rowid } [,...n ]

SINTAXIS DE SQLSERVER
<SENTENCIA SELECT> ::= SELECT <clausulasselect> <listaselect> [ INTO tablanueva ] FROM <tablafuente> [ WHERE <condiciondebusqueda> ] [ GROUP BY <expressiongroupby ] [ HAVING <condiciondebusqueda ] [ ORDER BY <expression> [ ASC | DESC ] ] <clausulasselect> ::= [ ALL | DISTINCT ] [ TOP n [PERCENT] [ WITH TIES] ] <listaselect> ::= {* | { nombretabla | nombrevista | aliasdetabla } . * | { nombrecolumna | expresion | IDENTITYCOL | ROWGUIDCOL } [ [ AS ] aliasdecolumna ] | column_alias = expression } [ ,...n ] <tablafuente> ::= { nombretabla [ [ AS ] aliasdetabla ] [ WITH ( < tabla_hint > [ ,...n ] ) ] | nombrevista [ [ AS ] aliasdetabla ] [ WITH ( < vista_hint > [ ,...n ] ) ] | funcin [ [ AS ] aliasdetabla ] | funciondefinidaporelusuario [ [ AS ] aliasdetabla ] | tabladerivada [ AS ] aliasdetabla [ ( aliasdecolumna [ ,...n ] ) ] | < uniondetablas > } [ ,...n ]

145 <uniondetablas> ::= <tablafuente> <tipodeunion> <tablafuente> ON <condiciondebusqueda> | <tablafuete> CROSS JOIN <tablafuente > | [ ( ] < uniondetablas > [ ) ] <tipodeunion> ::= [ INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } ] [ <tipodeunion> ] JOIN <expresiongroupby> ::= [ ALL ] <expression> [ ,...n ] [ WITH { CUBE | ROLLUP } ]

SINTAXIS DE ORACLE
<SENTENCIA SELECT> ::= SELECT <clausulasselect> <listaselect> FROM <tablafuente> [ WHERE <condiciondebusqueda> ] [ GROUP BY <expressiongroupby ] [ HAVING <condiciondebusqueda ] [ ORDER BY <expresiondeordenacion> <clausulasselect> ::= [ ALL | DISTINCT ] <listaselect> ::= {* | [esquema . ]{ nombretabla | nombrevista | aliasdetabla } . * | { nombrecolumna | expresin }[ [ AS ] aliasdecolumna ] } [ ,...n ] <tablafuente> ::= [esquema . ] { nombretabla [ [ AS ] aliasdetabla ] | nombrevista [ [ AS ] aliasdetabla ] | ( <expresin> ) [ [ AS ] aliasdetabla ] | < uniondetablas > } [,...n ] <uniondetablas> ::= <tablafuente> <tipodeunion> <tablafuente> ON <condiciondebusqueda> | <tablafuete> CROSS JOIN <tablafuente > | [ ( ] < uniondetablas > [ ) ] <tipodeunion> ::= [ INNER | { { LEFT | RIGHT | FULL } [ OUTER ] } ] [ <tipodeunion> ] JOIN <expresiongroupby> ::= <expresin> [ ,...n ] <expresiondeordenacion> ::= { <expresin> | <posicion> | tabla | aliasdetabla } [ ASC | DESC ] ] [,n]

146

SINTAXIS DE DB2
<SENTENCIA SELECT> ::= <clausulaselect> <clausulafrom> [ <clausulawhere> ] [ <clausulagroupby> ] [ <clausulahaving> ] [ <clausulaorderby ] [ <clausulafetch_first> ] <clausulaselect> ::= SELECT [ ALL | DISTINCT ] {* | <expresin> . * | <expresin> [ AS ] aliasdecolumna ] } [,...n] c <clausulaform> ::= FROM <definiciontabla> [, ..n] <definiciontabla> ::= { <nombretabla> | [ ONLY | OUTER] { nombretabla | nombrevista } } <clausulacorrelacion> | <uniondetablas> <nombretabla> ::= { nombretabla | nombrevista | nickname } <clausulacorrelacion> ::= AS nombre [ ( nombre_columna [, ..n] ) ] <uniondetablas> ::= <tabla> [ [AS] aliasdetabla ] | OUTER <tabla> [ [AS] aliasdetabla ] | OUTER ( <tabla> [ [AS] aliasdetabla ] , <uniondetablas> ) <clausulawhere> ::= WHERE <condiciondebusqueda> <clausulagroupby> ::= GROUP BY <expression> [, ..n] <clausulahaving> ::= HAVING <condiciondebusqueda> <clausulaorderby> ::= ORDER BY <elementoordenacion> [ ASC | DESC ] [, ..n]

GENERACIN DE CODIGO
Las sentencias del resto de gestores de bases de datos son mayormente compatibles con la que define Informix-SQL. Cabe destacar que ningn otro gestor soporta la opcin: INTO <variable> para almacenar el resultado de la consulta a la tabla y que Oracle y Db2 tampoco soportan el insertar los datos obtenidos en otra tabla, temporal o no, de la base de datos. Aparte de estos problemas esta sentencia plantea otros muchos temas a tener en consideracin: Utilizacin de variables definidas por programa. Utilizacin de expresiones agregadas y funciones SQL. Tipos de datos. Utilizacin de expresiones y operaciones con las mismas. Etc.

147 Todas estos temas se tratarn en secciones posteriores con total detalles y atendiendo a las peculiaridades de cada gestor de bases de datos. La forma en que se generar cdigo objeto solucionar el problema de la clusula INTO <variable> ya que se utilizarn los mtodos propios del API JDBC de JAVA para lanzar las sentencias contra el gestor y para la recuperacin de los datos. En cuanto a la clusula INTO TEMP <tabla> no ser analizada en esta versin. Dentro de los ejemplos mostrados en el Anexo I, se pueden ver varios casos del uso esta sentencia.

SENTENCIA START
Esta sentencia permite establecer la conexin con la base de datos. Es una ampliacin a la versin 4.10 de Informix-SQL (al igual que CONNECT), y semnticamente es equivalente a la sentencia DATABASE por esta razn ser contemplada en el traductor.

SINTAXIS DE INFOMRIX
<SENTENCIA START> ::= START DATABASE <nombrebasedatos>

GENERACIN DE CDIGO
La traduccin de esta sentencia a cdigo objeto ser, al igual que con la sentencia DATABASE, de forma independiente al gestor de bases de datos destino y aprovechando las funcionalidades que aporta el API JDBC de JAVA, ver ejemplo en: Ejemplo sentencias conexin/desconexin.

SENTENCIA UNLOAD
Esta sentencia permite descargar datos de en una tabla, vista o sinnimo de la base de datos a un fichero del sistema operativo. Al igual que ocurra con la sentencia LOAD esta sentencia no es soportada por el estndar SQL89 ni tampoco por el SQL92 la incorpora Informix-SQL como una funcionalidad adicional.

SINTAXIS DE INFORMIX
<SENTENCIA UNLOAD> ::= UNLOAD FROM <nombrefichero> [ DELIMITER <caracter> ] <sentencia select> Esta sentencia descarga filas de la tabla. No elimina las filas descargadas de la tabla origen. El fichero que se especifica en la sentencia UNLOAD contendr los datos a descargar de la tabla. En caso de omitirse el delimitador por defecto es la barra vertical |.

GENERACION DE CODIGO
Esta sentencia no es soportada por ningn otro gestor de bases de datos con una sintaxis similar a la de Informix-SQL y no todo gestor implementa esta funcionalidad. Al igual que se hizo en la sentencia LOAD y an conociendo que existen sentencias similares en algn otro gestor y por las mismas circunstancias se implementa la sentencia UNLAOD en JAVA. El mtodo definido se llamar unload y se definir en una clase accesible en tiempo de ejecucin. Recibe 2 3 parmetros: 1. Nombre del fichero en el cual se descargan los datos. 2. Delimitador de campos. Es opcional en caso de no ponerse se considerar el delimitador por defecto: | 3. Subsentencia select.

148 Para conseguir que el mtodo tenga el comportamiento esperado, en cdigo java, se realizan las siguientes tareas: Coger la parte select de la sentencia original y lanzarla contra la base de datos. Leer cada fila de la consulta campo a campo. Construir una cadena con la correlacin de campos, correspondientes a la consulta realizada a la base de datos, separados por el campo delimitador y mandarlo al fichero resultado indicado en la sentencia.

De esta forma, al utilizar como puente intermedio entre el fichero fuente y el gestor de bases de datos la tecnologa JDBC, la sentencia podr ser ejecutada sobre cualquier gestor de bases de datos. En el ejemplo mostrado al analizar la sentencia: SENTENCIA LOAD FROM , tambin se muestra la utilizacin de la sentencia UNLOAD.

UNLOCK TABLE
SINTAXIS DE INFORMIX
<SENTENCIAUNLOCK> ::= UNLOCK TABLE { nombretabla | nombresinonimo } Un usuario puede desbloquear una tabla si es el propietario o tiene privilegios de seleccin sobre la misma o sobre algn campo. No se podrn desbloquear tablas que no hayan sido bloqueadas por el mismo usuario. Solo se puede aplicar un bloqueo sobre una tabla al mismo tiempo.

SINTAXIS DE SQLSERVER
Como se comento al tratar la sentencia LOCK SqlServer no se encarga del manejo de bloqueos de forma automtica.

SINTAXIS DE ORACLE
Oracle no contempla la sentencia UNLOCK el bloqueo se mantiene hasta el fin de la transaccin activa.

SINTAXIS DE DB2
En Db2 tampoco se contempla la sentencia UNOLOCK el sistema mantiene el bloqueo sobre la tabla hasta el fin de la transaccin activa.

GENERACIN DE CODIGO
Al explicar la sentencia: SENTENCIA LOCK TABLE se comento tambin la forma de tratar esta sentencia.

SENTENCIA UPDATE
La instruccin UPDATE puede cambiar los valores de filas individuales, grupos de filas o todas las filas de una tabla. Una instruccin UPDATE que haga referencia a una tabla slo puede cambiar los datos de una tabla a la vez. Esta sentencia es soportada por el estndar SQL92. La sentencia proporcionada por Informix-SQL se adapta en su totalidad al estndar SQL92 lo que facilitar mucho su traduccin al resto de gestores de base de datos.

SINTAXIS DE INFORMIX
<SENTENCIAUPDATE> ::= UPDATE { nombretabla | nombresinonimo | nombrevista } SET <clausulaset> [ <clausulawhere> ]

149 <clausulaset> ::= { nombrecolumna = { <expresin> | <sentenciaselect> | <variable> } } [, n] | ( { nombrecolumna | * | <tabla> .* }[,n] ) = ( { <expresin> | ( <sentenciaselect> ) | <variablecompleja> } [,n] ) <variablecompleja> ::= <variable> . * | <variable> . valor <clausulawhere> ::= WHERE { <condicin> | CURRENT OF nombrecursor }

SINTAXIS DE SQLSERVER
<SENTENCIAUPDATE> ::= UPDATE { nombretabla WITH ( < sujerencias_de_alteracion > [ ..n ] ) | nombrevista | nombresinonimo } SET { nombrecolumna = { <expresin> | DEFAULT | NULL} | @variable = expresin | @variable = column = <expresin> } [ , ..n ] } [, ..n] { { [ FROM { <nombretabla> } [ , ...n ] ] [ WHERE <condicion_de_busqueda> ] } | [ WHERE CURRENT OF [ GLOBAL ] nombrecursor ]} [ OPTION ( < sugerencias_de_busqueda > [ ,...n ] ) ]

SINTAXIS DE ORACLE
<SENTENCIAUPDATE> ::= UPDATE <sugerencia_de_update> { esquema . { nombretabla | nombrevista | nombresinonimo } [ @basedatos] | ( <subconsulta> [ <condiciones_subconsulta> ] ) } [ sinonimoobjeto ] SET { nombrecolumna = { <expresin> | DEFAULT | <subconsulta>} | ( nombrecolumna [, ..n] ) = ( <subconsulta> ) } [, ..n] [ WHERE <condicion_de_busqueda> | WHERE CURRENT OF nombrecursor ] [ RETURNING <expresin> [, ..n] INTO <variable> [, ..n] ]

SINTAXIS DE DB2
<SENTENCIAUPDATE> ::= UPDATE { { nombretabla | nombrevista | nombresinonimo } | ONLY [ nombretabla | nombrevista ] } [ AS sinonimoobjeto ] SET { nombrecolumna = { <expresin> | DEFAULT | <NULL>} | ( nombrecolumna [, ..n] ) = ( [<expresin> | DEFAULT | <NULL> ] | <subconsulta> ) } [, ..n] [ WHERE <condicion_de_busqueda> | WHERE CURRENT OF nombrecursor ] [ WITH { RR | RS | CS | UR } ]

150

GENERACIN DE CODIGO
Observando la sentencia original de Informix-SQL y la que proporciona el resto de gestores se ve que es totalmente compatible. A lo largo de los ejemplos mostrados en el Anexo I se puede ver ejemplos de generacin de cdigo para esta sentencia. Dentro de la seccin: Sentencias de manipulacin dinmica de datos y cursores se muestran ejemplos de esta sentencia con la opcin: WHERE CURRENT OF.

UPDATE STATISTICS
Esta sentencia permite actualizar el catalogo de tablas del optimizar las bsquedas. sistema que el servidor utiliza para

SINTAXIS DE INFORMIX
<SENTENCIAUPDATESTATISTICS> ::= UPDATE STATISTICS

GENERACIN DE CODIGO
Esta es una sentencia y pura de administracin que se suele ejecutar con el objeto de optimizar el rendimiento de la base de datos. Cada gestor proporciona sus propios mtodos o forma de realizarla a travs de la herramienta de administracin. No se generar cdigo objeto para la misma.

SENTENCIAS DE MANIPULACIN DINMICA DE DATOS Y CURSORES

En este apartado se quiere hacer un tratamiento especial de los cursores atendiendo a la forma en que se ha decido se genere cdigo objeto. Las instrucciones SQL que trabajan con cursores son: CLOSE, DECLARE CURSOR FOR, DELETE FROM WHERE CURRENTO OF, EXECUTE, FETCH, FLUSH, FREE, OPEN, PREPARE, PUT, y UPDATE WHERE CURRENT OF. La sintaxis de todas estas sentencias ya se describi en las secciones anteriores en las cuales se analizaba cada uno de ellas. Como se comento no todas las sentencias son soportadas en igual medida por el resto de gestores de bases de datos pero en este caso no genera ningn problema ya que se van a aprovechar las posibilidades que proporciona el API JDBC de JAVA para el manejo de cursores. La forma tpica de definicin de un cursor en Informix-SQL es: DECLARE c5 cursor FO select * from tabla1 OPEN c1 FETCH c5 INTO x, y CLOSE c5 Donde la sentencia a ejecutar se puede colocar directamente detrs del DECALRE o bien venir definida a travs de una sentencia PREPARE. Este grupo de sentencias se trasformar, para todo gestor, de la siguiente forma: Statement ASG_sp_c5 = ASGdb.retCon().createStatement(ResltSet.TYPE_XXXXX, ,ResultSet.CONCUR_XXXXXXX); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( * ) Try { ASG_rsp_c5.next(); from tabla1");

151 vuno = ASG_rsp_c5.getShort(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); Observando la sentencia generada se pueden ver varias cosas: No existe una correlacin exacta entre sentencia origen y objeto, la correlacin real es: DECLARE con: createStatement o prepareStatement y executeQuery OPEN no genera cdigo objeto FETCH con: next y getXXX CLOSE con el close del RestultSet y del Statement.

Se utilizan variables de programa JAVA no definidas en el cdigo fuente y dejan de utilizarse nombre de cursores si definidos en el cdigo fuente. Informix-SQL no permite que dos cursores, dentro de un mismo programa, se nombren igual, pero si permite que un cursor se nombre igual que una variable. Aqu se ha de tener especial cuidado al definir las variables que se asocian a los cursores para evitar que se generen errores debido a nombres de variables duplicados. Para ello las variables necesarias para la transformacin de los cursores a cdigo objeto se nombrarn siguiendo la siguiente estructura: Un sufijo generado en funcin de la sentencia: Para Statement ser: ASG_sp (de sentencia preparada) Para el ResultSet ser ASG_rsp (de resulset de la sentencia preparada)

Y una parte final que corresponder con el nombre del cursor definido en el cdigo fuente.

La sentencia que permite definir las opciones del cursor es: createStatement a travs de sus parmetros, que son: Primer parmetro marca el modo de funcionamiento del cursor y la posibilidad de actualizacin de la vista de los datos si estos han sido modificados por otro usuario. Los valores que puede tomar son: ResultSet.TYPE_FORWARD_ONLY. Solo se puede recorrer el cursor hacia delante. Valor por defecto. ResulSet.TYPE_SCROLL_INSENSITIVE. Permite recorrer el cursor en ambos sentidos y no se ve afectados por cambios realizados en base de datos por otros usuarios. ResultSet.TYPE_SCROLL_SENSITIVE: permite recorrer el resultado usando un cursor bidireccional y adems permite actualizar el cursor con los cambios que se hayan producido en la base de datos.

El segundo parmetro marca la posibilidad de alterar el valor de los campos de la fila a la que apunta el cursor y puede tomar los valores: ResultSet.CONCUR_READ_ONLY. Los valores son solo lectura, no se pueden modificar. Valor por defecto. ResultSet.CONCUR_UPDATABLE. Indica que el valor de cursor puede ser actualizado en la base de datos. Esta opcin posibilita que la opcin FOR UPDATE del cdigo fuente pueda ser aplicable a travs de JAVA.

Segn la definicin sintctica, por defecto estos parmetros deben de ser: TYPE_SCROLL_SENSITIVE y CONCUR_READ_ONLY. En el caso de que se utilice la opcin SCROLL el primer parmetro ser: TYPE_SCROLL_INSENSITIVE y si se utiliza la opcin FOR UPDATE el

152 segundo parmetro ser: CONCUR_UPDATABLE. Por definicin sintctica no se puede ver que nunca coincidirn las opciones FOR UPDATE y SCROLL. Destacar aqu que Db2 no admite la combinacin: SCROLL_SENSITIVE y CONCUR_UPDATABLE en este caso se utilizar SCROLL_INSENSITIVE Y CONCUR_UPDATABLE. En el punto: Ejemplo sentencia prepare/execute prepare/declare del Anexo I se puede ver ejemplo del tratamiento de esta sentencia. En este ejemplo se muestra, tambin, un caso completo de utilizacin de un cursor con la sentencias DECLARE-OPEN-FETCH-CLOSE con y sin la sentencia PREPARE.

FOR UPDATE
Cuando se pone la opcin FOR UPDATE tras la subsentencia SELECT de la sentencia DECLARE CURSOR significa que a la hora de tratar las filas se genera un bloqueo especial por la posibilidad de que se actualicen campos de la fila que se esta procesando o se borre est, usando para ello la opcin WHERE CURRENT OF de las sentencias UPDATE o DELETE. La forma de indicar la opcin FOR UPDATE al declarar el cursor, en el momento de generar cdigo, es utilizando el parmetro: ResultSet.CONCUR_UPDATABLE del mtodo createStatement o prepareStatement. Aunque aparentemente no se manejan cursores en el cdigo JAVA generado, internamente el JDBC los utiliza. Existen varios mtodos para el tratamiento de la opcin WHERE CURRENT OF, como son: El mtodo: getCursorName(), proporcionado por el API JDBC 2.0, que nos permite recuperar el cursor actual. La utilizacin de este mtodo es la forma ms transparente y sencilla a la hora de traducir cdigo fuente a objeto, como se muestra a continuacin: Cdigo fuente: update tabla1 set campo1 = 4 where current of c4 Cdigo objeto: Statement.executeUpdate("update tabla1 set campo1 = 4 where current of "+ ResultSet.getCursorName()); El problema que tiene este mtodo propuesto es que no es implementado por tordos los drivers JDBC, por ejemplo SqlServer y Oracle no lo soportan. Para estos casos existen otras posibilidades de tratar esta clusula que se muestras seguidamente. mtodos: updateRow y deleteRow. Estos mtodos, del API JDBC 2.0, proporcionan realizar operaciones de actualizacin/eliminacin que afectan a la fila en la que se encuentra el cursor. Ejemplo: Cdigo objeto: ResultSet.next(); posicionamiento del cursor. ResultSet.updateShort(campo1, 4); ResultSet.updateRow(); Esta forma de realizar la traduccin de la opcin WHERE CURRENT OF aunque tambin es parte de las funcionalidades estndar proporcionadas por el API JDBC tampoco funciona para todos los gestores de bases de datos. En el caso de Oracle falla en ciertos casos como cuando la subsentencia SELECT del DECLARE CURSOR es del tipo: select * en lugar de: select camposx, campoy . Este sistema implica: Un cambio radical entre el cdigo fuente y el cdigo objeto. Ser capaces de determinar el tipo de dato que se va a alterar en la tabla de la base de datos para utilizar el mtodo correcto updateXXXX.

Rowid. La utilizacin de este mtodo solo puede aplicarse para gestores de bases de datos en particular y utilizando mtodos especficos del API JDBC proporcionado por el proveedor. Este mtodo se basa en para cada fila que se procese obtener tambin el ROWID y a la hora de ejecutar la sentencia UPDATE o DELETE utilizarlo en la clusula WHERE. Ejemplo: Cdigo objeto: . select campo1, campos, rowid where

153 Object ob1 = getObject(1); String variablerowid = getString(posicin); Statement.executeUpdate("update tabla1 set campo1 = 4 where ROWID = + variablerowid); Este sistema implica: Modificar la subsentencia SELECT del DECLARE CURSOR de tal forma que el obtenga el valor del rowid. Ejemplo: Cdigo fuente: declare c1 cursor for select * from tabla1 Cdigo fuente a traducir: declare c1 cursor for select *, rowid from tabla1 Recuperar en una variable tipo String el valor del campo rowid para luego utilizarlo en la sentencia UPDATE o DELETE.

En el Anexo I, apartado: Ejemplo sentencia declareforupdate muestran varios ejemplos as como su tratamiento por parte del traductor para obtener cdigo objeto valido.

SENTENCIAS DE CONTROL DE FLUJO


Sintaxis: <SENTENCIA FOREACH> ::= FOREACH cursor [INTO variable_de_programa] <sentencias> END FOREACH

En este apartado se estudia la sentencia FOREACH que aunque no es una sentencia SQL es la nica sentencia de control de flujo que se usa exclusivamente para recorrer cursores loa cuales si estn directamente ligados a sentencias SQL.

El funcionamiento de esta sentencia no es ms que el del recorrido secuencial de todos los elementos del cursor. Su traduccin a cdigo objeto JAVA se realizar como el resto de sentencias de manejo de cursores, de forma independiente al gestor y siguiendo las reglas indicadas en el punto anterior, de la siguiente forma: Cdigo fuente: foreach c1 into vuno, vdos, vtres Message campos: ,vuno, vdos, vtres end foreach Cdigo objeto: while ( ASG_rsp_c1.next() ) { vuno = ASG_rsp_c1.getShort(1); vdos = ASG_rsp_c1.getDouble(3); vtres = ASG_rsp_c1.getString(2); System.out.println(campos: + vuno + vtres + vdos ); } En la seccin Anexo I dentro del punto: Ejemplo sentencia foreach-forupdate se muestran varios ejemplos de traduccin y utilizacin de esta sentencia tanto de forma simple como con la opcin FOR UPDATE.

154

ESTUDIO DE TIPOS DE DATOS

En una tabla de la base de datos se pueden almacenar diferentes tipos de datos: fechas, cdigos, nombres, descripciones, salarios, costes, etc. Estos y otros datos se deben de almacenar en el tipo de datos ms adecuado. El tipo de dato seleccionado depender del tipo de informacin que se desee almacenar en cada columna. En el estudio que aqu se realiza lo que tiene importancia es saber si la definicin de los campos de las tablas declarados en el cdigo fuente y por tanto admitidos por el gestor de bases de datos Informix-SQL son: por un lado soportados por el driver JDBC de Java que se utiliza como puente para la ejecucin de las sentencias SQL y por otro lado compatibles con los tipos de datos definidos en otros gestores de base de datos. Desafortunadamente hay variaciones significativas entre los tipos de datos SQL soportados por los diferentes gestores de bases de datos. Incluso, para complicar ms el estudio, los diferentes gestores soportan algunos tipos de datos que semnticamente son igual pero tienen diferente nombre. El API JDBC define un conjunto de genrico de tipos de dato SQL en la clase java.sql.Types. Estos tipos fueron diseados para representar la mayora de los tipos de datos ms comnmente utilizados. A la hora de hacer la traduccin del cdigo fuente, si este se pretende sea valido para cualquier gestor de bases de datos, hay que tener especial cuidado con la definicin de los tipos de datos que hace cada gestor ya que los nombres genricos que define el API JDBC de Java no siempre son soportados por ellos. Como resultado de estudio se obtendrn los siguientes resultados: El mapeo entre los tipos de datos de Informix-SQL y el resto de gestores de bases de datos, de los aqu estudiados, con objeto de que las definiciones de los campos de las tablas que aparecen en el cdigo fuente Informix puedan ser ejecutados, aplicando dichos mapeos, sobre cualquiera de los otros gestores de bases de datos. Para realizar este mapeo de forma coherente se realizar un estudio sobre la definicin que cada proveedor de bases de datos hace de sus tipos de datos. La relacin que cada proveedor de bases de datos realiza entre sus tipos de datos y los tipos de datos SQL de la API JDBC. Esta relacin no nos proporciona directamente informacin aplicable para la traduccin de cdigo fuente Informix a Java pero si nos ayudar, en casos, a clarificar sobre que tipo de dato se puede mapear un tipo de dato Informix-SQL. El observar que en la mapeo que cada proveedor hace entre sus tipos de datos y los datos SQL JDBC nos puede hacer ver que dos proveedores distintivos mapean tipos de datos sintcticamente diferentes contra el mismo tipo de dato SQL JDBC y haciendo un estudio pormenorizado se puede ver que aunque ambos proveedores llamen de diferente forma a un tipo de dato semnticamente son iguales. Por ltimo, y no por ello menos importante, los mtodos que proporciona la API JDBC de Java para transferir datos entre las diferentes bases de datos y las aplicaciones desarrolladas en Java. No solo es preciso saber que mtodos aplicar para transferir datos de un campo de una tabla de una base de datos sino sobre que tipo de variables Java se van a almacenar los resultados obtenidos y viceversa.

TIPOS DATOS BASICOS


En primer lugar con objeto de sentar bases sobre los tipos de datos SQL y ayudar en el estudio que aqu se pretende realizar se presenta una tabla con los tipos de datos bsicos. Los tipos de datos SQL se clasifican en 13 tipos de datos primarios y de varios sinnimos vlidos reconocidos para dichos tipos de datos. Tipos de datos primarios: Tipo de Datos BINARY Longitud 1 byte Descripcin Para consultas sobre tabla adjunta de productos de bases de datos que definen un tipo de datos Binario.

155 BIT BYTE COUNTER CURRENCY DATETIME SINGLE 1 byte 1 byte 4 bytes 8 bytes 8 bytes 4 bytes Valores Si/No True/False Un valor entero entre 0 y 255. Un nmero incrementado automticamente (de tipo Long) Un entero escalable entre 922.337.203.685.477,5807. 922.337.203.685.477,5808 y

Un valor de fecha u hora entre los aos 100 y 9999. Un valor en punto flotante de precisin simple con un rango de -3.402823*1038 a 1.401298*10-45 para valores negativos, 1.401298*10-45 a 3.402823*1038 para valores positivos, y 0. Un valor en punto flotante de doble precisin con un rango de -1.79769313486232*10308 a -4.94065645841247*10-324 para valores negativos, 4.94065645841247*10-324 a 1.79769313486232*10308 para valores positivos, y 0. Un entero corto entre -32,768 y 32,767. Un entero largo entre -2,147,483,648 y 2,147,483,647. De cero a un mximo de 1.2 gigabytes.

DOUBLE SHORT LONG LONGTEXT LONGBINARY CHARACTER

8 bytes 2 bytes 4 bytes 1 byte por carcter 1 byte por carcter

Segn se necesite De cero 1 gigabyte. Utilizado para objetos OLE. De cero a 255 caracteres.

Tabla 21: Tipos de datos primarios La siguiente tabla recoge los sinnimos de los tipos de datos definidos: Tipo de Dato BINARY BIT BYTE COUNTER CURRENCY DATETIME VARBINARY BOOLEAN LOGICAL LOGICAL1 YESNO INTEGER1 AUTOINCREMENT MONEY DATE TIME TIMESTAMP FLOAT4 IEEESINGLE REAL FLOAT FLOAT8 IEEEDOUBLE NUMBER NUMERIC Sinnimos

SINGLE

DOUBLE

156 INTEGER2 SMALLINT INT INTEGER INTEGER4 GENERAL OLEOBJECT LONGCHAR MEMO NOTE ALPHANUMERIC CHAR CHARACTER STRING VARCHAR

SHORT LONG LONGBINARY LONGTEXT

TEXT

VARIANT (No Admitido) VALUE Tabla 22: Sinnimos de tipos de datos primarios

TIPOS DE DATOS JDBC


Es importante tener claros los tipos de datos que soporta el API JDBC de Java ya que este va ser el interface que se utilizar para interactuar con las diferentes bases de datos, sea el puente intermedio entre los valores almacenados en las variables de programa y los campos de las tablas de las bases de datos. Cada proveedor de bases de datos proporcionar la compatibilidad en la definicin de los tipos de datos que soporte su gestor con aquellos que soporte el SQL JDBC de Java. Esta compatibilidad es necesaria por dos motivos: primero los tipos de datos definidos en el API JDBC sern los contenedores intermedios entre los tipos de datos definidos en Java y los definidos en el gestor de bases de datos y segundo el API JDBC proporciona mtodos necesarios para manipular los tipos de datos que define en su interface JDBC. Los tipos de datos soportados por el SQL del interface JDBC de Java (JAVA JDBC SQL Type CHAR VARCHAR LONGVARCHAR NUMERIC DECIMAL BIT TINYINT SMALLINT INTEGER BIGINT Descripcin Cadena de tamao fijo de 0 a 254 caracteres de longitud Cadena de longitud variable de 0 a 254 caracteres de longitud Cadena de longitud variable de al menos 1 Gb Represente un valor decimal de precisin fija. La precisin es el nmero total de dgitos decimales soportados, y la escala es el nmero dgitos despus del punto decimal. JDBC requiere que la precisin y escala pueden tener un valor al menos de 15 dgitos. Dato equivalente al NUMERIC Representa un solo bit que puede tomar los valores uno o cero Tipo entero de 8 bits, representa valores entre 0 y 255 con o sin signo Entero con signo de 16 bits, toma valores entre -32768 and 32767 Entero con signo de 32 bits, toma valores entre -2147483648 and 2147483647 Entero con signo de 64-bit, admite valores desde -9223372036854775808
TM

JDBC 2.0 API) son:

157 hasta 9223372036854775807 REAL FLOAT DOUBLE BINARY VARBINARY LONGVARBINARY DATE TIME TIMESTAMP Nmero en punto flotante de simple precisin y mantisa Tipo de dato equivalente al DOUBLE Nmero en punto flotante de doble precisin que soporta 15 dgitos de mantisa Dato de tipo binario de longitud fija de 0 a 254 bytes Dato de tipo binario de longitud variable de 0 a 254 bytes Dato de tipo binario que admite al menos 1 Gb de datos Representa una fecha formada por da, mes, y ao Representa una unidad de tiempo en formato horas, minutos, y segundos. Tipo de dato donde almacenamos fecha y hora hasta una precisin de microsegundos (6 dgitos de precisin). al menos 7 dgitos de

Tabla 23: Tipos de datos JDBC Se puede observar que esta tabla se utiliza el trmino JDBC SQL type en lugar de SQL type, ambos trminos se refieren a los tipos genricos de SQL definidos en java.sql.Types, y ambos son intercambiables. Los tipos de datos bsicos de JDBC son tipos de datos que se introdujeron en la API principal de Java JDBC 1.0. y se han ido completando y ampliando en versiones sucesivas. Los diferentes controladores JDBC implementados por los proveedores de los respectivos gestores de bases de datos utilizan los tipos de datos bsicos de JDBC para convertir los tipos de datos propios definidos por su gestor en un formato comprensible para el lenguaje de programacin Java y viceversa. Cada proveedor proporciona la relacin entre los tipos de datos bsicos que define en su gestor, JDBC y el lenguaje de programacin Java. Estos tipos de datos: Soporta los tipos de datos ms comunes de SQL, mapeados en forma de tipos de datos Java. Muchos de los tipos de datos estndar de SQL-92, no tienen un equivalente nativo en Java. Para superar esta deficiencia, se deben mapear los tipos de datos SQL en Java, utilizando las clases JDBC para acceder a los tipos de datos SQL. Es necesario saber cmo recuperar adecuadamente tipos de datos Java; como int, long, o string, a partir de sus contrapartidas SQL almacenadas en base de datos. Esto puede ser especialmente importante si se est trabajando con datos numricos que necesiten control decimal con precisin, o con fechas SQL, que tienen un formato muy bien definido. Posibilitan que el mapeo de los tipos de datos Java a SQL es realmente sencillo.

TIPOS DE DATOS INFORMIX-SQL


Los principales tipos de datos soportados por Informix-SQL se pueden agrupar en los siguientes:

CHARACTER
Las columnas tipo carcter almacenan combinaciones de letras nmeros y smbolos. Las columnas tipo char se utilizan normalmente para almacenar nombres, direcciones, nmeros de la seguridad social, nombres de proyectos, etc. CHAR [ (n) ] Admite letras, nmeros y smbolos. Se puede, opcionalmente, especificar la longitud de la columna tipo carcter, La longitud mxima de las cadenas es de 32767. Sino se indica la longitud de la cadena por defecto se entiende que es 1. CHARACTER Es un sinnimo de CHAR.

158

NUMBERICOS
El tipo de dato NUMBER incluye 6 diferentes tipos de datos para almacenar cada diferente tipo de nmero. SMALLINT Admite un nmero entero entre -32,767 y +32,767. INTEGER Admite un nmero entero entre -2,147,483,647 y +2,147,483,647. INT Es un sinnimo de INTEGER. SMALLFLOAT Representa significativos. un nmero de punto flotante con aproximadamente 7 dgitos

REAL Es un sinnimo de SMALLFLOAT. FLOAT Representa un nmero de punto flotante con aproximadamente 14 dgitos significativos. DOUBLE PRECISION Es un sinnimo para FLOAT. DECIMAL [ (m [, n]) ] Define un tipo de dato numrico con precisin y escala fijas. Especificar la precisin y escala es opcional. Sino se indica la precisin por defecto se entiende que sta es 16, en el caso de la escala el valor por defecto es 0. DEC y NUMERIC Son dos sinnimo de DECIMAL.

SERIAL
Esta columna almacena nmeros secuenciales generados por el gestor de bases de datos. No se debe de aadir datos en una columna tipo SERIAL, cada vez que se aade una nueva fila a una tabla el gestor automticamente asigna el siguiente valor numrico de forma secuencial a la columna tipo SERIAL. Normalmente el valor inicial es 1, pero el usuario puede seleccionar el valor inicial mayor de 0 como valor inicial. El valor mayor que admite una columna tipo serial es 2.147.483.647. Una vez que se asigna un valor a un campo tipo SERIAL este no se puede modificar. Cada tabla de la base datos solo puede tener, como mximo, un campo tipo SERIAL. SERIAL [ ( n ) ] Define un tipo de dato autoincremental. El valor inicial por defecto es 1, a no ser que se indique explcitamente otro valor entero positivo.

FECHA Y HORA
DATE Tipo de dato que almacena fechas. Una columna tipo DATE almacena fechas en el formato mm/dd/yyyy donde mm es el mes (1-12), dd es el da del mes (1-31), y yyyy es el ao (00019999). El formato por defecto es mm/dd/yyyy Internamente el gestor almacena los campos de tipo DATE como un entero de 4 bytes el cual representa el nmero de das desde principios del siglo XX, 0 representa el 31 de diciembre de 1899, 1 el 1 de enero de 1900 y as sucesivamente. DATETIME Columna que contiene valores que representan momentos en el tiempo, su sintaxis se muestra a continuacin: DATETIME {YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|FRACTION} TO {YEAR|MONTH|DAY|HOUR|MINUTE|SECOND|FRACTION} Una columna de este tipo guarda valores que representan un momento en el tiempo. El momento en el tiempo permite especificar desde ao hasta la fraccin de segundo. La precisin de una columna de tipo DATETIME se fija en el momento de la definicin de la misma y puede llegar a ser hasta de hasta microsegundos (6 dgitos) siendo el valor por defecto de milisegundos (3 dgitos). El formato de un valor DATETIME es: yyyy-mm-dd hh:mm:ss.fff

159

MONEDA
MONEY [ (m [, n]) ] Esta columna almacena cantidades monetarias, en la precisin se indican la cantidad monetaria y en la escala los cntimos. Sino se indica, por defecto, la precisin es 16 y la escala 2.

INTERVALOS
INTERVAL Esta columna contiene valores que representan intervalos de tiempo. Su sintaxis se indica a continuacin: INTERVAL { [YEAR (n) | MONTH (n) ] TO [YEAR | MONTH] | [DAY(n)] | HOUR(n) | MINUTE(n) | SECOND(n) | FRACTION(n) TO [DAY | MINUTE | SECOND | FRACTION] } Este tipo de dato permite almacenar valores que representan un intervalo o periodo de tiempo. Un valor de tipo intervalo puede representar un intervalo de aos y meses o un intervalo de das hasta fracciones de segundo. La precisin de una columna de tipo intervalo se establece en el momento de la definicin de la misma.

TEXT/BYTE
Esta columna almacena tipos de datos simples de gran longitud. La longitud mxima es de 2**31 bytes. TEXT Cadena de caracteres de hasta 1 Gb de longitud. BYTE Cadena de caracteres binarios de hasta 1 Gb de longitud. Una vez definidos los tipos de datos que soporta el gestor de bases de datos Informix-SQL el paso ms delicado para garantizar que la definicin que ste hace es compatible con la que hacen el resto gestores de bases de datos aqu estudiados es encontrar, para cada uno, el tipo de dato equivalente semnticamente, para ello se ha de estudiar: La definicin que cada gestor hace de sus tipos de datos. La relacin que cada gestor proporciona entre sus tipos de datos y los tipos de datos genricos ODBC y que este ser el interface entre el lenguaje de programacin y el gestor de bases de datos.

Por otro lado no solo se ha de tener en cuenta la definicin de los datos por cada gestor de base de datos sino tambin la manipulacin de los mismos. En la tabla que se muestra a continuacin se proporciona la relacin entre el tipo de dato definido en Informix-SQL y aquel, correspondiente a la API de JDBC, que permite la manipulacin del mismo. Esta asociacin ayudar la traduccin de los tipos de datos, que aparezcan en las sentencias SQL del cdigo fuente Informix-4GL , a su equivalente de los soportados por el gestor de bases de datos destino en la definicin de tablas y el manejo de los datos a travs del API JDBC.

Tipo Dato Informix BYTE CHAR | CHARACTER CHAR | CHARACTER DATE DATETIME year to day

Tipo de valor Almacenado Cadena binaria de longitud mxima 1 Gb

Tipo Dato SQL JDBC LONGVARBINARY

Si cadena de caracteres de hasta 254 caracteres CHAR ASCII Cadena de caracteres de ms de 254 caracteres LONGVARCHAR ASCII Fechas desde 31 de diciembre de 1899 Momentos en el tiempo que representan fechas DATE DATE TIME

DATETIME hour to second Momentos en el tiempo que representas horas

160 Punto en el tiempo, especifica fechas combinadas TIMESTAMP con la hora del da hasta precisin de microsegundos DECIMAL PRECISION |Nmero en punto fijo con una precisin mxima DECIMAL de 16 dgitos |Nmero en punto flotante de hasta 14 dgitos de DOUBLE precisin. Entero, desde +2,147,483,647 Intervalos de tiempo Cantidad precisin monetaria definida con escala -2,147,483,647 hasta INTEGER no soportado y DECIMAL(16,2)

DATETIME DEC | NUMERIC DOUBLE FLOAT

INTEGER | INT INTERVAL MONEY SMALLFLOAT | REAL SMALLINT SERIAL TEXT VARCHAR

Nmero en punto flotante de hasta 7 dgitos de REAL precisin Nmero entero desde -32,767 hasta +32,767 Tipo de dato incremental Cadena de caracteres de longitud mxima 1 Gb SMALLINT INTEGER LONGVARCHAR

Cadena de longitud variable y no mas de 255 VARCHAR caracteres

Tabla 24: Mapeos de datos Informix-SQL a SQL JDBC Analizando las conversiones aqu plantadas se ve: El tipo de dato CHAR de Informix-SQL se ha de transformar en un tipo de datos del SQL de JDBC CHAR o en un LONGVARCHAR en funcin de la longitud con la que se haya definido este tipo de dato en el cdigo fuente. La eleccin entre un tipo de datos u otro no ser complicada ya que en la definicin del campo la longitud a de venir expresada como un literal numrico de forma explicita El tipo de dato TIMESTAMP que representa momentos en el tiempo se puede transformar en un tipo de dato JDBC: DATE, TIME o TIMESTAMP en funcin de la definicin del mismo, esto se puede discernir a la hora de hacer la traduccin de cdigo fuente a objeto. El tipo de datos SERIAL que define el gestor de bases de datos Informix-SQL se representa va JDBC con un tipo de datos INTEGER lo cual sintcticamente es correcto pero semnticamente no ya que aunque un INTEGER pueda albergar el contenido del tipo de dato SERIAL este ltimo tiene un significado especial para el gestor de bases de datos Informix-SQL que no tiene el tipo de datos INTEGER. INTERVAL. Este tipo de dato no es soportado por el estndar JDBC 2.0 y en esta versin del traductor no ser considerado.

Segn la tabla anterior de los tipos de datos que soporta el API JDBC se van a utilizar: LONGVARBINARY, CHAR, LONGVARCHAR, DATE, TIME, TIMESTAMP, DECIMAL, DOUBLE, INTEGER, REAL, SMALLINT, y VARCHAR. Una vez que tenemos claro que tipo de dato de la API JDBC es capaz de albergar cada tipo de datos que aparecen en las sentencias Informix-SQL esto nos asegura que esos tipos de datos podrn ser manejados sin problemas en el cdigo destino, JAVA, a travs del dicha API. El hecho de saber el mapeo que hacen el resto de gestor de bases de datos entre sus tipos de datos y los proporcionados por el driver JDBC nos proporcionar informacin adicional que en ciertos casos nos puede ser de utilidad.

161

TIPO DE DATOS SQLSERVER


El gestor de bases de datos SqlServer soporta los siguientes tipos de datos:

ENTEROS
BIT Datos enteros con valor 1 0. INT Datos enteros (nmeros enteros) comprendidos entre -231 (-2.147.483.648) y 231 - 1 (2.147.483.647). INTEGER es un sinnimo para INT. SMALLINT datos enteros comprendidos entre 215 (-32.768) y 215 - 1 (32.767). TINYINT Datos enteros comprendidos 0 y 255. BIGINT Datos enteros (nmeros enteros) comprendidos entre -263 (-9.223.372.036.854.775.808) y 263 -1 (9.223.372.036.854.775.807). El tamao de almacenamiento es 8 bytes.

DECIMALES Y NUMRICOS
DECIMAL [ ( p [, s] ) ] Nmeros de precisin y escala fijas. Cuando se utiliza la precisin mxima, los valores permitidos estn comprendidos entre - 1038 +1 y 1038 - 1. NUMERIC y DEC Son sinnimo de DECIMAL.

MONEY Y SMALLMONEY
MONEY Valores de moneda comprendidos entre -263 (-922.337.203.685.477,5808) y 263 - 1 (+922.337.203.685.477,5807), con una precisin de una diezmilsima de la unidad monetaria. SMALLMONEY Valores de moneda comprendidos entre -214.748,3648 y +214.748,3647, con una precisin de una diezmilsima de la unidad monetaria.

NUMRICOS CON APROXIMACIN


FLOAT [ ( n ) ] Un nmero de punto flotante con los siguientes valores vlidos: de - 1.79E + 308 a -2.23E - 308, 0 y de 2.23E -308 a 1.79E + 308. n es el nmero de bits que se utilizan para almacenar la mantisa del nmero FLOAT en notacin cientfica y por tanto dicta su precisin y el tamao de almacenamiento. n tiene que ser un valor entre 1 y 53. El valor predeterminado de n es 53. REAL Datos numricos de punto flotante con los siguientes valores vlidos: de 3.40E + 38 a 1.18E - 38, 0 y de 1.18E - 38 a 3.40E + 38. El tamao de almacenamiento es 4 bytes. En SqlServer, el sinnimo de REAL es FLOAT(24).

DATETIME Y SMALLDATETIME
DATETIME Datos de fecha y hora comprendidos entre el 1 de enero de 1753 y el 31 de diciembre de 9999 con una precisin de un trescientosavo de segundo, o 3.33 milisegundos. Para representar este tipo de datos internamente SqlServer utiliza una cadena de 8 bytes: los 4 primeros representan el nmero de das desde (o antes de) el 1 de enero de 1900 y los cuatro segundos representan el nmero de milisegundos desde la medianoche. SMALLDATETIME Datos de fecha y hora comprendidos entre el 1 de enero de 1900 y el 6 de junio de 2079 con una precisin de un minuto. La representacin interna de este tipo de dato es mediante 4 bytes, los dos primeros representan el nmero de das desde el 1 de enero de 1900 y los dos segundos los minutos desde la media noche.

NUMRICOS
CURSOR Un tipo de datos para las variables o para los parmetros de resultado de los procedimientos almacenados que contiene una referencia a un cursor. Las variables creadas con el tipo de datos CURSOR aceptan Null.

162 TIMESTAMP Es un tipo de datos que expone automticamente nmeros binarios generados, cuya exclusividad est garantizada en la base de datos. TIMESTAMP se suele utilizar como mecanismo para marcar la versin de las filas de la tabla. El tamao de almacenamiento es de 8 bytes. El tipo de datos TIMESTAMP de Transact-SQL no es el mismo que el tipo de datos TIMESTAMP definido en el estndar SQL-92. El tipo de datos TIMESTAMP de SQL-92 es equivalente al tipo de datos DATETIME Transact-SQL ROWVERSION Es un sinnimo de TIMESTAMP. UNIQUEIDENTIFIER Un identificador exclusivo global (GUID).

CADENAS DE CARACTERES
CHAR [ (n) ] Datos de caracteres no Unicode de longitud fija con una longitud mxima de 8.000 caracteres. El tamao de almacenamiento es n bytes, la longitud por defecto es 1. CHARACTER es un sinnimo de CHAR VARCHAR [ (n) ] Datos de caracteres no Unicode de longitud variable con una longitud de n bytes. n tiene que ser un valor comprendido entre 1 y 8.000. Cuando no se especifica el argumento n en una instruccin de definicin de datos o de declaracin de variable, la longitud predeterminada es 1. CHAR VARYING y CHARACTER VARYING son sinnimos de VARCHAR. TEXT Datos no Unicode de longitud variable con una longitud mxima de 231 - 1 (1.147.483.647) caracteres.

CADENAS DE CARACTERES UNICODE


NCHAR [ (n) ] Datos Unicode de longitud variable con una longitud mxima de 4.000 caracteres. El tamao de almacenamiento es dos veces n bytes. Si no se especifica longitud por defecto se entiende que es 1. NATIONAL CHAR y NATIONAL CHARACTER son sinnimos de NCHAR. NVARCHAR [ (n) ] Datos Unicode de longitud variable con una longitud mxima de 4.000 caracteres. El tamao de almacenamiento, en bytes, es dos veces el nmero de caracteres especificados. Si no se especifica longitud por defecto se entiende que es 1. NATIONAL CHAR VARYING y NATIONAL CHARACTER VARYING son sinnimos de NVARCHAR. NTEXT Datos Unicode de longitud variable con una longitud mxima de 230 - 1 (1.073.741.823) caracteres.

CADENAS BINARIAS
BINARY [ ( n ) ] Datos binarios de longitud fija con una longitud mxima de 8.000 bytes. Sino se especifica longitud por defecto sta es 1. Se utiliza BINARY cuando las entradas de datos de una columna se espera que tengan un tamao uniforme. VARBINARY [ ( n ) ] Datos Unicode de longitud variable con una longitud mxima de 8.000 bytes. Sino se especifica longitud por defecto sta es 1. Se utiliza VARBINARY cuando las entradas de datos de una columna no vayan a tener un tamao uniforme. IMAGE Datos Unicode de longitud variable con una longitud mxima de 231 - 1 (1.147.483.647) bytes.

163 Los tipos de datos soportados por SqlServer son mucho ms ricos, tanto en variedad como en rangos que soportan, que los que admite la versin de Informix-SQL que aqu se estudia, quiz debido a que la versin de SqlServer es ms moderna. Esto facilitar el que los tipos de datos definidos en Informix-SQL sean tambin admitidos por SqlServer. Como ejemplos el tipo de dato BIGINT definido en SqlServer, Informix-SQL no lo contempla, ocurre lo mismo con el TYNYINT. Los tipos de datos REAL y FLOAT estn definidos en ambos gestores pero sin embargo la precisin que admite SqlServer es mucho mayor que la que admite Informix-SQL 38 y 308 frente a 7 y 15. Segn la informacin proporcionada por el proveedor de driver JDBC para SqlServer, Microsoft, la compatibilidad de los tipos de dato definidos por el gestor con los soportados por el SQL JDBC se muestran en la siguiente tabla:

Tipo Dato SQL Server BINARY BIT CHAR DATETIME DECIMAL DECIMAL() IDENTITY FLOAT IMAGE INT INT IDENTITY MONEY NCHAR NTEXT NUMERIC NUMERIC() IDENTITY NVARCHAR REAL SMALLDATETIME SMALLINT SMALLINT IDENTITY SMALLMONEY SYSNAME TEXT TIMESTAMP BINARY BIT CHAR TIMESTAMP DECIMAL DECIMAL FLOAT LONGVARBINARY INTEGER INTEGER DECIMAL CHAR LONGVARCHAR NUMERIC NUMERIC VARCHAR REAL TIMESTAMP SMALLINT SMALLINT DECIMAL VARCHAR LONGVARCHAR BINARY

Tipo Dato SQL JDBC

164 TINYINT TINYINT IDENTITY UNIQUEIDENTIFIER VARBINARY VARCHAR BIGINT BIGINT IDENTITY SQL_VARIANT TINYINT TINYINT CHAR VARBINARY VARCHAR BIGINT BIGINT VARCHAR

Tabla 25: Mapeo de tipos de datos SqlServer a SQL JDBC Viendo esta relacin y la de la Tabla 24: Mapeos de datos Informix-SQL a SQL JDBC se puede notar que los tipos de datos Informix-SQL tienen su equivalente dentro de los tipos de datos SqlServer, cabe destacar: El tipo de dato CHAR de Informix-SQL admite 32767 de longitud mientras que este tipo en SqlServer tiene un tamao mximo de 8000 caracteres. Esto se tendr en cuenta a la hora crear tablas en SqlServer, utilizando el tipo de dato TEXT si la definicin supera los 8000 caracteres, y a la hora de manipular los datos de las tablas ya que este mismo tipo de dato en el SQL de la API JDBC solo soporta 254 caracteres, en este caso se trabajar con el tipo de dato LONGVARCHAR. El tipo de datos BYTE de Informix-SQL no existe como tal en SqlServer, pero si existe el tipo de dato IMAGE que semnticamente representa lo mismo. A la hora de definir un campo de una tabla de tipo BYTE para SqlServer se crear como IMAGE, aunque durante la manipulacin a travs del API JDBC este se tratar como LONGVARCHAR ya que ambos proveedores de mapean el tipo de dato propio del gestor en el tipo de dato del SQL JDBC LONGVARCHAR. SqlServer no define los tipos de datos DATE y TIME, solo trabaja con el tipo DATETIME. Si en el cdigo fuente se define un campo de una tabla de alguno de los mencionados tipos en el cdigo objeto se crearn como DATETIME ya que este tipo de dato es capaz de albergar la informacin de cualquiera de los dos anteriores. As mismo a la hora de manipularlos se tratarn con el tipo de dato del SQL JDBC TIMESTAMP. El tipo de datos DATETIME de SqlServer admite un rango de fechas inferior al que soporta el tipo de dato DATE de Informix-SQL. El tratamiento de ese problema es algo que excede ste estudio ya que no se pretende hacer un traspaso de datos entre gestores sino que el cdigo fuente que se puede ejecutar sobre el gestor de bases de datos Informix se pueda ejecutar sobre el resto. Los tipos de datos SERIAL e INTERVAL no existe como tal en SqlServer y, aunque el tipo de dato SERIAL se podra representar como un entero su semntica, nmero entero autoincremental, no es implementada por el gestor de bases de datos SqlServer. Estos dos tipos de datos se excluirn de este estudio.

TIPOS DE DATOS DE ORACLE


Los tipos de datos definidos por el gestor de bases de Oracle son:

CADENAS DE CARACTERES
CHAR [ (n) ] Define una cadena de ancho fijo. El mayor tamao admitido es de hasta 2000 bytes. Sino se especifica la longitud por defecto se entiende que tiene un solo carcter (1 byte). NCHAR [ (n) ] Define una cadena de ancho fijo. El mayor tamao admitido es de hasta 2000 bytes o caracteres, admite el juego de caracteres NLS y el tamao de la cadena depender del nmero

165 de caracteres que tenga y el nmero de bytes que ocupe cada uno de ellos. Sino se especifica la longitud por defecto se entiende que tiene un solo carcter (1 byte). VARCHAR [ (n) ] Cadena de caracteres de ancho variable y longitud mxima de 4000 bytes. Se debe especificar el tamao de la cadena en el momento de la definicin. NVARCHAR [ (n) ] Cadena de caracteres de ancho variable y longitud mxima de 4000 bytes o caracteres. El tamao es determinado en funcin del nmero de bytes requeridos para almacenar cada carcter y el nmero de estos. Admite el juego de caracteres NLS. Se debe especificar el tamao en el momento de la definicin. LONG Cadena de ancho variable y hasta un mximo de 2 Gb. Oracle recomienda no usar este tipo de dato.

NUMERICOS
NUMBER [ (p,s) ] Variable numrica definida con precisin y escala. La precisin tiene un rango de 1 a 38 y la escala de -84 a 127. NUMERIC, DEC, y DECIMAL son sinnimos de NUMBER. Oracle soporta los tipos de datos: int, integer, smallint float, double precisin, real, etc. aunque internamente los representa como NUMBER, siguiendo la siguiente tabla:

Tipo de dato DECIMAL, DEC NUMERIC INTEGER INT TINYINT SMALLINT BIGINT FLOAT DOUBLE PRECISION REAL NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER(38) NUMBER NUMBER NUMBER NUMBER

Representacin

Tabla 26: Tipos de datos numricos de Oracle

BINARIOS
RAW (n) Cadenas binarias de longitud variable hasta un mximo de 2000 bytes. LONGRAW Cadenas binarias de longitud variable hasta un mximo de 2 Gb. BLOB Localizadores LOB apuntan a un gran objeto binario, de hasta un mximo de 4Gb, dentro de la base de datos. CLOB Localizadores LOB apuntan a un gran objeto de tipo carcter, de hasta un mximo de 4Gb, dentro de la base de datos . NCLOB Localizadores LOB apuntan a un gran objeto NLS de caracteres, de hasta un mximo de 4Gb, dentro de la base de datos BFILE Localizadores de archivo apuntan a un objeto binario de slo lectura fuera de la base de datos. Longitud mxima 4 Gb.

166

DATETIME
DATE Una fecha entre el 1 de Enero de 4712 A.C. y el 31 de Diciembre de 9999 D.C. Representa fechas con el formato: DD-MON-YYYY HH{A|P}M :MI:SS. Oracle representa internamente las fechas como una cadena de 7 bytes: el primero representa la centuria + 100, el segundo del ao + 100, el tercero el mes, el cuarto el da del mes, el quinto la hora + 1, el sexto el minuto +1 y el sptimo el segundo +1. TIMESTAMP Oracle expande el tipo de dato DATE con este tipo de dato el cual almacena la misma informacin y adems las fracciones de segundo hasta con una precisin de 10 dgitos (por defecto 6 dgitos). El formato de este campo es: DD-MON-YYYY HH:MI:SS.FFFFFFFFFF {A|P}M Oracle admite tambin los tipos de datos: TIMESTAMP WITH TIMEZONE y TIMESTAMP WITH LOCAL TIMEZONE con las mismas caractersticas que el tipo de dato TIMSTAMP pero teniendo en cuenta el horario en funcin de la zona horaria y en funcin de la zona horaria local.

INTERVALOS
INTERVAL DAY TO SECOND, formato: DD HH MI SS, campo de tamao fijo que representa un periodo de tiempo que incluye: das, horas, minutos y segundos INTERVAL YEAR TO MONTH, formato: YYYY MM, campo de tamao fijo que represente un periodo de tiempo en aos y meses.

ROWS
ROWID tipo de dato binario que es utilizado para identificar una fila. UROWID universal rowid, es un tipo de dato utilizado para almacenar el rowid fsico y el lgico cuando las tablas son accedidas a travs de un gateway. Definidos los tipos de datos principales de Oracle es necesario conocer como el JDBC, proporcionado por Oracle, contempla cada uno de ellos a la hora de hablar con el gestor de bases de datos. En la siguiente tabla se muestra en resumen como realiza Oracle el mapeo de sus tipos de datos SQL va JDBC: Tipo Dato Oracle CHAR VARCHAR LONG | CLOB NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER CHAR VARCHAR LONGVARCHAR NUMERIC DECIMAL BIT TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE BINARY Tipo Dato SQL JDBC

167 RAW LONGRAW | BLOB DATE DATE TIMESTAMP VARBINARY LONGVARBINARY DATE TIME TIMESTAMP

Tabla 27: Mapeo de tipos de datos Oracle a SQL JDBC Viendo los tipos de datos que define Oracle puede parecer complicado la transformacin de las sentencias SQL de creacin de tablas de Informix a Oracle ya que el primero define muchos ms tipos de datos numricos, pero la Tabla 27: Mapeo de tipos de datos Oracle a SQL JDBC nos hace ver que todo tipo numrico se representa en Oracle como NUMBER independientemente de su rango con lo cual el cdigo generado para ser ejecutado contra el gestor de bases de datos Oracle solo considerar dicho tipo numrico. Otro elementos que entran en consideracin sobre los tipos de datos Oracle son: No contempla los tipos de datos INTERVAL y SERIAL al igual que pasaba con SqlServer. El tipo de datos INTERVAL si es definido en oracle, pero no es contemplado en la implementacin del JDBC definido por el mismo lo cual imposibilita, en primera instancia, la manipulacin de este dato. No define el tipo de dato MONEY, pero como su semntica es igual a la de un tipo de datos DECIMAL(16,2) el cual si es contemplado por Oracle no habra ningn problema en tratar estos tipos de datos en este gestor tanto en la definicin como en la manipulacin. Aparentemente no soporta el tipo de dato BYTE de Informix-SQL, pero define el tipo de dato LONGRAW que semnticamente es igual con lo cual a la hora de definir campos de tablas si en el fuente aparece el un tipo de datos BYTE se traducir en LONGRAW. La manipulacin del ambos por el API JDBC es a travs del tipo LONGVARCHAR. Los tipos de datos de Informix-SQL TEXT y CHAR de longitud superior a 254 caracteres tienen su equivalente en el tipo de dato LONG de Oracle. El tipo de dato DATE es capaz de albergar, en base a su definicin fechas y horas con lo que los tipos de datos TIME y DATE de Informix-SQL se mapearn en este.

TIPOS DE DATOS DE DB2


Tipos de datos admitidos por DB2 en la creacin de tablas se clasifican en los siguiente grupos:

CADENAS DE CARACTERES
CHAR(n) especifica una cadena n de caracteres de tamao fijo. La longitud mxima es de 254 caracteres. VARCHAR(n) cadena de tamao variable de hasta un mximo de 32672 caracteres.

GRAPHIC
Estos tipos de datos son utilizados para almacenar grficos. El tipo GRAPHIC es una secuencia de bytes que representan datos de tipo carcter de double-bytes. La longitud es el nmero de doublebytes consecutivos reservados. GRAPHIC(n) es una cadena grfica de tamao fijo y un mximo de 127 double-bytes. Si no se especifica n por defecto es 1. VARGRAPHIC(n) Cadena grfica de tamao variable. El rango de double-byte. n va desde 1 hasta 16336

168

NUMERICOS
SMALLINT es una variable de 2 bytes con una precisin de 5 dgitos. El rango vara desde -32768 hasta 32767. INTEGER | INT entero de 4 bytes y una precisin de 10 dgitos. El rango va desde -2147483648 hasta +2147483647. REAL | FLOAT(n) especifica un nmero en punto flotante de simple precisin, si no se indica el valor de n o es menor de 21 entonces se trata de simple precisin, los valores pueden variar desde 7.2E+75 hasta 7.2E+75. FLOAT(n) | DOUBLE PRECISION | FLOAT | DOUBLE especifica un nmero en punto flotante con doble precisin, n puede oscilar entre 22 y 53. Si n se omite por defecto toma el valor de 53. El rango de esta variable va desde 2.225E-307 hasta 1.79769E+308 DECIMAL(p,s) | DEC(p,s) esta variable contiene un valor decimal especificado a travs de su precisin y escala, el mximo valor de precisin es de 31 dgitos y el valor de la escala oscila entre cero y la precisin.

DATE, TIME, AND TIMESTAMP


DATE almacena informacin de fechas (ao, mes, y da). El rango que soporta va desde 1 de enero de 0001 hasta 31 de diciembre de 9999. Este tipo de dato es representado internamente por DB2 como una cadena de 4 bytes. Cada byte representa 2 dgitos. Los dos primeros representan el ao (de 0001 a 9999), el tercero se reserva para el mes (de 1 a 12) y el cuarto contiene el da (de 1 a 31). TIME almacena informacin de horas (hora, minutos, y segundos). El rango que admite va desde las 00 horas 00 minutos 00 segundos hasta 24 horas 00 minutos 00 segundos. La representacin interna que hace DB2 de este dato es una cadena de tres bytes, un byte para las horas, otro para los minutos y el ltimo para los segundos. TIMESTAMP este tipo de dato contiene informacin de la fecha y la hora hasta un precisin de milisegundos (ao, mes, da, hora, minutos, segundos, y microsegundos). El rango que admite vas desde 1 de enero de 0001 a las 00 horas 00 minutos 00 segundos 000000 microsegundos hasta el 31 de diciembre de 9999 a las 24 horas 00 minutos 00 segundos 000000 microsegundos. La representacin interna de este tipo de dato es mediante una cadena de 10 bytes: 4 para la fecha, 3 para la hora y los otros tres para representar los microsegundos.

BLOB, CLOB AND DBCLOB


BLOB(n[K|M|G]) tipo de dato que define un objeto binario largo de longitud variable hasta un mximo de 2 Gb. Si solo se especifica el valor de n este indica la longitud mxima. Si K, M, o G son especificados estos pueden ser como mximo: 1024, 1048576 o 1073741824 y n podr valer como mximo: 2097152, 2048 o 2 respectivamente. CLOB(n[K|M|G]) cadena de caracteres de tamao variable y de hasta un mximo de 2 Gb. de longitud. DBCLOB(n[K|M|G]) objeto de tamao variable que almacena cadenas de caracteres grficos de tamao double-byte. La longitud mxima es de 1073823 caracteres de longitud.

VALORES ROW ID
Los valores ROWID son valores que identifican unvocamente una fila en una tabla. Cada valor en una columna ROWID debe de ser nico, cuando una fila es insertada en una tabla, DB2 genera el valor de la columna ROWID amenos que este sea proporcionado. Si el valor ROWID es proporcionado a de ser un valor valido. No se pueden modificar, por el usuario, el valor de una columna tipo ROWID. En la siguiente tabla se muestran los tipos de datos de DB2 y su correspondiente JDBC: Tipo de dato DB2 SMALLINT Tipo dato SQL JDBC BIT, TINYINT, SMALLINT

169 INTEGER REAL DOUBLE DECIMAL CHAR GRAPHIC VARCHAR VARGRAPHIC CLOB(n) BINARY VARBINARY BLOB(n) DATE TIME TIMESTAMP BLOB CLOB DBCLOB INTEGER FLOAT, REAL DOUBLE NUMERIC, DECIMAL CHAR CHAR VARCHAR, LONGVARCHAR VARCHAR VARCHAR, LOGVARHAR, CLOB BINARY VARBINARY VARBINARY, LONGVARBINARY DATE TIME TIMESTAMP BLOB CLOB CLOB

Tabla 28: Mapeo de tipos de datos DB2 a SQL JDBC Como se ve algn tipo de datos SQL de DB2 se puede convertir en ms de uno JDBC esto se entiende desde dos puntos de vista: algunos de los tipos de datos JDBC son sinnimos como el caso de DECIMAL y NUMERIC y en otros casos el tipo de datos DB2 en funcin de su longitud se podr convertir en uno u otro de los tipos de datos JDBC. A la hora de convertir los tipos de datos Informix-SQL a DB2 nos encontramos los mismos problemas que ocurran con Oracle y tambin con la misma solucin para los casos en los que la hay.

TABLA DE MAPEOS
Del estudio realizado en los puntos anteriores en el que se muestran los tipos de datos soportados por el API JDBC de Java, los definidos por cada uno de los diferentes gestores de bases de datos, y la implementacin que cada proveedor de base hace del JDBC as se obtienen las dos tablas que se muestran a continuacin: La primera se centra encontrar los mapeos adecuados que garanticen que las definiciones de datos que se hace en el cdigo fuente Informix-SQL, y por tanto validas para se ejecutadas contra el gestor de bases de datos Informix, puedan ser ejecutadas contra el resto de gestores de bases de datos haciendo para ello las modificaciones oportunas en el cdigo generado. Estos mapeos permitirn que las sentencias de definicion de datos: create, alter, etc. puedan ser ejecutadas contra cualquier gestor de bases de datos de forma transparente e independiente a su definicin. La segunda muestra los mapeos entre los tipos de datos Informix-SQL y los tipos de datos SQL JDBC y la correlacin con los mapeos que hace el resto de proveedores de bases de datos con los tipos de datos SQL JDBC. Esta segunda tabla es la que nos permitir saber como manipular los datos en las sentencias SQL de forma independiente a la definicin del mismo que se hace en cada gestor.

170

Tipo Dato Informix


BYTE CHAR | CHARACTER (254) CHAR | CHARACTER (35767) DATE DATETIME year to day DATETIME hour to second DATETIME DEC | DECIMAL | NUMERIC DOUBLE PRECISION | FLOAT INTEGER | INT INTERVAL MONEY SMALLFLOAT | REAL SMALLINT SERIAL TEXT (2 Gb) VARCHAR (254)

Tipo Dato JDBC Informix

Tipo Dato SQLSERVER

Tipo Dato Oracle


LONGRAW |BLOB CHAR(2000) LONG ( 2 Gb) DATE DATE DATE TIMESTAMP DECIMAL FLOAT INTEGER ---------DECIMAL REAL SMALLINT INTEGER CLOB (4 Gb) VARCHAR(4000)

Tipo Dato DB2


BLOB CHAR (254) VARCHAR (35767) DATE DATE TIME TIMESTAMP DECIMAL FLOAT INTEGER ---------DECIMAL REAL SMALLINT INTEGER CLOB (2 Gb) VARCHAR (4000)

LONGVARBINARY IMAGE CHAR (254) LONGVARCHAR DATE DATE TIME TIMESTAMP DECIMAL FLOAT INTEGER no soportado DECIMAL REAL SMALLINT INTEGER LONGVARCHAR VARCHAR CHAR (8000) TEXT (2 Gb) DATETIME DATETIME DATETIME DATETIME DECIMAL FLOAT INTEGER ---------DECIMAL REAL SMALLINT INTEGER TEXT (2 Gb) VARCHAR(8000)

Tabla 29: Mapeo entre tipos de datos Informix-SQL y el resto de gestores

Tipo Dato Informix


BYTE CHAR | CHARACTER CHAR | CHARACTER DATE DATETIME year to day DATETIME hour to second DATETIME DEC | DECIMAL | NUMERIC DOUBLE PRECISION | FLOAT INTEGER | INT INTERVAL MONEY SMALLFLOAT | REAL

Tipo Dato Tipo Dato JDBC JDBC Informix SQLSERVER


LONGVARBINARY LONGVARBINARY CHAR LONGVARCHAR DATE DATE TIME TIMESTAMP DECIMAL FLOAT INTEGER no soportado DECIMAL REAL CHAR LONGVARCHAR TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP DECIMAL FLOAT INTEGER ---------DECIMAL REAL

Tipo Dato JDBC Oracle


LONGVARBINARY CHAR LONGVARCHAR DATE DATE TIME TIMESTAMP DECIMAL FLOAT INTEGER ---------DECIMAL REAL

Tipo Dato JDBC DB2


LONGVARBINARY CHAR LONGVARCHAR DATE DATE TIME TIMESTAMP DECIMAL FLOAT INTEGER ---------DECIMAL REAL

171
SMALLINT SERIAL TEXT VARCHAR SMALLINT INTEGER LONGVARCHAR VARCHAR SMALLINT INTEGER IDENTITY SMALLINT INTEGER SMALLINT

GENERATED IDENTITY
LONGVARCHAR VARCHAR

INTEGER

AS

LONGVARCHAR VARCHAR

LONGVARCHAR VARCHAR

Tabla 30: Mapeos de datos Informix-SQL a implementaciones JDBC de los gestores A continuacin se mostrar un ejemplo ilustrativo de cmo se generar el cdigo objeto, a partir de la definicin de tablas, para cada uno del gestores de base de datos sobre el cual se pueda ejecutar una aplicacin: Cdigo fuente Informix:
create table tabla99 ( campo1 byte, campo2 char, campo3 char(10), campo4 char(9000), campo5 date, campo6 datetime year to day, campo7 datetime hour to second, campo8 datetime year to second, campo9 decimal, campo10 decimal(10), campo11 decimal(10,2), campo12 float, campo13 integer, campo14 money, campo15 real, campo16 smallint, campo17 text, campo18 varchar(30) )

Cdigo objeto generado para ejecutarse contra gestor de base de datos Informix:
create table tabla99 ( campo1 byte , campo2 char(1) , campo3 char(10) , campo4 char(9000) , campo5 date , campo6 date , campo7 datetime hour to second , campo8 datetime year to second , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 text , campo18 varchar(30) )

Cdigo objeto generado para ejecutarse contra gestor de base de datos SqlServer:
create table tabla99 ( campo1 image , campo2 char(1) , campo3 char(10) , campo4 text , campo5 datetime ,

172
campo6 datetime , campo7 datetime , campo8 datetime , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 text , campo18 varchar(30) )

Cdigo objeto generado para ejecutarse contra gestor de base de datos Oracle:
create table tabla99 ( campo1 blob , campo2 char(1) , campo3 char(10) , campo4 long , campo5 date , campo6 date , campo7 date , campo8 timestamp , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 clob , campo18 varchar(30) )

Cdigo objeto generado para ejecutarse contra gestor de base de datos Db2:
create table tabla99 ( campo1 blob , campo2 char(1) , campo3 char(10) , campo4 long varchar , campo5 date , campo6 date , campo7 time , campo8 timestamp , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 clob , campo18 varchar(30) )

Dentro del Anexo I se pueden ver ejemplos prcticos, de traduccin de cdigo fuente a objeto, de la creacin de una tabla en la que intervienen todos los tipos de datos. Dirigirse al apartado: Ejemplo sentencia tipos de datos.

MAPEO DE TIPOS DE DATOS ENTRE JDBC Y JAVA

Ya hemos definido los mapeos entre Informix-SQL y el resto de gestores de bases de datos necesario para la creacin de tablas en cada gestor de bases de datos, tambin se han mostrado la tabla de mapeos de todos los gestores con el SQL JDBC interface que se utilizar para la

173 manipulacin de los datos entre el lenguaje de programacin y el gestor de bases de datos. Ahora lo que nos queda es saber que tipo de dato Java se utilizar como contenedor inicial o final de los datos utilizados o retornados de la ejecucin de una sentencia SQL. Para ello se ha de definir el mapeo entre los tipos de dato SQL JDBC y Java y viceversa. El interface JDBC proporciona un mapeo razonable de los tipos de datos SQL ms comunes a Java. En los puntos anteriores hemos obtenido la suficiente informacin sobre los tipos de datos de los diferentes gestores como para poder garantizar que las tareas de almacenar y obtener parmetros y recuperar resultados de las sentencias SQL sean posibles de forma segura. En la tabla que se muestra a continuacin se muestran los mapeos de los tipos de datos SQL JDBC definidos en la Tabla 30: Mapeos de datos Informix-SQL a implementaciones JDBC de los gestores a los tipos de datos Java.

Tipo de dato SQL JDBC CHAR VARCHAR LONGVARCHAR NUMERIC | DECIMAL SMALLINT INTEGER REAL FLOAT DOUBLE LONGVARBINARY DATE TIME TIMESTAMP String String String

Tipo de dato Java

java.math.BigDecimal short int float double double byte[] java.sql.Date java.sql.Time java.sql.Timestamp

Tabla 31: Mapeo entre tipos de datos SQL JDBC y Java En la siguiente tabla se muestra el mapeo inverso al mostrado en la tabla anterior:

Tipo de dato Java String java.math.BigDecimal short int float Double byte[] java.sql.Date

Tipo de dato SQL JDBC VARCHAR o LONGVARCHAR NUMERIC | DECIMAL SMALLINT INTEGER REAL DOUBLE VARBINARY o LONGVARBINARY DATE

174 java.sql.Time java.sql.Timestamp TIME TIMESTAMP

Tabla 32: Mapeo entre tipos de datos Java y SQL JDBC

FUNCIONES DE RECUPERACION DE DATOS SQL


Para recuperar datos SQL de una tabla de una base de datos lo primero que debemos saber es el tipo de dato a recuperar, y esto lo podramos saber de varias formas: En la definicin de la tabla podemos guardar el tipo de dato de cada columna. Esto solo nos vale si en el programa actual trabajamos con una tabla que hemos creado en el mismo. A travs del dato sobre el cual se va a almacenar el resultado. Es un mtodo bastante bueno pero impreciso. La mejor solucin es consultar al propio gestor de bases de datos de que tipo de dato es el campo que se pretende recuperar.

La API JDBC de Java proporciona en su clase ResultSet mtodos suficientes para recuperar los datos SQL de una base de datos. JDBC permite muchas lateralidades para utilizar los mtodos getXXX para obtener diferentes tipos de datos SQL, por ejemplo, el mtodo getInt puede ser utilizado para recuperar cualquier tipo numrico de caracteres. Los datos recuperados sern convertidos a un int; esto es, si el tipo SQL es VARCHAR, JDBC intentar convertirlo en un entero. Lo ideal es utilizar cada mtodo para recuperar el tipo de dato para el cual fue diseado, esto no implica que un mismo mtodo pueda ser utilizado para recuperar distintos tipos de datos SQL, por ejemplo el mtodo getString es el adecuado para recuperar campos de los tipos de datos CHAR, VARCHAR e incluso LONGVARCHAR. Java proporciona es su documentacin relativa a la API JDBC una tabla con todas las posibilidades de mtodo a aplicar para recuperar cada tipo de datos SQL. En la tabla que hay a continuacin muestra el mtodo ms adecuado para recuperar tipos SQL JDBC.

Tipo de dato SQL JDBC CHAR VARCHAR LONGVARCHAR NUMERIC | DECIMAL SMALLINT INTEGER REAL FLOAT DOUBLE LONGVARBINARY DATE TIME GetString GetString

Funcin Java para recuperarlo

GetAsciiStream, getCharacterStream, getString GetBigDecimal, getDouble GetShort GetInt GetFloat GetDouble GetDouble GetBinaryStream GetDate GetTime

175 TIMESTAMP GetTimestamp

Tabla 33: Funciones para recuperacin de datos del gestor de bases de datos

CONVERSIONES DE TIPOS DE DATOS


En este punto se trata:

En general los valores son representados por algn tipo de dato. Cada tipo de dato describe que tipo de informacin almacena y que tipo de operaciones se pueden hacer sobre el mismo. En algunos casos un valor almacenado en un tipo de dato puede convertirse en otro. Describir las conversiones automticas o implcitas que son soportadas por el gestor de bases de datos Informix con el objeto de saber si aquellas que se hayan aplicado en el cdigo fuente pueden ser mantenidas en el cdigo destino y por tanto ejecutadas sobre otros gestores de bases de datos sin generar ningn error de ejecucin. Reconocer aquellas conversiones que siendo tratadas como implcitas en el gestor de bases de datos origen en el destino no lo son, son explicitas, y en tal caso aplicar las medidas necesarias a la hora de generar cdigo para que dichas conversiones sean tambin aplicables sobre el gestor de bases de datos destino de forma transparente.

El gestor de bases de datos Informix soporta conversiones implcitas de datos dentro de las expresiones SQL en las siguientes situaciones: Comparaciones. Una conversin de datos ocurre cuando se comparan dos valores de diferente tipo. Inserciones. Se produce una conversin de dato cuando se trata de insertar una valor de un tipo de variable en una columna de la base de datos de diferente tipo. Operaciones aritmticas. Cuando se aplica un operador sobre valores de diferente tipo.

El gestor de bases de datos automticamente invoca un casting implcito cuando necesita evaluar y comparar expresiones. Operaciones que requieran ms que un casting implcito producen un error. En la gua de referencia de SQL de Informix se contemplan los siguientes tipos de conversiones: Nmero a nmero. Una conversin implcita se aplicar siempre y cuando esta sea posible, sea, si el tipo de dato destino pueda albergar el valor de origen. En caso contrario se producir un error. En el caso tratarse de operaciones aritmticas Informix-SQL hace las mismas sobre valores de tipo DECIMAL independientemente de los tipos de datos de los operndoos. Entre nmero y carcter y viceversa. La conversin entre valores tipo char a nmero ser posible siempre y cuando la cadena contenga nicamente un valor numrico valido. El caso contrario siempre ser posible si la longitud de la cadena puede albergar los dgitos del nmero a convertir. Entre fecha y fecha-hora. Se pueden convertir valores tipo DATE a DATETIME siempre y cuando la precisin del tipo de datos destino tenga al menos hasta el da, si tiene ms se completa, al hacer la conversin, con ceros. Es posible expresar fechas mediante literales tipo cadena. Estas son convertidas automticamente en valores tipo DATE o DATETIME siempre y cuando la cadena contenga un valor tipo fecha expresado en un formato adecuado: DATE = mm/dd/yyyy y DATETIME = yy-mm-dd hh:mm:ss.fff En la tabla que se muestra a continuacin se ilustran las conversiones implcitas soportadas por Informix. Las casillas sombreadas hacen referencia a conversiones no posibles y las otras a conversiones factibles aunque tiendo en cuenta las siguientes consideraciones:

176 En algn caso puede haber posibles fallos de conversin o discrepancia entre los valores recibidos y los esperados. Se pueden producir resultados inesperados bien por su valor o por su formato.

Tipo de dato destino

SMALLFLOAT

DATETIME
Y Y Y

SMALLINT

CHAR

CHAR

VARCHAR INTEGER SMALLINT

Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

DATE
Y Y Y Y Y Y Y Y Y

Tipo de dato origen

FLOAT SMALLFLOAT DECIMAL MONEY DATE

Y Y Y Y Y

Y Y Y

DATETIME INTERVAL

Tabla 34: Conversiones implcitas soportadas por Informix No es soportada por Informix ninguna otra conversin que involucre tipos de datos binarios largos: TEXT y BYTE. El resto de gestores de bases de datos tienen un comportamiento similar ante las conversiones implcitas. Todos ellos soportan este tipo de conversiones aunque cada uno con sus peculiaridades y restricciones. A continuacin se mostrarn las tablas de conversiones implcitas proporcionadas por cada proveedor de bases de datos y en el siguiente punto: tratamiento de las conversiones no implicitas se analizarn y buscarn soluciones para aquellas que puedan ser problemticas a la hora de traducir cdigo fuente Informix-SQL a cdigo objeto ejecutable sobre al gestor de bases de datos destino. Las tablas que se muestran a continuacin siguen la misma nomenclatura que la vista al definir las conversiones implcitas soportadas por Informix. En el caso de SqlServer si admite las conversiones implcitas y explcitas, estas ultimas con las funciones CAST Y CONVERT. En la tabla siguiente se muestras las conversiones implcitas admitidas por SqlServer: Tipo de dato destino
VARBINARY NVARCHAR UNIQUEIDENTIFIER

SMALLDATETIME

INTERVAL
Y Y

VARCHAR

DECIMAL

INTEGER

MONEY

FLOAT

BINARY

BIGINT

MONEY

NCHAR

IMAGE

BINARY

VARBINARY

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

Y Y

NTEXT

FLOAT

CHAR

REAL

TEXT

Tipo de dato origen

SQL_VARIANT
Y Y

SMALLMONEY

TIMESTAMP

DATETIME

SMALLINT

VARCHAR

NUMERIC

DECIMAL

TINYINT

INT

BIT

177
CHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

VARCHAR NCHAR NVARCHAR DATETIME DECIMAL FLOAT REAL INT SMALLDATETIME NUMERIC

Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y

BIGINT SMALLINT TINYINT MONEY

Y Y Y Y Y Y Y

SMALLMONEY BIT TIMESTAMP IMAGE NTEST TEXT

UNIQUEIDENTIFIER

Y Y Y

Y Y Y

Y Y Y

Y Y Y

Y Y

Y Y

SQL_VARIANT

Tabla 35: Conversiones soportadas por SqlServer En el caso del gestor de bases de datos Oracle, al igual que la mayora de gestores, recomienda no usar conversiones implcitas y en su lugar las explcitas, por varias razones: Pueden tener un impacto negativo en el rendimiento del gestor de bases de datos. Dependiendo del contexto en el que se aplican se pueden comportar de diferente manera. Los algoritmos para conversiones implcitas estn sujetos a cambios segn van saliendo nuevas versiones de software.

En la tabla que se muestra a continuacin se plasma la matriz de conversiones implcitas que soporta Oracle:

ROWID

NCHAR

CHAR DATE

VARCHAR TIMESTAMP LONG NUMBER ROW ROWID CLOB BLOB

Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y

Y Y

Y Y

Y Y Y

Y Y

Y Y

Y Y

Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y Y Y Y

NCLOB

CHAR

LONG

BLOB

DATE

CLOB

ROW

Tipo de dato origen

Y Y

Y Y

Y Y Y Y Y Y

NCHAR

Y Y

N BINARY_DOUBLE

Tipo de dato destino


BINARY_FLOAT NVARCHAR2 TIMESTAMP

VARCHAR

NUMBER

178
NVARCHAR2 NCLOB BINARY_FLOAT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

Y Y Y

BINARY_DOUBLE

Tabla 36: Conversiones implcitas soportadas por Oracle Para el gestor de bases de datos DB2 tambin existe la posibilidad de aplicar conversiones implcitas y explcitas. El gestor de bases de datos puede convertir implcitamente tipos de datos durante las asignaciones en las que participa un tipo diferente. La Tabla 37 muestra las conversiones implcitas permitidas entre tipos de datos internos. Tipo de dato destino

VARGRAPHIC

TIMESTAMP
Y Y Y Y

VARCHAR

GRAPHIC

DECIMAL

SMALLINT

INTEGER

DOUBLE

DBCLOB

CHAR

BLOB

DATE

CLOB

REAL

SMALLINT INTEGER REAL DECIMAL DOUBLE CHAR VARCHAR CLOB GRAPHIC DBCLOB BLOB DATE TIME VARGRAPHIC

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y

Y Y Y

TIMESTAMP ROWID

Tabla 37: Conversiones implcitas soportadas por DB2 Cuando se asigna un tipo de dato GRAPHIC o CHARACTER a otro tipo de dato se puede producir un truncado del valor final.

TRATAMIENTO DE LAS CONVERSIONES NO IMPLICITAS


Es importante mencionar que todo gestor de bases de datos contempla las conversiones implcitas con cierta preocupacin debido principalmente a que pueden producirse errores de: precisin, trucado, etc. durante las mismas. En el proceso de analizar si las conversiones implcitas definidas por Informix-SQL son tambin soportadas por el resto de gestores de bases de datos hay que tener muy presente los mapeos entre tipos de datos Informix-SQL y el resto de gestores definidos en la Tabla 29: Mapeo entre tipos de datos Informix-SQL y el resto de gestores y utilizados para la traduccin del cdigo fuente, que se ejecuta sobre el gestor de bases de datos, a cdigo objeto. Solo interesar saber que son soportadas aquellas conversiones que se pueden llegar a producir en el gestor de base de datos destino y sobre los tipos de datos que se vayan a aplicar. Por ejemplo sobre SqlServer no se va producir un intento de conversin de un tipo de dato BIT a ningn otro debido a que ningn tipo de dato Informix-SQL que se va a traducir al tipo de dato SqlServer BIT durante el proceso de paso de cdigo fuente a objeto. Segn esto las tablas de conversiones implcitas proporcionadas

TIME

Tipo de dato origen

ROWID

179 por los proveedores se reducirn bastante como se ver en las tablas que se muestran seguidamente. De las tablas que se muestran a continuacin se han eliminado las conversiones implcitas de: Los tipos de datos que contempla el gestor destino y el origen no, tales como BINARY y VARBINARY en SqlServer, NCHAR y NVARCHAR en Oracle, etc. Aquellos tipos de datos que aunque se contemplan en gestor origen y destino en el primero no se definen conversin implcita tales como: TEXT, BYTE, etc. desapareciendo as la necesidad de estudiar en SqlServer los tipos de datos: TEXT e IMAGE, en Oracle los tipos: LONGRAW y CLOB y en DB2 los tipos: BLOB y CLOB.

En las tablas que se muestran a continuacin se identifican en rojo aquellas conversiones que Informix-SQL trata como implcitas y que sin embargo de aplicarse sobre otro gestor produciran errores al no ser consideradas por estos como tal. Es todas las tablas asociado al tipo de dato CHAR, y no de forma independiente, aparece el tipo de dato que permite cadenas de caracteres de tamao superior al CHAR: TEXT, LONG, VARCHAR segn el gestor que se este estudiando: CHAR/TEXT, CHAR/LONG, CHAR/VARCHAR, esto se hace as para denotar que se ha de tener en cuenta que el tipo CHAR de Informix-SQL se puede convertir en dichos tipos de datos sobre el gestor destino y aunque sobre dichos tipos no se contemple ninguna conversin implcita habr que considerar estos casos a la hora de traducir cdigo fuente a objeto. La solucin ms comn que se utilizar para solventar los problemas que se plantean sobre los gestores de bases de datos destinos para soportar las conversiones implcitas que define InformixSQL ser aplicar, a la hora de generar cdigo, conversiones explicitas.

SQLSERVER
A continuacin se muestra la tabla definitiva de conversiones posibles a utilizar en SqlServer y el estudio detallado cmo enfrentarse a aquellos casos en los que SqlServer no considera conversiones implcitas y sin embargo Informix-SQL s.

Tipo de dato destino


CHAR/text DATETIME SMALLINT VARCHAR NUMERIC DECIMAL

FLOAT

REAL

CHAR/text VARCHAR DECIMAL FLOAT REAL INT DATETIME NUMERIC

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y/N Y Y Y Y Y Y Y

Y/N Y

Y/N Y Y Y Y Y Y

Y/N Y Y Y Y Y Y

Y/N Y Y Y Y Y Y

Y/N Y Y Y Y Y Y

INT

Tipo de dato origen

Y/N Y Y Y Y Y Y

Y Y Y Y Y

SMALLINT

Tabla 38: Conversiones implcitas necesarias para SqlServer Sobre el gestor de bases de datos SqlServer se plantean problemas, principalmente, sobre el tipo de datos DATETIME. La solucin consistir en utilizar la funcin de SqlServer: CONVERT que permite, entre otras, realizar la conversin explicita de tipos de datos fecha/hora a nmero3.
Para ms informacin dirigirse a los libros de pantalla de Microsoft SQL

180 La conversin implcita que Informix-SQL hace del tipo de dato DATE a nmero se basa en proporcionar el nmero de das desde el 1 de enero de 1900 de tal forma que para la fecha 31/12/1899 nos devuelve 0, para 01/01/1900 1 y para el resto de fechas la cuenta de das. En el caso de SqlServer el comportamiento es similar, la funcin CONVERT retorna la cuenta de das desde el 1 de enero de 1900 aunque para el da 01/01/1900 nos retorna el valor 0 y para 31/12/1899 nos retorna el valor 1. Ejemplos de la funcin CONVERT de SqlServer: CONVERT(int, expr_datetime,formato) CONVERT(int, getdate()) CONVERT(int, CONVERT(datetime,'12/31/1899')) CONVERT(int, CONVERT(datetime,'01/01/1900')) = = = 39149 = 09/03/2007 -1 0 = 31/12/1899 = 01/01/1900

A continuacin se muestra un ejemplo prctico de cmo aplicar esta solucin al problema sobre el gestor de base de datos SqlServer: Codigo fuente: Select count(*) from tablaX where campo_fecha = 1 Esta sentencia devolver el nmero de filas de la tablaX donde el campo fecha tenga un valor de: 01/01/1900. El cdigo objeto Sqlserver ser: Select count(*) from tablaX where CONVERT(int, campo_fecha) = 1 Esta sentencia devolver el nmero de filas de la tablaX donde el campo fecha tenga un valor de: 02/01/1900. Como se puede observar, despus de haber solventado el problema de la conversin implcita, el resultado de ejecutar la sentencia para Informix-SQL y SqlServer no es el mismo. Esto nos da pe a plantear otro problema: aunque SqlServer permita la conversin implcita de valor numrico a DATETIME el resultado de una operacin sobre Informix-SQL no ser el mismo que el de aplicar la misma operacin sobre SqlServer ya ambos gestores interpretan ese valor numrico como una fecha distinta. La forma de tratar esta diferencia semntica as como los lugares donde ser necesario tenerla en cuenta se estudiar posteriormente en el punto: Tratamiento de las fechas. En la tabla de concesiones implcitas necesarias se marca la concesin de CHAR/TEXT a DATETIME, DECIMAL, NUMERIC, etc. con Y/N, con esto se trata de indicar que la conversin implcita de CHAR estos tipos de datos si es soportada, pero la de TEXT no. Esto no ha de ser tratado de forma especial ya que la aparicin del tipo de dato TEXT es por la necesidad de conversin de cadenas grandes de Informix-SQL a SqlServer y una cadena grande es muy poco probable que contenga un valor susceptible de ser convertido a los tipos de datos destino indicados en la tabla.

ORACLE
Tipo de dato destino
CHAR /long VARCHAR

TIMESTAMP
Y Y Y

CHAR /long VARCHAR DATE

Y Y Y Y

Y Y Y Y

Y/N Y

DATE

Tipo de dato origen

Y/N

TIMESTAMP NUMBER

Tabla 39: Conversiones implcitas necesarias para Oracle

NUMBER

181 Como se ve en la tabla de conversiones implcitas necesarias para Oracle se plantean problemas sobre los tipos de datos: DATE, DATETIME y NUMBER. El tratamiento adoptado es el mismo que para el gestor de bases de datos SqlServer aplicar conversiones explicitas donde las implcitas no se puedan utilizar. Como paso previo para entender la solucin adoptada para cada uno de los casos es preciso conocer algunas funciones de Oracle, estas son: TO_CHAR convierte el valor que recibe como primer parmetro a un tipo de dato VARCHAR2. Tiene varias definiciones: TO_CHAR (<fecha_o_columna>, [ <formato> [, <nsl_parametro>] ]) TO_CHAR (<nmero_o_columna>, [<formato> [, <nsl_parametro>] ]) TO_CHAR (<cadena_o_columna>) TO_NUMBER convierte el un valor tipo carcter: CHAR, VARCHAR2, NCHAR, o NVARCHAR2 que contiene un valor numrico a un valor de tipo NUMBER. Opcionalmente permite especificar el formato. TO_NUMBER (<cadena_o_columna>, [ <formato> [,<nsl_parametro>] ]) TO_DATE convierte un valor de tipo cadena: CHAR, VARCHAR2, NCHAR, o NVARCHAR2 a un valor de tipo DATE. Si se omite el formato se entiende que este es el que haya por defecto, si este es: J, indicando calendario Juliano y en este caso el primer parmetro ha de ser un entero. TO_DATE (<cadena_o_columna>, [ <formato> [,<nsl_parametro>] ]) TO_DATE (<nmero_o_columna>, [ <formato> ]) TO_TIMESTAMP convierte el valor que recibe como primer parmetro de tipo cadena: CHAR, VARCHAR2, NCHAR, o NVARCHAR2 a un valor de tipo TIMESTAMP. TO_TIMESTAMP (<cadena_o_columna>, [ <formato> [,<nsl_parametro>] ]) CAST convierte el valor que recibe como parmetro en otro. CAST (<expresin> AS <tipo_de_dato> ) Esta funcin est limitada a ciertos tipos de datos. Para informacin ms detallada sobr estas funciones referirse al manual de referencia SQL de Oracle. La solucin aportada para tratar las conversiones que en cdigo fuente, Informix-SQL, se consideran implcitas y al tratar de ejecutarlas sobre el gestor destino, Oracle, produciran errores es: Convertir de DATE a TIMESTAMP. Existen dos funciones explcitas que permiten hacer est conversin: TO_TIMESTAMP y CAST, a continuacin se ponen dos ejemplos: TO_TIMESTAMP(campo_date,'YYYY-MM-DD HH:MI:SS') TO_TIMESTAMP('1999-12-01 11:00:00','YYYY-MM-DD HH:MI:SS') CAST(campo_date AS TIMESTAMP) Para Convertir de tipo de dato DATE a NUMBER se utiliza la funcin TO_NUMBER en combinacin con TO_CHAR. La primera recibe un tipo de dato cadena y lo pasa a nmero y la segunda permite convertir un tipo de dato DATE a CHAR. Ejemplo: TO_NUMBER(TO_CHAR(SYSDATE,'J')) 2454169 (sysdate = 09/03/2007) TO_NUMBER(TO_CHAR(TO_DATE('01/01/1900','DD/MM/YYYY'),'J')) 2415021 TO_NUMBER(TO_CHAR(TO_DATE('31/12/1899','DD/MM/YYYY'),'J')) 2415020

182 Esta funcin devuelve el nmero de das desde el 1 de enero del 4712 antes de Cristo. La conversin explicita del tipo de dato TIMESTAMP a DATE se realiza con la funcin TO_DATE en combinacin con TO_CHAR o con la funcin CAST tambin junto con TO_CHAR. A continuacin se muestran ejemplos: TO_DATE('11-10-99 01:23:45', 'MM-DD-YY') TO_DATE(TO_CHAR(datetimecol, 'DD/MM/YYYY HH24:MI:SS'),DD/MM/YYYY) TO_DATE(TO_CHAR(10/12/2005 14:15:00, 'DD/MM/YYYY HH24:MI:SS'),DD/MM/YYYY) CAST(datetimecol AS DATE) CAST( TO_CHAR(10/12/2005 14:15:00, 'DD/MM/YYYY HH24:MI:SS') AS DATE) La ltima conversin a tener en cuenta es de NUMBER a DATE para ello se utilizar la funcin TO_DATE en conjuncin con TO_CHAR. A continuacin se muestran ejemplos: TO_DATE ( TO_CHAR ( valor_numerico, '99999999999') , 'J') TO_DATE ( TO_CHAR ( 103465, '99999999999') , 'J') En el caso de que el gestor destino sea Oracle hay que tratar como explicitas tanto la conversin de nmero a fecha como de fecha a nmero y en este caso tambin debemos fijarnos en que el valor numrico es interpretado de forma diferente a como lo hace Informix-SQL, la forma de solventar esta diferencia semntica se ver en el punto: Tratamiento de las fechas. Al igual que con el gestor de bases de datos SqlServer el tipo de datos origen CHAR/LONG tiene problemas a la hora de convertir de forma implcita el tipo LONG a tipo DATE y NUMBER. La solucin adoptada ser la misma: no hacer nada ya que son conversiones que no se van a producir, eso s se recomienda se revise el cdigo generado para garantizar la integridad en la traduccin.

DB2
Tipo de dato destino

CHAR /VARCHAR

SMALLINT INTEGER REAL DECIMAL DOUBLE

Y Y Y Y Y Y

Y Y Y Y Y Y

Y Y Y Y Y Y

Y Y Y Y Y Y

Y Y Y Y Y Y

Y Y Y Y Y Y Y Y

Y Y Y Y Y Y Y Y Y Y Y Y Y

CHAR/VARCHAR VARCHAR DATE

TIMESTAMP

Tabla 40: Conversiones implcitas necesarias para DB2 Como se muestra en la tabla anterior para DB2 se plantean problemas al tratar de convertir el tipo de dato DATE a nmero y TIMESTAMP y con los tipos de datos numricos a DATE. El tratamiento adoptado, a la hora de hacer que el cdigo fuente Informix-SQL se pueda ejecutar sobre el gestor de bases de datos DB2, es el mismo que para el resto de gestores: utilizar conversiones explicitas donde las implcitas produciran errores.

DATE

REAL

Tipo de dato origen

TIMESTAMP

VARCHAR

DECIMAL

SMALLINT

INTEGER

DOUBLE

183 Para convertir el tipo de dato DATE a TIMESTAMP se utilizar una combinacin de funciones soportadas por DB2. estas son: CHAR que retorna una cadena correspondiente al valor formado por el dato que recibe como primer parmetro, tipo fecha, tras aplicarle el formato indicado en el segundo parmetro. TIMESTAMP_FORMAT que convierte a tipo TIMESTAMP el valor de tipo cadena que recibe como parmetro. CONCAT que retorna la cadena resultante de concatenar las dos valores de tipo cadena que recibe como parmetros.

La combinacin de estas funciones que nos permite hacer esta conversin explicita es: TIMESTAMP_FORMAT(CONCAT(CHAR(campo_date,ISO),' 00:00:00'),'YYYY-MM-DD HH24:MI:SS') TIMESTAMP_FORMAT(CONCAT('2007-03-09',' 00:00:00'),'YYYY-MM-DD HH24:MI:SS') La conversin de NUMBER a DATE se puede conseguir utilizando la funcin DATE. Esta funcin recibe como parmetro una fecha en formato cadena o un nmero que representa el nmero de das menos 1 desde el 1 de enero de 0001. DATE(nmero) DATE(693595) 1899-12-31 La conversin de DATE a NUMBER se realiza con la funcin DAYS la cual retorna el nmero de das + 1 desde el 1 de enero del 0001 recibiendo como parmetro la fecha en formato cadena, fecha o fecha/hora. DAYS(CHAR(campo_date,LOC)) DAYS(03/09/2007) 732744 DAYS(01/01/1900) 693596 DAYS(31/12/1899) 693595 DAYS(CHAR(campo_date,LOC)) Aparte de las conversiones explicitas necesarias se habr de aplicar algn tipo de conversin cuando se trate de operar con algn valor numrico que represente una fecha ya que el mismo nmero no proporcionar la misma fecha en Informix-SQL y Db2. La forma de llevar a cabo esta transformacin se explicar en el punto: Tratamiento de las fechas.

EXPRESIONES SQL

Una expresin es una combinacin de uno o mas valores, operadores, y/o funciones SQL que como resultado de su evaluacin se obtiene un valor. Es importante hacer mencin especial a la definicin que Informix-SQL hace de las expresiones SQL ya que, al igual que el resto de la Sintaxis de Informix-SQL, se ha de procurar que sea portable a cualquier otro de los gestores de bases de datos en estudio. Informix-SQL subdivide las expresiones SQL en: Expresiones de manejo de columnas. Expresiones de constantes. Funciones SQL. Expresiones agregadas. Y Nombres de variables.

184 Las expresiones SQL de Informix-SQL se utilizan: a la hora de seleccionar un elemento de una tabla en la sentencia SELECT, en la parte SET de la sentencia UPDATE, en la sentencia CHECK, en la parte HAVING de la sentencia SELECT y en clusula WHERE de las sentencias SELECT, UPDATE y DELETE. Como partimos de programas sintcticamente correctos no es el objetivo de esta seccin el evaluar o garantizar que se utiliza adecuadamente una expresin SQL dentro de la definicin de una sentencia sino que lo que se pretende es tener claros los elementos que definen una expresin SQL para as poder evaluar la compatibilidad y potabilidad del cdigo fuente al resto de gestores de bases de datos. La definicin sintctica es la siguiente: <expresin> ::= [ + | - ] <tipos_de_expresion> <mas_tipos_de_expresion> <mas_tipos_de_expresion> ::= [ [ + | - | * | / ] <tipos_de_expresion> <mas_tipos_de_expresion> ] | vacio <tipos_de_expresion> ::= [ <expresion_columna> | <expresion_cte> | <expresion_funcion> | <expresion_agregada> | <variable> | ( <expresin> ) ]

EXPRESIONES DE MANEJO DE COLUMNAS


Simplemente definen la forma de acceder a una columna de una tabla, la sintaxis admitida por Informix-SQL es: <expresion_columna> ::= [ { <nombretabla> | <aliastabla> | <nombresinonimo> | <nombrevista> } . ] <nombrecolumna> [ [ n , m ] ] | ROWID <nombretabla> | <aliastabla> | <nombresinonimo> | <nombrevista> ::= [ propietario . ] identificador Esta sintaxis es bsicamente admitida por el resto de gestores de bases de datos. En Oracle si se especifica el propietario en la parte de la clusula SELECT en la cual se seleccionan los campos tambin debe especificarse en el clusula WHERE. Ejemplo: Sentencia Informix: select usuario.tabla.campo1 from tabla1 Sentencia generada para Oracle: select usuario.tabla.campo1 from usuario.tabla1 Sentencia generada para el resto: select usuario.tabla.campo1 from tabla1 Esta peculiaridad de Oracle es considerada a la hora de traducir el cdigo fuente a objeto. Al indicar el nombre de columna Informix-SQL permite limitar el nmero de caracteres del campo que se retornan utilizando para ello la sintaxis opcional: [ n, m ] donde n y m son literales numricos que representan: n indica la posicin del carcter inicial y m la del final. El resto de gestores no soportan esta sintaxis, al menos con este mismo significado, pero todos ellos definen alguna funcin que permite obtener una subcadena de un campo, estas son: Para SqlServer la funcin: SUBSTRING ( nombrecolumna, n, m ), donde n es el carcter inicial y m la longitud del substring. Para Oracle la funcin: SUBSTR ( nombrecolumna, n, m ), donde n es el carcter inicial y m la longitud del substring. Y para DB2 la funcin: SUBSTR ( nombrecolumna, n, m ), donde n es el carcter inicial y m la longitud del substring.

En Informix-SQL y tambin en el resto de gestores las cadenas de caracteres van desde 1 hasta la longitud de la misma. Teniendo en cuenta que n y m son literales y que sabemos la forma de simular el mismo comportamiento en el resto de gestores no habr ningn problema en traducir esta sintaxis al gestor de base de datos destino. Los valores de n y m se calculan:

185 n: es igual a n para cualquier gestor. m: para el resto de gestores se calcula aplicando la formula: m-n+1 Cdigo fuente Informix-SQL: select campo1[2,4] from tabla

Ejemplos: Cdigo objeto Oracle: select substr(campo1,2, (4-2+1) ) from tabla Cdigo objeto SqlServer: select substring(campo1,2,3) from tabla Cdigo objeto DB2: select substr(campo1,2,3) from tabla Donde m se calculo aplicando la formula indicada: m-n+1 sea: 4-2+1 Dentro del Anexo I, en la seccin: Ejemplo de manejo de columnas y constantes predefinidas, se pueden ver ejemplos prcticos del uso de nombres de campos y substrings. Otro elemento que aparece en la definicin del manejo de columnas es el ROWID. El rowid es un nmero nico y secuencial que Informix asigna a cada uno de los registros (filas) insertados en una tabla. Se podra decir que es un "ndice nico interno de Informix". Este nmero es nico para una fila dentro de una tabla, lo cual no implica que otra fila de otra tabla pueda tener el mismo. Ejemplo: SELECT MAX(rowid) FROM tabla El concepto de ROWID no es soportado por todos los gestores. Oracle e Informix lo implementan, aunque Informix lo interpreta como un valor entero y Oracle como uno tipo cadena de longitud de 18 caracteres, esto de por si ya es un problema a la hora de traducir cdigo fuente a objeto, veamos los siguientes ejemplos: Ejemplo1: delete from tabla where rowid == (select max(rowid) from tabla ) Ejemplo2: select max(rowid) into vble1 from tabla; delete from tabla where rowid = vble1 El primer ejemplo es valido tanto para Oracle como para Informix-SQL, pero el segundo se apoya en una variable intermedia definida en el cdigo fuente de Informix, de tipo integer, con lo cual este cdigo al ser ejecutado sobre el gestor de base de datos Oracle dar un error. Haciendo un anlisis mas profundo quiz pudiese solventarse este problema basndonos en la posibilidad que da Java de definir variables de forma bastante libre. Ejemplo de consulta del ROWID sobre Informix: select rowid,* from tabla; rowid
257 258 259 260 261 262 263 264 25/07/2006 25/07/2006 25/07/2006 25/07/2006 25/07/2006 25/07/2006 31/12/1900 25/07/2006

campo1

Ejemplo de consulta del ROWID sobre Oracle: SQL> select rowid, tabla.* from tabla ROWID
-----------------AAADJiAABAAADhNAAA AAADJiAABAAADhNAAB AAADJiAABAAADhNAAC AAADJiAABAAADhNAAD AAADJiAABAAADhNAAE AAADJiAABAAADhNAAF AAADJiAABAAADhNAAG

UNO
1 2 3 4 5 6 7

DOS
1 1 1 1 1 1 1

------ ---------

186 Por otra lado Db2 y SqlServer no soportan el concepto de ROWID, ambos gestores entienden que los programadores que deseen trabajar con el nmero nico de fila deben definirlo explcitamente en la declaracin de la tabla, aadiendo para ello un campo adicional. Lo que si proporcionan son los elementos para que el programador pueda implementar esta funcionalidad. Para el caso de SqlServer se definen el tipo de dato UNIQUEIDENTIFIER, la opcin ROWGUIDCOL, y la funcin NEWID() que proporciona el identificador nico. La opcin ROWGUIDCOL permite luego que en la sentencia SELECT se pueda retornar el ROWID sin especificar ningn campo de la tabla, vase el siguiente ejemplo: create table tabla1 ( campo1 uniqueidentifier ROWGUIDCOL, campo2 smallint ); insert into tabla1 values (newid(),1); select ROWGUIDCOL,* from tabla1 Resultados: campo1
F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA A8908CB3-7230-43C4-BE39-0E0194D3380E 38679D43-0EF3-40BD-A132-D651BF98F909 B7334E8B-5D61-429B-B339-F7E2A22440C1 095BA7DA-5A43-4B00-8BA5-F513221E1624 CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 4DDA3709-380E-4B90-BBB1-1648414E9A5A F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA A8908CB3-7230-43C4-BE39-0E0194D3380E 38679D43-0EF3-40BD-A132-D651BF98F909 B7334E8B-5D61-429B-B339-F7E2A22440C1 095BA7DA-5A43-4B00-8BA5-F513221E1624 CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 4DDA3709-380E-4B90-BBB1-1648414E9A5A

campo1

campo2
1 1 1 1 1 1 1

El ROWGUIDCOL es un nmero nico de forma global: este nmero no lo contendr ninguna otra fila de ninguna otra tabla de ninguna base de datos. Aunque este concepto es mucho ms global que el definido en Informix-SQL tiene el mismo significado que el ROWID. Para traducir el concepto ROWID de Informix-SQL a SqlServer se nos plantean dos problemas difciles de solventar: El primero, al igual que Oracle, el tipo de dato que retorna que es una cadena de 32 caracteres. Y el segundo y ms insalvable nos obliga a cambiar la estructura de las tablas originales aadindoles un campo nuevo el cual hay que tratar en el resto del cdigo (insert, delete, etc.) create table tabla1 ( campo1 uniqueidentifier ROWGUIDCOL default newid(), campo2 smallint ); De esta forma no es preciso insertar los valores directamente aunque cambia la sintaxis de la sentencia insert: insert into tabla1 (campo2) values (1); select ROWGUIDCOL,* from tabla1 Resultados: campo1
F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA A8908CB3-7230-43C4-BE39-0E0194D3380E A8908CB3-7230-43C4-BE39-0E0194D3380E 38679D43-0EF3-40BD-A132-D651BF98F909 38679D43-0EF3-40BD-A132-D651BF98F909

Otra forma que se puede plantear es mediante la siguiente definicin:

campo1

campo2
1 1 1

187
B7334E8B-5D61-429B-B339-F7E2A22440C1 095BA7DA-5A43-4B00-8BA5-F513221E1624 CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 4DDA3709-380E-4B90-BBB1-1648414E9A5A B7334E8B-5D61-429B-B339-F7E2A22440C1 095BA7DA-5A43-4B00-8BA5-F513221E1624 CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 4DDA3709-380E-4B90-BBB1-1648414E9A5A 1 1 1 1

SQLSERVER sugiere otras formas de devolver un valor nico para cada fila de la tabla que aunque no cumple el concepto de ROWGUIDCOL si cumplira la definicin que Informix-SQL hace del ROWID. Estas soluciones se basan en aadir cdigo en los programas basado en las funciones propias de SQLSERVER: rank(), count(), y row_number()4. En el caso de que el gestor de base de datos destino sea DB2 la implementacin del ROWID es muy similar a la de SqlServer con la diferencia que el campo de tipo ROWID, segn se defina, permite que el valor se genere de forma automtica y por otro lado no admite la consulta del mismo utilizando una palabra reservada, vase el siguiente ejemplo: Create table tabla1 ( camporowid ROWID NOT NULL GENERATED ALWAYS, campo2 smallint ); db2 => select * from tabla1 camporowid
!AYCQs !B y3 !B H4 !B &8 !B V !B 5C$

campo2
1 1 1 1 1 1

------ --------------------

Esta definicin guarda el identificador nico en una variable de 17 bytes. La opcin GENERATED ALWAYS indica que no se deben insertar los valores de forma explicita sino que el gestor se encarga de ello. Esta definicin permite generar el concepto de rowid como lo entiende Informix-SQL: un nico valor por cada columna de la tabla lo cual permite identificarlas de forma univoca. Los valores que almacena una variable de tipo ROWID son de tipo caracteres de longitud variable a diferencia de Informix que son valores numricos. Una forma de definir un campo numrico que simule el comportamiento del ROWID es la siguiente: Create table tabla1 ( camporowid integer NOT NULL GENERATED ALWAYS AS IDENTITY, campo2 smallint ); El atributo AS IDENTITY junto con GENERATED ALWAYS genera automticamente valores numricos incrementales (o decrementales) cuando una nueva columna es insertada en la tabla. db2 => select * from tabla1

Ejemplos en los enlaces: http://www.databasejournal.com/features/mssql/article.php/3572301 y http://support.microsoft.com/default.aspx?scid=KB;EN-US;q186133


4

188 camporowid
1 2 3 4 5 6

campo2
1 1 1 1 1 1

------ --------------------

Un problema adicional de DB2 es que no proporciona ningn mtodo para recuperar el valor de tipo rowid, la nica forma de recuperarlo es accediendo al nombre del campo, no permite usar palabras reservadas tales como: ROWID o ROWGUIDCOL. Otro problema que se plantea es que Db2 obliga a cambiar las sentencias insert indicando en todo caso los campos sobre los que trabajan, las siguientes instrucciones provoca un error: db2 => insert into tabla1 values(1,1) db2 => insert into tabla1 values(1) La forma de realizar la insercin sera: db2 => insert into tabla1 (campo2) values(1) Segn el estudio realizado el ser capaces de pasar el concepto del rowid al resto de gestores podra forzar a redefinir el cdigo fuente e incluso plantear el cambiar estructuras de alguna tabla lo cual excede el estudio aqu planteado. An as se proporcionan mltiples ideas que pueden ser tiles a al hora de tratar el rowid y que en futuras versiones incluso se plantear el tenerlas en cuenta a la hora de generar cdigo objeto para cada diferente gestor. Si en el cdigo fuente aparece esa palabra reservada se notificar por pantalla, en el momento de la traduccin, para que se proceda a revisar el cdigo objeto generado.

EXPRESIONES DE CONSTANTES
Informix-SQL Admite como expresiones constantes las siguientes: Cadenas entre comillas (simples y dobles), literales numricos, literales de definicin de fechas y de definicin de intervalos. Constantes USER, TODAY y CURRENT.

La definicin de constantes esta ntimamente relacionado con los tipos de datos soportados por el gestor de bases de datos. Destacar que Informix-SQL permite definir constates tipo cadena entre comilla doble y entre comilla simple y como el resto de gestores trabajan con la comilla simple (ver estudio realizado en el apartado: Configuracin local ) en la traduccin de cdigo se usar siempre comilla simple. A continuacin se muestra la definicin sintctica: <cadena_caractares> ::= [ caracter | ] | [ caracter | ] La definicin sintctica de la constante numrica se muestra a continuacin: <nmero> ::= [ + | - ] { digito [..n] [.] [digito] | [.] digito[..n] } [ E [-] digito[..n] ] Esta definicin es soportada por todos los gestores de bases de datos. En Informix-SQL para definir una constante tipo DATE se puede hacer de varias formas: con un nmero entero que indica el nmero de das desde el 31/12/1899 o bien con una cadena de caracteres en el formato mm/dd/yyyy (segn configuracin local). Las constantes tipo DATE en formato cadena de caracteres se pueden pasar directamente al gestor de bases de datos, siempre y cuando la configuracin local sea igual en todos los gestores (ver apartado: Configuracin local), con el nico cambio de sustituir la comilla doble por comilla simple. Aunque todos los gestores reconocen la constante fecha en formato cadena se pueden producir errores al realizar operaciones con esta, como en el caso de sumar una constate numrica a una fecha o restar dos fechas o pasrselo como parmetro a funciones que esperan recibir un tipo dato

189 DATE, por lo que para evitar problemas en la ejecucin y/o hacer que el cdigo sea ms correcto, aunque en casos algo menos legible, se pasar la constante de caracteres a un tipo de dato: DATE utilizando para ello las funciones propias de cada gestor de bases de datos. La siguiente sentencia ejecutada sobre el gestor de bases de datos Oracle producira un error, ya que ste entiende que se est intentado hacer una operacin aritmtica sobre una cadena y un entero, mientras que Informix lo admite sin problemas: select 31/12/2007 + 1 from tabla Cuando aparezca, en el cdigo fuente, una constante cadena con formato fecha se aplicar, en funcin del gestor destino, la siguiente traduccin: Oracle: to_date(fecha_cad,'formato_fecha'), caso prctico: to_date(31/12/2007,dd/mm/yyyy); Sqlserver: convert(datetime,fecha_cad,formato_fecha), caso prctico: convert(datetime,31/12/2007,103); Db2: date(fecha_cad), caso prctico: date(31/12/2007); A la hora de hacer la traduccin de cdigo el formato_fecha se generar en funcin de la configuracin local establecida en el fichero de configuracin de la conexin ver: Este fichero se llama: conexion.cfg, y Al igual que ocurre con las constantes tipo DATE en formato cadena las constantes tipo DATE en formato numrico, aunque en la mayora de los casos son soportadas por el gestor destino, es recomendable utilizar las funciones propias de cada gestor para pasarlas a tipo fecha, estas son: Oracle: to_date( to_char (fecha_num,'formato_fecha'), formato ), caso prctico: to_date( to_char( 1,99999999999),J); Sqlserver: convert(datetime, fecha_num,formato_fecha), caso prctico: convert(datetime, 1 ,103); Db2: date(fecha_num), caso prctico: date(1); Como se coment en el punto en el que se estudiaban las conversiones implcitas soportadas por cada gestor un mismo valor numrico no ser interpretado como la misma fecha en todos los gestores. La forma de llevar a cabo, en la prctica, esta transformacin de nmero a fecha se estudia en el punto: Tratamiento de las fechas. Para definir una constante de tipo DATETIME Informix-SQL tiene una sintaxis mucho ms especfica, la cual se muestra a continuacin: <literal_datetime> ::= DATETIME ( <numeric_datetime> ) <datetime_calificador> <numeric_datetime> ::= yyyy-mm-dd hh:mm:ss.ffffff <datetime_calificador> ::= { year | month | day | hour | minute | second | fraction } to { year | month | day | hour | minute | second | fraction [ (3) | ( nmero ) ] } Tambin admite directamente el formato de cadena con un DATETIME embebido: 'yyyy-mm-dd hh:mm:ss.ffffff'. Las constantes tipo fecha/hora en el formato propio de Informix-SQL no es soportado por ningn otro gestor de bases de datos con lo que ser preciso realizar un procesamiento de este tipo de constantes para pasarlas a un formato que entienda el gestor de bases de datos destino. Por otro lado las constantes tipo fecha/hora en formato cadena si son soportadas por el resto de gestores

190 sin apenas limitaciones, a continuacin se muestran las conversiones a realizar para cada uno de los gestores de bases de datos estudiados: Para el gestor de bases de datos Oracle ha de recibir las constantes tipo fecha/hora como una cadena de caracteres y justo antes de ella la palabra reservada timestamp. As los dos casos que se pueden dar en Informix-SQL se deben convertir a este formato: timestamp yyyy-mm-dd hh:mm:ss.fff Ejemplos: 2006-08-25 22:10:12.453 timestamp 2006-08-25 22:10:12.453 timestamp 2006-08-25 22:10:12.453 SQLSERVER solo reconoce como validos los datos fecha/hora incluidos entre comilla simple con los siguientes formatos: Formatos alfabticos de fecha (por ejemplo, '15 de abril de 1998') Formatos numricos de fecha (por ejemplo, '15/4/1998', '15 de abril de 1998') Formatos de cadenas sin separar (por ejemplo, '19981207', '12 de Diciembre de 1998') datetime (2006-08-25 22:10:12.453) year to fraction

Dadas que estas son las nicas posibilidades de definir constantes tipo fecha la forma de solventar el problema consiste en utilizar la funcin CONVERT, para ello se ha de extraer del cdigo fuente la constate tipo cadena con una fecha/hora embebida o el literal datetime y generar cdigo objeto siguiendo la siguiente sintaxis: convert(datetime,cadena,formato_fecha_hora) Ejemplos: 2006-08-25 22:10:12.453 convert(datetime,2006-08-25 22:10:12.453,121) convert(datetime,2006-08-25 22:10:12.453,121) Donde 121 es el cdigo que utiliza SqlServer para indicar formato fecha/hora. Db2. No plantea ningn problema al admiten sin restricciones las definiciones de constantes y literal fecha/hora que hace Informix-SQL. datetime ( 2006-08-25 22:10:12.453 ) year to fraction

Tanto el reconocimiento de los tipos de dato fecha como fecha/hora que estn introducidos como constantes de tipo cadena se realiza dentro del analizador lxico punto el cual seremos capaces de discernir si se trata de un token tipo fecha, fecha/hora o por el contrario cadena, ver: Reconocimiento de las fechas. La identificacin y utilizacin de las constantes tipo fecha y fecha-hora dentro de expresiones SQL se estudiarn con detalle con posterioridad en el apartado: Tratamiento de las fechas. Para ver ejemplos del comportamiento del traductor en el tratamiento de literales, constates y variables dirigirse a: Ejemplo de manejo de literales, constantes y variables dentro del Anexo I. La funcin TODAY retorna la fecha del sistema como un tipo de datos DATE. Esta funcin como tal no existe en el resto de gestores, pero existen otras similares que teniendo en cuenta la Tabla 29: Mapeo entre tipos de datos Informix-SQL y el resto de gestores, son correctas para ser utilizadas en el gestor de bases de datos destino: En SqlServer la funcin GETDATE(), retorna la fecha actual en formato fecha y hora. En Oracle la constante SYSDATE que retorna la fecha y hora actual. No recibe parmetros. En DB2 la constante CURRENTE DATE retorna la fecha actual del sistema.

191 Tener en cuenta que GETDATE() y SYSDATE retornan un valor DATETIME y las variables sobre el cual se almacena, en la base de datos, guardan la parte de hora. Esto puede afectar al resultado de las operaciones realizadas con los valores devueltos por estas funciones proporcionando datos diferentes a los que se produciran si se ejecutase sobre el gestor de bases de datos original. A la hora de traducir esta constante para Sqlserver y Oracle se utilizarn, respectivamente, las expresiones: En SqlServer: DATEPART(dd,0, DATEDIFF(dd,0,GETDATE())) Para Oracle: TO_DATE(TO_CHAR(SYSDATE,'dd/mm/yyyy')) En los casos prcticos relativos a operaciones aritmticas sobre fechas, punto: Error! No se encuentra el origen de la referencia., se detalla el problema y solucin con ejemplos. La constante CURRENT de Informix-SQL es similar a TODAY, pero en este caso retorna un tipo de dato DATETIME que contiene la fecha y hora mostrando el momento en el tiempo actual. Segn su definicin las funciones equivalentes en el resto de gestores son: En SqlServer la funcin GETDATE(), retorna la fecha actual en formato fecha y hora. En Oracle la constante SYSDATE que retorna la fecha y hora actual. En Db2 la constante CURRENTE TIMESTAMP retorna la fecha y hora actual del sistema. USER es una funcin, sin parmetros, que retorna un cadena de caracteres que contiene el login del usuario actual (esto es, la persona que esta ejecutando el proceso). SqlServer define la constante USER como el usuario actual de base de datos lo cual viene a ser lo mismo que Informix ya que este no trabaja con usuarios de base de datos sino con usuarios del sistema. Oracle tambin define esta constante como el usuario que ha iniciado la sesin actual. Y Db2 tambin define esta constante con similar significado, con lo que se podr usar esta funcin sin ningn problema contra cualquier gestor de bases de datos. Los ejemplos del comportamiento del traductor con las constantes: TODAY, CURRENT y USER se muestra en punto: Ejemplo de manejo de columnas y constantes predefinidas dentro del Anexo I.

FUNCIONES SQL
El gestor de bases de datos Informix define una serie de funciones que pueden ser utilizadas dentro de una expresin SQL y por tanto procesadas por el mismo. Estas funciones son: DAY, MONTH, WEEKDAY, YEAR, DATE, EXTEND, MDY, LENGHT, HEX, TRUNC Y ROUND. A continuacin se estudia cada una de ellas y la compatibilidad con el resto de gestores de bases de datos. DAY ( [ date_expr | datetime_expr ] ) Esta funcin retorna un nmero entero que representa el da del mes del valor tipo DATE o DATETIME que recibe como parmetro. Esta funcin es soportada por SqlServer y Db2 con idntica sintaxis y semntica que InformixSQL. Oracle no la define aunque si se puede obtener el mismo resultado utilizado la funcin TO_CHAR, como se muestra en el siguiente ejemplo: TO_CHAR(campo_tipo_fecha,'DD') TO_CHAR(sysdate,'DD') MONTH ( [ date expr | datetime expr ] ) Esta funcin retorna un nmero entero de 1 a 12 que representa el mes del valor tipo DATE o DATETIME que recibe como parmetro. Esta funcin es soportada por SqlServer y Db2 con la misma sintaxis y semntica que Informix-SQL. Para obtener el da del mes en oracle se puede utilizar la funcin TO_CHAR como se muestra en a continuacin: TO_CHAR(campo_tipo_fecha,'MM') WEEKDAY ( [ date expr | datetime expr ] ) Esta funcin retorna un entero que representa el da de la semana. Para Informix-SQL: cero representa domingo, 1 lunes y as sucesivamente. Para obtener el da de la semana en el resto de gestores de bases de datos se ha de utilizar:

192 En SqlServer no existe una funcin exclusiva que nos de el da de la semana. Se debe de usar la funcin DATEPART(gw, campo_date). Esta funcin retorna domingo = 1 y sbado = 7. La operacin a realizar durante el proceso de traduccin de cdigo fuente a objeto ser: WEEKDAY (today) DATEPART(dw, getdate()) En Oracle la forma de obtener el da de la semana se ha de aplicar la siguiente consulta: TO_CHAR(sysdate,'D') la cual retorna un nmero del 1 al 7 tomando el 1 como lunes y el 7 como domingo. Al igual que con SqlServer la traduccin a realizar del cdigo fuente ser: WEEKDAY (today) TO_CHAR(sysdate,D) En Db2 existe la funcin DAYOFWEEK ( campo_date ) que retorna un nmero del 1 al 7 donde 1 representa domingo. Al igual que para el resto de gestores la forma de traducir la expresin de Informix-SQL ser: WEEKDAY (today) DAYOFWEEK (current date) La representacin del da de la semana como nmero al igual que el formato de fecha y otros parmetros depender de como este configurado el gestor de bases de datos: idioma, fecha, etc. A la hora de realizar la traduccin de estas funciones al gestor de bases de datos destino habr que tener en cuenta como interpreta este el da de la semana y hacer la correccin, si es necesaria, para que el comportamiento sea igual al que se dise en el cdigo fuente para el gestor de bases de datos Informix. Ver el apartado: Configuracin local para ms detalles. YEAR ( [ date expr | datetime expr ] ) Retorna 4 dgitos que representan el nmero de ao del valor DATE o DATETIME que recibe como parmetro. Esta funcin es soportada por SqlServer y Db2 con la misma sintaxis y semntica que Informix-SQL. Para obtener el ao en Oracle hay que utilizar la funcin TO_CHAR como se muestra a continuacin: TO_CHAR(campo_tipo_fecha,'YYYY') TO_CHAR(sysdate,'YYYY') DATE ( nondate_expr ) Esta funcin retorna un valor tipo DATE correspondiente a la expresin de tipo no DATE que recibe como parmetro. El tipo de parmetro que suele recibir son CHAR, INTENTER o DATETIME. Cuando recibe un parmetro tipo CHAR la funcin DATE lo evala teniendo en cuenta la variable de entorno DBDATE. Si se recibe un tipo de dato INTEGER entiende que es el nmero de das que van desde el 31/12/1899. Y si recibe un valor de tipo DATETIME retorna la parte fecha del mismo. Para que el resultado de la misma sea igual que el que producira si se ejecutase sobre el gestor de bases de datos Informix es importante saber el formato de fechas que admite esta funcin el cual depender del formato de fechas que tenga el gestor destino. La traduccin de esta funcin para el resto de gestores de bases de datos ha de considerar los tres tipos de datos que puede recibir como parmetro. A continuacin se indica se tratara la funcin DATE por cada gestor: Db2. Define la funcin DATE como Informix y admite como parmetros: entero, timestamp, cadena de 7 caracteres o representando una fecha valida. Si el valor es un timestamp retorna la parte fecha. Si es una fecha en formato caracter la interpreta. El parmetro de entrada cadena de 7 caracteres no se producir. Y si recibe un nmero la fecha se obtiene sumando n-1 das al 1 de enero de 0001. Ej.: DATE(expr_date_time) DATE(expr_caracter) DATE(expr_nmero) En Oracle se utiliza la funcin: TO_DATE en combinacin, en algn caso, con otras como: TO_NUMBER o TO_CHAR. Vanse los siguientes los casos posibles: TO_DATE(TO_CHAR(expr_date_time, 'DD/MM/YYYY HH24:MI:SS'),DD/MM/YYYY) TO_DATE(TO_CHAR(expr_numerica,999999999999), J) TO_DATE(expr_caracter, 'DD/MM/YYYY)

193 El gestor de base de datos SqlServer no define la funcin DATE pero si una que permite obtener el mismo resultado. La funcin a utilizar es CONVERT. A continuacin se muestras los casos que se pueden plantear: CONVERT(datetime, expr_date_time, formato) Esta no tiene sentido ya que Sqlserver no tiene un tipo de datos DATE y otro DATETIME sino que solo utiliza el tipo de datos DATETIME. CONVERT(datetime, expr_caracter) CONVERT(datetime, expr_numerica, formato) El nico caso que plantea problemas aqu es el parmetro numrico de entrada ya que el mismo nmero proporcionar una fecha diferente en funcin de sobre que gestor de bases de datos se lance la funcin. La solucin a este problema se muestra en el apartado: Tratamiento de las fechas. EXTEND ( [ date_expr | datetime_expr ] [, Datetime qualifier ] ) Esta funcin ajusta la precisin de un valor del tipo de dato DATE o DATETIME. Si no se indica la precisin se entiende que va desde ao hasta fraccin de segundo con 3 dgitos de precisin. La expresin no puede ser una constante tipo cadena. Si se pretende ajustar el nuevo tipo de datos a uno con mayor precisin de la que tiene la expresin original los campos de mes y da toman, por defecto, el valor de 1 y los de hora, minutos, segundos, y fraccin de 0. En el fondo esta funcin lo que realiza es un cambio de formato de del tipo de dato fecha/hora que recibe como parmetro. Para poder traducirla al resto gestores habr que convertir el segundo parmetro al formato que reconoce cada gestor, que suele ser: dd-MM-yyyy hh:mm:ss.fff, y tener en cuenta tambin el formato de fecha que este establecido en la configuracin del cliente y su posible. Uno cualificador valido par Informix tiene la sintaxis: <DATETIME_QUALIFIER> ::= { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | FRACTION } TO { YEAR | MONTH | DAY | HOUR | MINUTE | SECOND | FRACTION [ ( n ) ]} Las funciones a utilizar son: Para Oracle: TO_DATE(TO_CHAR(expr_date_time, 'DD/MM/YYYY HH24:MI:SS.FFFFFF'), formato) Como la funcin TO_DATE recibe como primer parmetro una cadena de caracteres que representa un tipo de datos fecha/hora y la funcin original de informix recibe un tipo de dato fecha/hora se convertir este a cadena con el patrn: 'DD/MM/YYYY HH24:MI:SS.FFFFFF' con el objeto de no perder precisin. El segundo parmetro de esta funcin se construir en tiempo de ejecucin adaptando el formato de Informix-SQL a uno que admita Oracle, para ello se utilizar la tabla de elementos de formato Datetime definida por Oracle en su manual de referencia SQL y la configuracin local (ver punto: Configuracin local). En lugar de la funcin TO_DATE se puede utilizar la funcin TO_DATETIME que recibe como primer parmetro una valor fecha/hora en formato cadena y como segundo una cadena indicando el formato y retorna un valor tipo fecha/hora. Ej.: TO_TIMESTAMP ('1999-12-01 11:00:00', 'YYYY-MM-DD HH:MI:SS') Para SqlServer: CONVERT(datetime, expr_date_time, formato) El formato se de elegir, al igual que para Oracle, teniendo en cuenta la configuracin local y la tabla de formatos definida por SqlServer en los: Libros de pantalla de Microsoft SqlServer asociados a la funcin CONVERT. Para DB2. TIMESTAMP_FORMAT ( expr_cadena, formato )

194 Al igual que con Oracle esta funcin recibe el primer parmetro en formato cadena con lo cual habr que convertir el valor que nos llegue a una cadena que represente una fecha/hora segn la definicin de la configuracin local y sin perder precisin. Ej.: TIMESTAMP_FORMAT(CHAR(expr_cadena, LOC), 'YYYY-MM-DD HH24:MI:SS') El nico formato que admite esta funcin es el indicado en el ejemplo. Una funcin mas recomendable a utilizar es: TIMESTAMP ( expr_fecha/hora, formato ), la expresin fecha/hora puede venir en formato cadena o fecha/hora y el formato: yyyymm-dd hh:mm:ss.ffffff MDY (mes, da, ao ) Retorna un valor tipo DATE obtenido como resultado de evaluar las tres expresiones de tipo entero que recibe como parmetro. La primera representa el mes de 1 a 12, la segunda el da del mes de 1 a 31 y la tercera el ao como un nmero de 4 dgitos. Esta funcin no esta definida por el resto de gestores de bases de datos, pero si se puede obtener el mismo resultado utilizando para ello la combinacin de varias funciones, a continuacin se muestra el cdigo a generar para cada gestor: SqlServer: CONVERT (datetime, CONVERT (char(10), dd/mm/yyyy), 103) donde la cadena dd/mm/yyyy se debe construir en el momento de la ejecucin, el valor 103 corresponde a la representacin de fecha local segn la tabla de formato de fechas proporcionada por SqlServer. Oracle: TO_DATE (dd/mm/yyyy) donde la cadena debe construirse en tiempo de ejecucin. El formato de la cadena depender de la configuracin local. Db2, usado la funcin: DATE (dd/mm/yyyy) donde la cadena se ha de construir en tiempo de ejecucin y el formato de la misma depender de la configuracin local. En el Anexo I, apartado: Ejemplo funciones de manejo de fechas, se muestran ejemplos prcticos del tratamiento de funciones sobre fechas por parte del traductor. El ejemplo: Ejemplo de funcion weekday profundiza en la funcin weekday. LENGTH ( quoted string | variable | tabla.columna ) Esta funcin retorna el nmero de caracteres de la cadena que recibe como parmetro si tener en cuenta los espacios en blancos al final de la misma. Db2 y Oracle definen esta funcin con igual sintaxis pero semntica diferente, ya que para ambos gestores si tiene en cuenta los espacios al final de la misma. Para que el funcionamiento sea el mismo se aadir la funcin RTRIM antes de aplicar la funcin LENGH, como se muestra a continuacin: LENGTH (RTRIM( expr_cadena ) ) En el caso de SqlServer la sintaxis es diferente pero la semntica igual, la funcin a utilizar es: LEN ( cadena). HEX ( int_expr ) Retorna el valor hexadecimal del entero que recibe como parmetro. Para obtener el mismo resultado en el resto de gestores de ha de hacer: Para Oracle: TO_CHAR (expr_ entera ,'XXXXXXXX') Db2 define la misma funcin HEX con igual sintaxis y semntica. SqlServer no define la funcin HEX ni ninguna otra que realice esta operacin. La solucin que se adopta en este caso es definir una funcin en el gestor de bases de datos que realice dicha conversin. Esta funcin es:
drop function inttohex go Create function IntToHex(@Dec as bigint) --@Hex As varchar(8) Output) returns varchar(16) as begin Declare @HexDigits as char(16) declare @Hex as varchar(16) Set @HexDigits = '0123456789ABCDEF'

195
Set @Hex = '' While @Dec >= 16 Begin Set @Hex = SubString(@HexDigits, (@Dec % 16) + 1, 1) + @Hex Set @Dec = @Dec / 16 End Set @Hex = SubString(@HexDigits, @Dec + 1, 1) + @Hex end go return @hex

Antes de ejecutar ningn programa que utilice la funcin HEX se debe de ejecutar este cdigo sobre el gestor de bases de datos, para ello se abre un "SQL Query Analyzer" sobre la base de datos se copia dicho cdigo en el mismo y se lanza. ROUND (expr_sql [, nmero | 0] ) Este funcin proporciona como resultado el valor redondeado de la expresin que recibe como parmetro. Si se omite el nmero de dgitos decimales se redondea a 0 dgitos. El nmero puede ser un valor que va desde 32 hasta +32. El resto de gestores definen esta funcin en algunos casos con alguna particularidad, pero siempre admitiendo la semntica de Informix-SQL. Oracle no contempla ninguna particularidad, Db2 y SqlServer si lo hacen, el primero no pone como opcional el nmero de dgitos a redondear y el segundo admite, de forma opcional un tercer parmetro que indica el modo de comportamiento de la funcin (0 o en blanco: redondea, 1 trunca). La sintaxis final a la que se traducir esta sentencia en el cdigo objeto ser: ROUND (expr_sql , nmero ), donde nmero ser 0 si en la definicin original se omita dicho parmetro. TRUNC ( expr_sql [, nmero | 0] ) Devuelve el valor truncado de la expresin numrica que recibe como parmetro. Si se omite el nmero de dgitos decimales a dejar por defecto se entiende que es 0. El nmero puede ser un valor que va desde 32 hasta +32. En este caso no todos los gestores de bases de datos aqu estudiados contemplan esta funcin, como es el caso de SqlServer, pero esto no ser problema ya que la funcin ROUND de SqlServer admite un tercer parmetro que si se pone a 1 har que se comporte como la funcin TRUNC. Para el resto de gestores pasa igual que con ROUND, Oracle la admite sin ninguna diferencia y Db2 la admite obligando a poner el segundo parmetro. El cdigo generado, en funcin del gestor de base de datos destino, ser: Informix, Oracle, y Db2: TRUNC ( expr_sql , nmero ), nmero ser 0 en el caso de que en el cdigo fuente este valor se omita. SqlServer: ROUND (expr_sql , nmero , 1) donde nmero ser 0 si en la sentencia original no haba dicho parmetro.

En el apartado: Ejemplo de funciones matemticas dentro del Anexo I se plasman casos prcticos del uso de las funciones matemticas.

EXPRESIONES AGREGADAS
Las funciones agregadas permiten obtener informacin resumida de los datos de una tabla. Cuando se realiza una consulta a una tabla utilizando una funcin agregada el resultado ser una simple fila conteniendo el dato solicitado. Las funciones agregadas definidas por Informix-SQL son: COUNT, MAX, MIN, AVG, y SUM. A continuacin se define el significado y sintaxis de las mismas y como se traducirn a cdigo objeto, en caso de ser necesario, para ser ejecutadas sobre cualquier gestor de bases de datos de los aqu estudiados. COUNT ( * | [ DISTINCT | UNIQUE ] [ nombretabla . ] nombrecolumna ) Retorna la cuenta del nmero de filas que satisfacen la condicin WHERE de una sentencia SELECT. Si se incluye el nombre de una columna entonces esta funcin retorna el nmero total de valores no nulos para dicho campo. Si adems se aade UNIQUE o DISTINCT retorna el nmero de valores nicos (no repetidos) no nulos para dicha columna. UNIQUE y DISTINCT son sinnimos.

196 AVG ( [ ALL] expr_sql | [ DISTINCT | UNIQUE ] [ nombretabla . ] nombrecolumna ) Esta funcin retorna la media de todos los valorares de las seleccionadas en la columna o expresin. MAX ( [ ALL] expr_sql | [ DISTINCT | UNIQUE ] [ nombretabla . ] nombrecolumna ) Retorna el valor mximo de la columna especificada o expresin. MIN ( [ ALL] expr_sql | [ DISTINCT | UNIQUE ] [ nombretabla . ] nombrecolumna ) Retorna el valor mnimo de la columna especificada o expresin. SUM ( [ ALL] expr_sql | [ DISTINCT | UNIQUE ] [ nombretabla . ] nombrecolumna ) Esta uncin retorna la suma de los valores de la columna especificada o de la expresin. Estas expresiones agregadas son soportadas por todos los gestores aqu estudiados y con la sintaxis original de Informix-SQL con la peculiaridad que el resto de gestores no reconocen el token UNIQUE en la misma. Esto no ser problema ya que si en el cdigo fuente aparece UNIQUE se sustituir por DISTINCT en el cdigo objeto generado. En el punto: Ejemplo de funciones agregadas se muestran ejemplos de generacin de cdigo objeto de estas funciones para cada uno de los gestores de bases de datos estudiados.

NOMBRES DE VARIABLES
Con este titulo Informix hace referencia a el acceso a variables complejas: arrays y registros. La sintaxis que Informix define es: <nombre_vbles> ::= <registro> | <array> <registro> ::= [ registro . ] [1..n] variable <array> ::= array [ nmero [,..n] ] [ . <nombre_vbles> ] Es una sintaxis compleja pero admitida por cualquier gestor de bases de datos.

NOMBRES DE ELEMENTOS DE LA BASE DE DATOS

Al definir la sintaxis, a lo largo de ste documento, se hace referencia a elementos de la base de datos como: tablas, vistas, sinnimos, ndices, y constraints. Esto plantea dos dudas: que sintaxis representa y si sta soportada por el resto de gestores de base de datos. Estas dos cuestiones se estudian a continuacin: La sintaxis de estos elementos es: <ELEMENTOBD> ::= [ usuario .] nombretabla Donde: usuario y nombretabla son dos identificadores. Y esta sintaxis es soportada por el resto de gestores de bases de datos sin ninguna restriccin. Para hacer referencia a un campo de una tabla se usa la siguiente sintaxis: <CAMPOTABLA> ::= [ <ELEMENTOBD> . ] nombrecampo Esta sintaxis tambin es soportada por todos los gestores de bases de datos aqu estudiados, teniendo en cuenta la peculiaridad de oracle comentada en el apartado: Expresiones de manejo de columnas que si en la parte SELECT se indica el propietario de la tabla tambin se debe indicar en la parte FROM de la sentencia.

197

OPERACIONES SOBRE EXPRESIONES SQL

Sobre las expresiones de Informix-SQL se pueden aplicar una serie de operadores. La mayora de los operadores tienen restricciones en cuanto a los tipos de datos sobre los cuales se pueden aplicar y los valores resultado de aplicarlos. Las operaciones sobre expresiones SQL se definen sintcticamente al definir las condiciones y las expresiones como se muestra a continuacin: Definicin sintctica de las expresiones: <expresin> ::= [ + | - ] <tipos_de_expresion> <mas_tipos_de_expresion> <mas_tipos_de_expresion> ::= [ [ + | - | * | / ] <tipos_de_expresion> <mas_tipos_de_expresion> ] | vacio <tipos_de_expresion> ::= [ <expresion_columna> | <expresion_cte> | <expresion_funcion> | <expresion_agregada> | <variable> | ( <expresin> ) ] Las expresiones SQL as como su tratamiento ya Expresiones sql. Definicin sintctica de las condiciones: <condicin> ::= { [ NOT ] <condicion_de_comparacion> | <condicon_con_subquery> } [ AND | OR ] [..n] <condicon_de_comparacion> ::= <expresin> <operador_de_relacion> <expresin> | <expresin> [NOT] BETWEEN <expresin> and <expresin> | <expresin> [NOT] IN ( {literal_numerico | literal_fechahora | cadena_caracteres | TODAY | USER | CURRENT} [, ..n] ) | <campo> IS [NOT] NULL | <campo> [NOT] [LIKE | MATCHES] cadena_caracteres <operador_de_relacion> ::= [ < | > | = | <= | >= | != | <> ] <condicon_con_subquery> ::= <expresin> [NOT] IN (<sentencia_select>) | <expresin> [NOT] EXISTS (<sentencia_select>) | <expresin> <operador_de_relacion> [SOME|ANY|ALL] (<sentencia_select>) Como se ve en la definicin de la sintaxis las operaciones que se pueden realizar en el gestor de bases de datos son una combinacin de expresiones y operadores. A continuacin se detallan los operadores que admite Informix-SQL: Operadores aritmticos se aplican sobre expresiones numricas y son: +, -, *, y /. Si ambos operndoos son de los tipos de datos: INTEGER, SMALLINT o DATE el resultado de una operacin aritmtica ser un nmero entero. Si un operando es del tipo de dato: DECIMAL, FLOAT, MONEY o SMALLFLOAT el valor resultante contendr una parte fraccional. Los operadores: + y se pueden aplicar sobre operndoos tipo fecha. El resultado depender de los operndoos: Si uno de los operndoos es un entero el resultado ser una fecha siempre y cuando este dentro del rango de una fecha valida. Si ambos son fechas el resultado ser un entero negativo o positivo. han sido tratadas en el punto anterior:

Operadores de relacin son: <, <=, >, >=, =, <> y !=. Operadores lgicos: BETWEEN. Para que sea evaluada como cierta la expresin a la izquierda de la palabra reservada BETWEEN debe de estar incluida en el rango de valores de las dos expresiones de la parte derecha de la plabra reservada BETWEEN. Sintaxis:

198 <expresion> [NOT] BETWEEN <expresion1> and <expresion2> Otra forma equivalente de hacer la misma bsqueda es utilizando la siguiente sintaxis: <expresion> >= <expresion1> AND <expresion> <= <expresion2> Ejemplo: select count(*) from prueba1 where campo2 between 1 and 2 IN. Una condicin IN es satisfecha cuando la expresin de su parte izquierda esta incluida en la lista de elementos de la parte derecha, esta lista de elementos pueden ser literales separados por comas o bien el resultado de una sentencia select. Sintaxis: <expresin> [NOT] IN ( {literal_numerico TODAY | USER | CURRENT} [, ..n] ) <expresion> [NOT] IN ( <sentencia_select> ) Ejemplos: select campo3 from prueba1 where campo2 in (select campo2 from prueba2) select campo3 from prueba1 where campo2 in (1,2,3) IS. Permite chequear la presencia o ausencia de valores NULL. Sintaxis: <campo> IS [NOT] NULL Ejemplo: select count(*) from prueba1 campo1 is null LIKE, MATCHES. La condicin de bsqueda es satisfecha cuando el valor de la columna indicado en la parte izquierda coincide con el patrn especificado en la cadena de caracteres. Sintaxis: <campo> [NOT] [LIKE | MATCHES] cadena_caracteres Si se usa la palabra reservada LIKE se pueden usar los siguientes caracteres espaciales dentro de cadena_caracteres: % coincidencia con cero o ms caracteres. \ coincidencia con un solo carcter. elimina el significado especial del resto de caracteres especiales. | literal_fechahora | cadena_caracteres |

Si se usa la palabra reservada MATCHES se puede usar los siguientes caracteres especiales dentro de cadena_caracteres: * ? coincidencia con cero o ms caracteres. coincidencia con un solo carcter.

[] coincidencia con los caracteres indicados dentro de los corchetes, admite rangos como [a-z]. Si el primer carcter es: ^ la coincidencia es con cualquier carcter excepto de los indicados entre corchetes. \ elimina el significado especial del resto de caracteres especiales.

Cuando se realizan comparaciones de cadenas con LIKE/MATCHES, todos los caracteres de la cadena del modelo son importantes, incluidos los espacios iniciales o finales y la distincin entre maysculas y minsculas. Si una comparacin de una consulta debe devolver todas las filas con una cadena LIKE/MATCHES 'abc ' (abc seguido de un espacio), no se devuelve una fila en que el valor de esa columna sea abc (abc sin un espacio). Sin embargo, los espacios en blanco a la derecha de la expresin con la que se compara el modelo, se omiten. Si la comparacin de una consulta debe devolver todas las filas con la

199 cadena LIKE/MATCHES 'abc' (abc sin un espacio), se devuelven todas las filas que empiezan con abc y tienen cero o ms espacios a la derecha. EXISTS. La condicin es evaluada a cierto cuando la subconsulta retorna al menos un valor. Sintaxis: [NOT] EXISTS ( <sentencia_select> ) Ejemplo: select campo3 from prueba1 where exists prueba1.campo2) ANY/ALL/SOME. La sintaxis es la siguiente: <expresin> <operador_de_relacion> [SOME|ANY|ALL] (<sentencia_select>) Si se usa el token ALL la expresin se evala a cierta si todos los elementos retornados por la subconsulta cumplen la comparacin. Si no retorna ningn valor se evala cono cierta. En caso de usar el token ANY la expresin se evala a cierto si al menos un valor de los devueltos por la sentencia select cumple la condicin. Si la sentencia select no retorna ningn valor la expresin se evala como falsa. SOME es un alias de ANY. Ejemplo: select sum(campo3) from prueba1 where campo2 any > (select campo2 from prueba2) En la tabla siguiente se muestra la precedencia de operadores, que el gestor de bases de datos Informix soporta, en orden descendente (de mayor a menor precedencia). Los operadores con la misma precedencia se muestran en la misma fila: ( select * from prueba2 where campo2=

Operador

Propsito Operadores unarios: positivo, negativo. Operadores binarios: multiplicacin, divisin. Operadores binarios: suma, resta. Negacin. Operadores relacionales. Operadores lgicos. Conjuncin. Disyuncin.

+, *, / +, NOT

<, <=, =, >, >=, !=, <>


IN, BETWEEN, LIKE, MATCHES, SOME, ALL, ANY AND OR

Tabla 41: Precedencia de operadores en Informix-SQL

TRATAMIENTO POR SQLSERVER


Para SQL Server un operador es un smbolo que especifica una accin que es realizada por una o ms expresiones. SQL Server utiliza las siguientes categoras de operadores: Operadores aritmticos: realizan operaciones matemticas con dos expresiones de cualquiera de los tipos de datos de la categora del tipo de datos numrico. Cuando se aplica un operador a dos expresiones de tipos de datos diferentes, las reglas de precedencia especifican cul de los dos tipos se convierte al otro. El tipo de datos con menor precedencia se convierte al tipo de datos con mayor precedencia. Si la conversin no es una conversin implcita admitida, se

200 devuelve un error. Cuando ambas expresiones de operndoos tienen el mismo tipo de datos, el resultado de la operacin tiene ese tipo de datos5. Tambin se pueden utilizar los operadores de suma (+) y resta (-) para realizar operaciones aritmticas sobre valores datetime. Ej: SET @startdate = '1/10/1900 12:00 AM' SET @adddays = 5 SELECT @startdate + @adddays AS 'Add Date'

El resultado de sumar un nmero a una fecha es una fecha. En SQLSERVER no se pueden restar fechas entre s directamente como se puede hacer en Informix-SQL. Para solventar este problema a la hora de traducir el cdigo objeto se debe de utilizar la funcin DATEDIFF como se muestra en el siguiente ejemplo: Restar Fechas: DATEDIFF (dd, fecha1, fecha2) Para saber si se debe utilizar esta funcin se necesitar determinar durante el anlisis semntico que ambos partes de la expresin son de tipo DATE. Para poder determinarlo ser preciso, en tiempo de traduccin, tener conexin a la base de datos con objeto de obtener el tipo de datos de los campos. Operador de asignacin. Informix no considera este operador. Operadores bit a bit. Los operadores bit a bit realizan tratamientos de bits entre dos expresiones de cualquiera de los tipos de datos de la categora del tipo de datos enteros. No se profundiza ms en este tipo de operador debido a que Informix-SQL no lo reconoce como tal y por tanto no habr la necesidad de tratarlo a la hora de traducir cdigo fuente a objeto. Operadores de comparacin. Los operadores de comparacin comprueban si dos expresiones son iguales o no. Se pueden utilizar en todas las expresiones excepto en las de los tipos de datos TEXT, NTEXT O IMAGE. Es muy improbable que cause problemas este tipo de operaciones a la hora de ejecutar cdigo destino sobre SQLSERVER ya que de estos tres tipos de datos solo se puede llegar a utilizar el tipo de dato TEXT y este contendr cadena de tamao grande (ms de 254 caracteres) que es muy improbable se utilicen en comparaciones dentro de expresiones. Devuelve un valor boolean: TRUE o FALSE. Operadores lgicos. Los operadores lgicos comprueban la veracidad de alguna condicin. stos, como los operadores de comparacin, devuelven el tipo de datos boolean con valor TRUE o FALSE. ) ALL/ANY/SOME. Sintaxis: <expresin> {= | <> | != | > | >= | !> | < | <= | !<} [ALL|ANY|SOME] ( <subconsulta> ALL: Devuelve TRUE cuando la comparacin especificada es TRUE para todas las parejas (scalar_expression, x) donde x es un valor del conjunto de columna nica; de lo contrario, devuelve FALSE. SOME o ANY: devuelve TRUE cuando la comparacin especificada es TRUE para una pareja (scalar_expression, x) donde x es un valor del conjunto de resultados de una sola columna. De lo contrario, devuelve FALSE. BETWEEN. Especifica el intervalo que se va a probar. Sintaxis: <expresion> [ NOT ] BETWEEN <begin_expresion> AND <end_expresion>

Para ms informacin sobre precedencia de operadores dirigirse a los libros en pantalla de Sql Server.
5

201 BETWEEN devuelve TRUE (verdadero) si el valor de <expresin> es mayor o igual que el valor de <begin_expresion>, y menor o igual que el valor de <end_expression>. EXISTS. Especifica una subconsulta para probar la existencia de filas. Sintaxis: [NOT] EXISTS ( <subconsulta> ) Devuelve TRUE si alguna subconsulta contiene alguna fila. IN. Determina si un valor dado coincide con algn valor de una subconsulta o lista. Sintaxis: <expresion> [NOT] IN ( <subquery> | <expresion2> [ ,...n ] )

Si el valor de <expresin> es igual a cualquier valor devuelto por <subconsulta> o es igual a cualquier elemento de la lista separada por comas, el valor del resultado es TRUE. En caso contrario, el valor del resultado es FALSE. Con NOT IN se niega el valor devuelto. Hasta el momento los operadores lgicos estudiados para SQLSERVER tienen igual sintaxis que los que define Informix-SQL y un comportamiento igual con lo que no se plantea ningn problema a la hora de traducir cdigo fuente a cdigo objeto que pueda ser ejecutado sobre el gestor de bases SQL Server. LIKE. Determina si una cadena de caracteres dada coincide o no con un determinado modelo. Un modelo puede incluir caracteres normales y caracteres comodn. Durante la coincidencia de patrones, los caracteres regulares deben coincidir exactamente con los caracteres especificados en la cadena de caracteres. Sin embargo, los caracteres comodn pueden coincidir con fragmentos arbitrarios de la cadena de caracteres. Con los caracteres comodn el operador LIKE es ms flexible que los operadores de comparacin de cadenas = y !=. Sintaxis: <expresion> [ NOT ] LIKE <patron> [ ESCAPE escape_character ] El patrn es el modelo que se va a buscar en <expresin> y puede incluir cualquiera de los siguientes caracteres comodn vlido de SQL Server: % Cualquier cadena de cero o ms caracteres. _ Cualquier carcter individual. [] Cualquier carcter individual de intervalo ([a-f]) o del conjunto ([abcdef]) especificado. [^] Cualquier carcter individual que no se encuentre en el intervalo ([^a-f]) o el conjunto ([^abcdef]) especificado.

Los caracteres comodn de concordancia de patrn se pueden utilizar como literales. Para utilizar como literal un carcter comodn, se incluye entre corchetes. Con la opcin ESCAPE se pueden buscar cadenas de caracteres que incluyan uno o ms caracteres comodn especiales. Esta opcin permite cambiar el carcter que se utiliza para utilizar los caracteres especiales en el patrn. Ejemplo: para buscar las filas que contengan la cadena 30% en cualquier parte de la columna, se puede especificar la clusula WHERE siguiente: WHERE campo LIKE '%30\%%' ESCAPE '\' SQL Server no define el operador MATCH pero define el operador LIKE de forma ms completa que lo hace Informix-SQL lo cual facilitar el hacer la traduccin de este operador de cdigo fuente a cdigo objeto. Si en cdigo fuente se utiliza el token MATCH en cdigo objeto se utilizar LIKE, se analizar el patrn y se sustituirn los caracteres: * por % y ? por , se mantendr la utilizacin de corchetes para especificar conjuntos o rangos de caracteres. Tambin se especificar la clusula: ESCAPE '\' al generar cdigo, en caso de que en el cdigo fuente no se especifique y se utilice, con objeto de mantener el mismo carcter de escape.

202 Si en cdigo fuente se utiliza la clusula LIKE a la hora de generar cdigo objeto para SQLSERVER lo nico que debe hacer para que el cdigo objeto original sea compatible es especificar la clusula: ESCAPE '\' SqlServer, al igual que Informix-SQL, desprecia los caracteres blancos a la derecha de las palabras almacenadas en los campos a la hora de hacer comparaciones con la clausula LIKE. Un problema que se plantea en este gestor de bases de datos es que los campos de la base de datos por defecto son case insensitive lo que implica que una comparacin de una consulta que debe devolver todas las filas con una cadena LIKE Abc devolvera lo mismo que si la cadena LIKE fuese abc lo cual no es lo mismo que devolvera el gestor de bases de datos Informix-SQL para el cual se escribi el cdigo original. SQLSever 2000 no plantea solucin para este problema pero Sqlserver 2005 permite configurar el tratamiento de los campos por parte del gestor de dos formas diferentes: bien a travs de la herramienta de administracin del propio gestor de bases de datos en las propiedades de la misma, como se muestra en la siguiente figura, o bien a la hora de definir las campos de las tablas con la opcin COLLATE, Ej.: create table prueba1 ( campo1 char(20) collate MODERN_SPANISH_CS_AI ). Por transparencia y sencillez esta configuracin se har a nivel de base de datos a travs de la herramienta de administracin.

Figura 13: Propiedades de la base de datos SQL Server En el campo Intercalacin se ha de fijar el valor: MODERN_SPANISH_CS_AI SQLSERVER no define el operador lgico IN pero define la funcin IN que devuelve TRUE si dos objetos comparados son equivalentes, y FALSE en el resto de casos. Sintaxis: <objeto1> IN <objeto2> <objeto1> IS [ NOT] NULL Operador de concatenacin de cadenas. El operador de concatenacin de cadenas permite concatenar cadenas con el signo de suma (+), tambin conocido como operador de

203 concatenacin de cadenas. Cualquier otro tratamiento de cadenas se controla a travs de funciones de cadenas como SUBSTRING. En la versin de Informix que estamos traduciendo no se contempla este operador con lo que no habr necesidad de utilizarlo a la hora de traducir cdigo fuente a cdigo objeto. Operadores unarios. Los operadores unarios realizan una operacin sobre una nica expresin de cualquiera de los tipos de datos de la categora del tipo de datos numrico.

Cuando una expresin compleja tiene mltiples operadores, la precedencia de operadores determina la secuencia en la que estos son evaluados. El orden de ejecucin puede variar significativamente el resultado. Los operadores tienen precedencia que se muestra en la tabla siguiente de mayor a menor precedencia. Los operadores de mayor precedencia son evaluados antes que aquellos de menor precedencia.

Operador +, - , ~ *,/,% +, -,+ =, >, <, >=, <=, <>, !=, !>, !< ^, &, | NOT AND ALL, ANY, BETWEEN, IN, LIKE, OR, SOME =

Propsito Operadores unarios: positivo, negativo, negacin a nivel de bit. Operadores mdulo. Comparacin Comparacin a nivel de bit: or exclusivo, and y or Negacin lgica Conjuncin Operadores lgicos Asignacin binarios: multiplicacin, divisin,

Operadores binarios: suma, resta, concatenacin

Tabla 42: Precedencia de operadores en SqlServer

TRATAMIENTO PO ORACLE
Para oracle los operadores manipulan unidades de datos individuales llamados operndoos o argumentos. Los operadores se representan como caracteres especiales o palabras reservadas y Oracle los clasifica en los siguientes tipos: Operadores aritmticos: Se utilizan en una expresin para negar, sumar, restar, multiplicar, o dividen valores numricos. El resultado de una operacin aritmtica es un valor numrico. Algunos operadores se pueden utilizar sobre valores tipo DATE. Oracle permite sumar o restar un valor tipo numrico a un valor tipo fecha o fecha/hora, proporcionando como resultado otro valor tipo fecha/hora. Oracle internamente convierte los valores tipo TIMESTAMP a valores tipo DATE e interpreta los valores numricos como el nmero de das a aplicar sobre el operador. Si el valor numrico a es fraccional se entiende como el nmero de minutos. Ejemplos: select sysdate + 1 from dual; select sysdate 7 from dual; select sysdate + (10/1440) from dual; Da siguiente. Semana pasada. Suma 10 minutos.

204 Oracle permite restar fechas retornando el nmero de das (positivos o negativos) que haya entre ambos operndoos. Debido a que el tipo de dato DATE de Oracle contiene componente hora, Oracle permite que el resultado de una operacin con fechas incluya y proporcione como resultado parte fraccional. Esta parte fraccional significa la porcin de da. Ejemplo 1,5 das son 36 horas. El comportamiento de Oracle con las operaciones sobre fechas, descrito anteriormente, es ms amplio que el que define Informix-SQL debido a que: por un lado el tipo de datos DATE de oracle es ms amplio al contener fechas y horas, y por otro a que Oracle permite sumar valores fraccionales a los valores tipo DATE. Esta mayor amplitud en la definicin del tipo de dato DATE y las operaciones que se pueden hacer sobre l hace que la traduccin de cdigo fuente a cdigo objeto ejecutable sobre Oracle no tenga ningn problema. Operador de concatenacin. El operador de concatenacin manipula tipos de datos de cadenas de caracteres. El resultado de concatenar dos cadenas de caracteres es otra cadena de caracteres. En caso de que un parmetro sea de mayor rango (VARCHAR2, CLOB) que el otro el resultado se almacena sobre el de ms rango estando limitada la longitud de la cadena resultante al la longitud del tipo de dato destino. No es preciso utilizar este operador ya que la versin de Informix-SQL que se esta traduciendo no lo contempla. Operadores de relacin. Las condiciones de comparacin comparan una expresin con otra. El resultado de dicha comparacin es TRUE, FALSE o DESCONOCIDO. Operadores lgicos. SOME/ANY/ALL. Sintaxis: <expresin> <operador_de_relacion> ( <subquerey> | <expresion_list> ) <operador_de_relacion> ::= < | > | <= | >= | != | = | <> <expresion_list> ::= <expresin> [,..n] SOME/ANY. Compara el valor con cada uno de aquellos devuelto en la <subconsulta>. Si en algn caso la condicin de comparacin se cumple el resultado de evaluar la expresin es TRUE. Si la <subconsulta> no retorna ninguna fila la expresin es evaluada como FALSE. ALL. Compara el valor con todos los valores devueltos por la <subconsulta>. Si la condicin se cumple para todos y cada uno de los valores retornados por la <subconsulta> la expresin se evala como TRUE. Si la <subconsulta> no retorna valores la expresin se evala como TRUE. La sintaxis de este operador es totalmente compatible con la sintaxis de Informix-SQL con lo que no habr ningn probleme al traducir cdigo fuente a cdigo objeto. LIKE. Esta condicin especifica una comparacin con un patrn de caracteres. Sintaxis: <expresion_de_caracteres> [NOT] LIKE patron [ ESCAPE caracter ] Oracle evala la condicin LIKE dividiendo el patrn en subpatrones que casan con uno o ms caracteres cada uno. Los subpatrones que casan con ms de un carcter se forman con uno de los siguientes caracteres de escape: % Casa con uno o ms caracteres. Casa con un nico carcter.

La opcin ESCAPE permite especificar dentro del patrn uno de los dos caracteres de escape anteriores sin que sean considerados como tal. A la hora de traducir la sentencia LIKE del cdigo fuente Informix-SQL a Oracle no se plantea ningn problema siempre y cuando se utilice la clusula ESCAPE y el carcter de escape la barra invertida: \. En el caso de que en el cdigo fuente se utilice la sentencia

205 MATCHES, al igual que ocurra al traducir la sentencia para SqlSever, hay que sustituir el token MATCHES por LIKE y analizar el patrn y realizar sustituciones en el mismo: * por % y ? por -. Aqu se plantea un problema adicional debido a que la sentencia like no admite el patrn []. Para solventar este problema, y conseguir as que el cdigo resultante sea equivalente al cdigo fuente, se propone como solucin aadir una condicin ms a la sentencia en la cual se utilice la funcin SUBSTR, a continuacin se muestras dos casos ilustrativos: Cdigo fuente Informix-SQL: select campo1 from tabla1 where campo1 like A[^B]C% Cdigo objeto Oracle: select campo1 from tabla1 where campo like A_C% and substr(campo1,2,1) != B Cdigo fuente Informix-SQL: select campo1 from tabla1 where campo1 like [A-C]E% Cdigo objeto Oracle: select campo1 from tabla1 where campo1 like _E% and substr(campo1,1,1) in (A,B,C) Otro problema que se plantea sobre el gestor de bases de datos Oracle al aplicar la condicin LIKE es que este considera los espacios en blanco al final de las cadenas debido a lo cual una condicin de bsqueda LIKE abc (sin espacio al final) no casar con aquellos campos que contengan abc (con espacio al final) y esto no es el comportamiento del gestor original. Para solucionar este problema se han planteado dos soluciones: bien aplicar la funcin RTRIM sobre el campo o bien aadir al final de la cadena patrn un %. Aunque se entiende que es ms correcta la primera solucin se implementa la segunda por sencillez en su tratamiento. BETWEEN. Comprueba sin una expresin esta incluida en un rango. Sintaxis: <expresion> [NOT] BETWEEN <expresion1> AND <expresion2> La sintaxis de est sentencia es totalmente compatible con la de Informix-SQL. IS. Permite comprobar si la expresin es NULL. Sintaxis: <expresin> IS [NOT] NULL No se plantea ningn problema con esta sentencia al traducir cdigo fuente Informix-SQL a Oracle. EXISTS. Testea la existencia de filas en la subconsulta. Sintaxis: EXISTS ( <subconsulta> ) Informix-SQL define la misma sintaxis para esta sentencia. IN. Chequea sin una expresin esta incluida en a una lista o subconsulta. Sintaxis: <expresion> [NOT] IN { <expresion_list> | <subquery> } Esta sentencia no plantea ningn problema a la hora de traducir cdigo fuente a cdigo objeto. En la tabla siguiente se muestran los operadores utilizados por oracle as como la precedencia de los mismos. A la hora de evaluar condiciones en la misma expresin, Oracle evala las condiciones con mayor precedencia antes que aquellas de menor precedencia. Las condiciones de igual precedencia son evaluadas de izquierda a derecha. Los operadores son evaluados antes que las condiciones SQL.

206 En la tabla que se muestra a continuacin se listan los niveles de precedencia en comparaciones de mayor a menor. Las condiciones en la misma lnea tienen la misma precedencia Operador +, *, / +, -, || =, !=, <, >, <=, >=, <> Propsito Operadores unarios: positivo, negativo. Operadores binarios: multiplicacin, divisin. Operadores binarios: concatenacin. Comparacin. suma y resta,

IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT] Comparacin lgica. IN, EXISTS, IS OF type, SOME, ANY, ALL NOT AND OR Tabla 43: Precedencia de operadores Oracle Negacin lgica Conjuncin. Disyuncin.

TRATAMIENTO POR DB2


Las expresiones son el elemento bsico de construccin de querys. Las expresiones puedes utilizarse solas o junto con otras expresiones para construir querys complejas. Los tipos de expresiones bsicos son: Expresiones aritmticas, incluye los operadores unarios: + y y +, -, *, y / binarios. El resultado de realizar una operacin aritmtica sobre dos valores validos es un valor numrico. Al igual que en Informix-SQL se pueden aplicar los operadores + y sobre fechas, permitindose incrementar, decrementar fechas y restar: Sumar o restar un valor numrico a una fecha. El resultado es una fecha que corresponde a la fecha que se recibe como operando +/- el nmero el cual se interpreta en funcin de la definicin de la duracin. Db2 no deja sumar valores numricos directamente a fechas, estos deben de venir precedidos de la etiqueta de duracin. La etiqueta de duracin representa la unidad de tiempo en la cual se expresa el nmero. Las palabras que se pueden utilizar para indicar la duracin son: YEARS, MONTHS, DAYS. Para ser capaces de traducir cdigo fuente Informix a Db2 que incluya esta operacin ser preciso un tratamiento semntico de la expresin, y este tratamiento implicar la necesidad de, en tiempo de traduccin, tener conexin a la base de datos con objeto de determinar el tipo del campo que se procesa en la expresin. Ejemplo: cdigo fuente: select campo4 + 1 from tabla cdigo objeto Db2: select campo4 + 1 DAY from tabla Para realizar la conversin de cdigo de forma correcta se requiere del anlisis semntico con objeto de determinar, en tiempo de traduccin, el tipo de datos de las variables, constantes y/o campos. Restar fechas. El resultado de restar una fecha de otra es un valor entero, positivo o negativo, que represente el nmero de aos, meses y das entre ambos operndoos. Db2 representa el resultado en un tipo de dato decimal(8,0) donde, empezando de izquierda a derecha, los dos primeros dgitos representan los das los, dos siguientes los meses y el resto los aos de diferencia entre ambas fechas. Ej: El resultado de restar las fechas 15/03/2000 y 31/12/199 es 00000215 que representa: 0 aos, 2 meses y 15 das.

207 El valor devuelto por Db2 al ejecutar el operador de resta (-) no es coherente con el que proporciona el gestor de bases de datos Informix-SQL, para que ambos gestores retornen el mismo valor se habr modificar el cdigo generado para Db2 de la siguiente forma: cdigo fuente: select campo2 campo1 from tabla1 cdigo objeto: select days(campo2) days(campo1) from tabla Evidentemente se ha de saber en tiempo de compilacin los tipos de datos de los operndoos. Esto nos lo proporcionar el analizador semntico. Expresiones lgicas usan los operadores AND y OR para, tras ser aplicados sobre los operndoos, proporcionar un valor booleano (TURE o FALSE). Expresiones de comparacin. construir

En DB2 se pueden combinar querys con diferentes conjunto de operadores para sentencias condicionales complejas.

Una condicin de bsqueda esta formada por uno o ms predicados. Un predicado especifica una condicin sobre una fila que puede ser evaluada como: TRUE, FALSE o UNKNOWN. Dentro de la clusula WHERE se pueden usar los siguientes predicados: Predicados bsicos: <, <=, =, >, >=, <> permiten comparar dos valores. Sintaxis:

<expresin> [ = | <= | >= | < | > | <> ] <expresin>


Predicados Cualificados: ANY, SOME, ALL. Permiten comparar uno o ms valores con una coleccin de valores. Sintaxis: <expresin> <operador_relacion> {SOME|ANY|ALL} ( <subconsulta> ) | <expresiones> {SOME|ANY} ( <subconsulta> ) Cuando se utiliza ALL el resultado de evaluar el predicado es TRUE si la <subconsulta> no retorna valores o la comparacin entre la expresin y los valores devueltos por la <subconsulta> se evala a TRUE para todos ellos. Si se especifica SOME o ANY el predicado es evaluado a TRUE si la condicin se cumple para al menos una fila de las retornadas en la <subconsulta>. Si la <subconsulta> no retorna ninguna fila la expresin se evala a FALSE. Esta sintaxis, aunque ms amplia, es totalmente compatible con la definida por Informix-SQL. Predicado BETWEEN. Compara un valor con un rango de valores. Sintaxis: <expresion> [NOT] BETWEEN <expresion1> AND <expresion2> sintaxis compatible con la de Informix-SQL. Predicado EXISTS. Comprueba la existencia de alguna fila en la subconsulta. Sintaxis: EXISTS ( <subconsulta> ) Sintaxis compatible con la de Informix-SQL. Predicado IN. Compara un valor o conjunto de valores con una coleccin de valores. Sintaxis: <expresion> [NOT] IN { ( <subquery> ) | <expresion2> | ( <expresion2> [,..n] ) } | <expresion> [,..n] [NOT] IN ( <subquery> ) La sintaxis de esta sentencia es ms amplia que la definida en Informix-SQL pero incluye sta con lo que no habr ningn problema para al ejecutar esta sentencia sobre el gestor de bases de datos DB2.

208 Predicado LIKE. Este predicado busca una cadena de caracteres que cumpla un cierto criterio. El patrn es otra cadena de caracteres en la cual los caracteres: - y % tienen un significado especial. Sintaxis: <expresion> [NOT] LIKE <patron> [ESCAPE <expresion_escape>] El patrn utilizado para definen el criterio a aplicar a la expresin puede contener los siguientes caracteres: Carcter de subrayado (_) representa cualquier carcter simple. Carcter de porcentaje (%) representa una cadena de 0 ms caracteres. Cualquier otro carcter se representa as mismo.

Si dentro del patrn se necesita incluir un carcter especial (_, %) como un carcter normal se debe de utilizar clusula ESCAPE. El carcter indicado en esta clusula ha de preceder al carcter especial que se desea utilizar como carcter normal dentro del patrn. A la hora de traducir cdigo fuente Informix-SQL para ser ejecutado sobre el gestor de bases de datos DB2 con esta sentencia se plantean los mismos problemas que con Oracle: no admite el definir un grupo de caracteres o la exclusin dentro del patrn y considera los caracteres en blanco al final de la cadena a la hora de comparar con el patrn LIKE. La solucin planteada, para cada uno de los casos, ser la misma que se aplico para Oracle. Predicado NULL. Testea la existencia de valores NULL. Sintaxis: <expresin> IS [NOT] NULL Esta sentencia es equivalente a la definida por Informix-SQL. En la siguiente tabla se muestra los operadores de DB2 en orden de mayor a menor precedencia: Operador +, *, / +, SOME, ANY, ALL NOT <, <=, =, >, >=, <> EXISTS, IN, BETWEEN, LIKE, MATCHES AND OR Tabla 44: Precedencia de operadores Db2 Negacin. Operadores de comparacin. Operadores lgicos. Conjuncin. Disyuncin. Propsito Operadores unarios: positivo, negativo. Operadores binarios: multiplicacin, divisin. Operadores binarios: suma, resta.

TRADUCCIN DE OPERADORES SOBRE EXPRESIONES


Al operar con fechas hay que tener en cuenta la definicin de las mismas. Oracle y SqlServer definen los tipos de datos DATE y SMALLDATETIME respectivamente para almacenar fechas, estos tipos de datos contienen informacin de la fecha y de la hora lo cual difiere con la definicin que realiza Informix (y DB2) la cual solo contiene informacin sobre la fecha. Esto podra producir errores a la hora de operar y hacer comparaciones como en los ejemplos que se muestran a continuacin: Ejemplo1, restar un campo tipo fecha con la constate today: Cdigo fuente: select campo1 today into entero from tabla

209 Cdigo fuente SqlServer: select campo1 getdate() into entero from tabla Cdigo fuente SqlServer: select campo1 sysdate into entero from tabla Dependiendo de la hora del da el valor de la variable: entero para la consulta realizada para SqlServer y Oracle podra ser el mismo que para Informix o un da menos. Ejemplo2, comparar fechas: Cdigo fuente: select count(campo2) from tabla where campo1 = today Cdigo fuente SqlServer: select count(campo2) from tabla where campo1 = getdate() Cdigo fuente SqlServer: select count(campo2) from tabla where campo1 = sysdate Lo ms normal es que la consulta que se realiza sobre el gestor de base de datos Informix proporcione un valor entero positivo y la realizada sobre SqlServer y Oracle de 0. Por otro lado para que las operaciones sobre fechas tengan el mismo significado sobre todos los gestores habr que realizar, a la hora de generar cdigo objeto para SqlServer y Oracle, para aquellas sentencias que definen valores para este tipo de variables/campos es que la parte hora tome el valor 0:0:0. Este caso se dar bsicamente a la hora de traducir la constante TODAY a estos gestores. La traduccin a realizar ser: Para Oracle en lugar de usar SYSDATE utilizar: TO_DATE(TO_CHAR(SYSDATE,'dd/mm/yyyy')) Para SqlServer en lugar de usar GETDATE() utilizar: DATEPART(dd,0, DATEDIFF(dd,0,GETDATE())) Para poder traducir las operaciones de que involucran fechas a otros gestores hay que aplicar mucha semntica y utilizar la tabla se smbolos. Es preciso saber el tipo de datos de los operandos que intervienen en la expresiones y para saber estos es necesario identificar los tipos a los que pertenecen las constantes, variables y campos de las tablas y para estos ltimos es necesario saber a que tabla pertenecen los campos. El primer problema para determinar el tipo de dato de un campo es que en alguna sentencia, sentencia select por ejemplo, el nombre de la tabla se lee con posterioridad al nombre de los campos y a la hora de procesar los campos se debe de saber el tipo de estos. La solucin a este problema es hacer una lectura haca delante de tokens hasta determinar las tablas y/o sinnimos que intervienen en la sentencia. Una vez sabido el nombre de las tablas que intervienen en la sentencia ya se puede determinar el tipo de datos de los campos haciendo una consulta a la base de datos. Dentro del Anexo I, en la seccin: Ejemplo de manejo de operaciones sobre expresiones se plasma un ejemplo completo del comportamiento del traductor ante los distintos operadores y atendiendo al gestor de bases de datos destino.

CONFIGURACIN LOCAL

No se pretende en esta seccin explicar como se ha de configurar los diferentes gestores de bases de datos a nivel de idioma, formatos, fechas, etc., sino: por un lado saber como son reconocidos los literales por cada uno de los gestores de bases de datos, aqu estudiados, para garantizar que un literal definido en el cdigo fuente Informix-SQL sea tambin reconocido de la misma manera por el gestor de base de datos sobre el que se ejecute, y por otro lado poner los medios necesarios para garantizar que la interpretacin de los literales que hace Informix-SQL sea la misma que realicen el resto de gestores, por ejemplo si tenemos la fecha 12/6/2006 Informix la interpreta como el 6 de diciembre de 2006 es por tanto necesario si queremos que el cdigo fuente pueda ser ejecutado, con el mismo significado semntico, sobre el resto de gestores que estos la interpreten de la misma forma. Pongamos un ejemplo: Si en el campo: campofecha de la tabla: tablaY tenemos el valor: 30 de diciembre de 2005 y ejecutamos la siguiente sentencia: Select campotipofecha 12/01/2006 into vble from tablaY

210 El resultado de esta que este interpreta sentencia sobre un resultado ser 336 esperados. sentencia ejecutado sobre el gestor de bases de datos Informix, suponiendo la fecha como dd/mm/yyyy, ser 13, pero si ejecutamos esta misma gestor de bases de datos que interprete la fecha como mm/dd/yyyy el y por tanto la ejecucin del programa obtendr resultados diferentes a los

Los elementos clave a considerar son: delimitares de cadena y fecha, formato de fecha, separador de campo dentro de la fecha, delimitador de decimales, nmero de da de la semana, etc. Para ello se empezara indicando la configuracin que tiene Informix-SQL por defecto, algunas variables de entorno que fijan/modifican dicha configuracin, posteriormente se estudiara como definen y en base a que estos elementos de la configuracin el resto de gestores de bases de datos para con ello determinar los puntos a tener en cuenta para que el resto de gestores interpreten de igual forma, que Informix, los literales.

ELEMENTOS DE INFORMIX
En Informix-SQL hay elementos que definen la configuracin de los literales que vienen fijados por el idioma como por ejemplo el formato de fecha, separador decimal, etc., pero tambin existen otros que son fijos como el delimitador de cadenas, el nmero asociado al da de la semana, etc. Estos elementos se definen a nivel de gestor de bases de datos y algunos de ellos pueden ser modificados a nivel configuracin de sesin de usuario. Por defecto Informix tiene la siguiente configuracin: Elemento Delimitador de cadenas o fechas Delimitador de decimal Formato de fecha Formato fecha/hora Delimitador fecha Das de la semana Delimitador Comilla doble comilla simple Punto mm/dd/yyyy yyyy-mm-dd hh:mm:ss.ffffff Flash (/) 0 domingo, 1 lunes, ...., 6 sbado

Tabla 45: Formatos por defecto de Informix-SQL De estos valores, el da de la semana y el formato de fecha/hora no dependen del idioma configurado para el gestor ni de ninguna otra variable del servidor o de la sesin actual, su configuracin es siempre la misma. Existe un grupo de variables de entorno a nivel de sesin de usuario que pueden cambiar el comportamiento por defecto del gestor para cada usuario, estas son: DBDATE. Variable que permite especificar a los usuarios finales el formato de los valores tipo fecha. Con esta variable se indica: Orden del Mes (M), da (D), y ao (Y) en la fecha. Nmero de dgitos para el ao: Y2 (dos dgitos) , Y4 (cuatro dgitos) Separador entre los valores de la fecha, valor por defecto /, si se pone 0 (cero) se entiende que no hay. MDY4/ DMY2MDY4/ MDY20 07/01/1950 01-07-50 07/01/1950 070150

Ejemplos:

211 DBCENTURY. La parte ao de las fechas puede ser introducida con dos o con cuatro dgitos. Si el valor es expresado con dos dgitos la centuria se calcula en funcin del valor de esta variable de entorno. Lo posibles valores que puede tomar son: P = Pasado; asume que la fecha ambigua es pasada. F = Futuro; asume que la fecha ambigua es futura. C = Cercano; las fechas pasadas, presentes y futuras son evaluadas como lo mas cercana a la fecha actual. R = Presente; una fecha ambigua se entiende que es de la centuria actual. Si esta variable no esta fijada se entiende que tiene el valor R sea la fecha se evala como de la centuria actual. DBMONEY. Indica el delimitador decimal y por omisin el separador de miles. DBDELIMITER. Indica el valor delimitador de los campos de las tablas en las descargas y cargas de datos a y desde ficheros.

ELEMENTOS DE SQLSERVER
En SqlServer la opcin de lenguaje por defecto establece el formato de mensajes, nombres de meses, das de la semana, fechas y otras caractersticas relativas a la localizacin. A la hora de instalar el servidor de bases de datos se elige el lenguaje del mismo que por defecto ser el que tendrn los usuarios. El lenguaje que se tiene en cuenta es el que se establece para cada login y puede cambiarse si se desea. Con el idioma por defecto: Ingles, los valores que asume este gestor son: Elemento Delimitador de cadenas o fechas Delimitador de decimal Formato de fecha Formato de fecha/hora Delimitador fecha Das de la semana Tabla 46: Formatos por defecto de SqlServer Los formatos en los que se presentan las fechas pueden ser: dma (da, mes ao) amd (ao, mes, da) Para el caso de das de la semana si el idioma del usuario que se conecta fuese espaol tomara los valores: 1 lunes, 2 martes, ..., 7 domingo. Para este gestor este valor, al igual que el formato de fecha, depende del idioma del login del usuario y variar en funcin de este. Sin tener que cambiar el idioma existe posibilidad de cambiar alguno de estos parmetros como el formato de fecha y el orden de los das de la semana, para ello se pueden usar las variables de SqlServer: DATEFORMAT y DATEFIRST6. formato si el idioma es espaol. mda (mes, da, ao) formato por defecto. Comilla simple Punto mm/dd/yyyy (mdy) yyyy-mm-dd hh:mm:ss.fff slash (/) 1 domingo, 2 lunes, ...., 7 sbado Delimitador

Ver Documntacin de SQL Server

212

ELEMENTOS DE ORACLE
En Oracle existen varias variables que dependen del idioma seleccionado, estas se basan en el conjunto de caracteres de la base de datos actualmente definido para un servidor, cliente o sesin. Estn variables son las que definen los formatos de fecha, das de la semana, idioma de los mensajes, etc., y son conocidas como parmetros NLS. El idioma se fija por primera vez a la hora de instalar el servidor. Hay muchas formas de establecer los parmetros NLS tanto para el cliente como para el servidor: Se pueden especificar los parmetros NLS en el archivo de inicializacin de la base de datos en el servidor (init.ora). Esta configuracin no tiene ningn efecto en el lado del cliente, solo en el comportamiento del servidor. Se pueden establecer los parmetros NLS como una variable de entorno en el cliente. Esto define el comportamiento del cliente y modifica los definidos al momento de iniciar la sesin en el archivo de parmetros. Se pueden cambiar los parmetros NLS para una sesin con el comando: alter session set ... Y se pueden cambiar parmetros NLS incluso dentro de alguna sentencia SQL.

Los valores de los parmetros por defecto dependen del lenguaje elegido a la hora de hacer la instalacin o bien el del sistema operativo sobre el que se instala el gestor. En el caso de que el idioma sea espaol estos valores son: Elemento Delimitador de cadenas o fechas Delimitador de decimal Formato de fecha Formato de fecha/hora Delimitador fecha Das de la semana Tabla 47: Formatos por defecto de Oracle Una forma de ver la configuracin actual de cada sesin que se inicia contra el servidor es consultar, va sqlplus, la tabla: nls_sesssion_parameters que nos proporcionar los valores que tomara cada usuario al iniciar sesin, como se muestra a continuacin:
SQL> select * from nls_session_parameters; PARAMETER VALUE ------------------------------ -----------------------------NLS_LANGUAGE SPANISH NLS_TERRITORY SPAIN NLS_CURRENCY Pts NLS_ISO_CURRENCY SPAIN NLS_NUMERIC_CHARACTERS , NLS_CALENDAR GREGORIAN NLS_DATE_FORMAT DD/MM/YY NLS_DATE_LANGUAGE SPANISH NLS_SORT SPANISH NLS_TIME_FORMAT HH24:MI:SSXFF NLS_TIMESTAMP_FORMAT DD/MM/YY HH24:MI:SSXFF NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZH:TZM NLS_TIMESTAMP_TZ_FORMAT DD/MM/YY HH24:MI:SSXFF TZH:TZM NLS_DUAL_CURRENCY NLS_COMP

Delimitador Comilla simple Punto dd/mm/yyyy yyyy-mm-dd hh:mm:ss.fffffffff slash , guin, punto, espacio en blanco, etc. 1 lunes, ...., 7 domingo

213 Una forma sencilla de cambiar un parmetro para un cliente en particular es fijrselo como variable de entorno, ejemplo: set NLS_DATE_FORMAT=MM/DD/YYYY, en programas java se puede ejecutar la sentencia: alter session set NLS_DATE_FORMAT=MM/DD/YYYY. Para documentarse en mayor profundidad sobre los valores a configurar parmetros NLS referirse a la documentacin proporcionada por Oracle. en los diferentes

ELEMENTOS DE DB2
Cuando se crea una base de datos en DB2 se ha de decidir en que lenguaje sern almacenados los datos en ella. Al crear la base de datos se ha de especificar el territorio y conjunto de cdigos, los cuales pueden ser diferente del que tenga configurado el sistema operativo sobre el cual se esta instalando el gestor de bases de datos. Si no se especifica de forma explcita en el momento de la creacin de la base de datos el lenguaje con el cual se crear esta vendr determinado por la configuracin local. La configuracin local de los usuarios que acceden a la base de datos a de ser compatible con la que tenga el servidor. El idioma local se puede fijar en el script de inicializacin del usuario (profile, autoexec.bat, variables de entorno) y para ello se usa la variable de entorno LANG. La representacin de literales de fecha y hora, el delimitador de decimales, y otros elementos que dependen del cdigo de territorio (idioma) que se fija en el entorno de usuario a travs de la variable LANG. Con el idioma por defecto: Espaol igual al sistema operativo en el cual esta instalado, los valores que asume este gestor son: Elemento Delimitador de cadenas o fechas Delimitador de decimal Formato de fecha Formato de fecha/hora Delimitador fecha Das de la semana Tabla 48: Formatos por defecto de Db2 De estos elementos hay algunos que son fijos, que no dependen del idioma, como son: el delimitador de literales y el nmero asociado a cada da de la semana, etc. Para ms informacin referirse a la documentacin proporcionada por IBM respecto a su gestor de bases de datos DB2. Comilla simple Punto dd/mm/yyyy yyyy/mm/dd hh:mm:ss.fffff slash (/) 1 domingo, 2 lunes, ...., 7 sbado Delimitador

ELEMENTOS DE JAVA
Algo muy normal dentro de un programa es que se produzca el intercambio de valores: variables o constantes, entre el entorno de programacin y el gestor de bases de datos. Por tanto se debe de tener claro como interpreta java los elementos de la configuracin local para as poder garantizar que el traspaso de cdigo fuente informix a objeto java mantenga la misma coherencia sobre estos elementos que cuando se escribi. A la hora de representar fechas en java se utilizar la clase java.sql.Date o java.sql.Timestamp dependiendo del tipo de dato a almacenar. Las constantes predefinidas en java no estn condicionadas por el idioma como ocurre con los gestores de bases de datos. Su definicin se muestra en la siguiente tabla: Elemento Delimitador de cadenas o fechas Comilla doble Delimitador

214 Delimitador de decimal Formato de fecha Formato de fecha/hora Delimitador fecha Das de la semana Punto yyyy-mm-dd yyyy-mm-dd hh:mm:ss.fffffffff guin (-) 1 domingo, 2 lunes, ...., 7 sbado

Tabla 49: Formatos del lenguaje de programacin Java Los valores tipo fecha son almacenados en variables tipo java.sql.Date y la funcin esttica valueOf permite reconocer cadenas de texto con el formato: "yyyy-mm-dd" y transformarla en valores tipo Date. En este caso la cadena de caracteres de entrada ha de ser preprocesada ya que el formato original no suele cumplir este formato. Si se asocia a un campo tipo java.sql.Date un valor entero hay que tener en cuenta que una variable tipo date representa, como long, el nmero de milisegundos desde el 1 de enero de 1970 con lo cual ser preciso aplicar un valor de correccin al valor numrico que aparece en el cdigo fuente puesto que este representar el nmero de das desde el 31/12/1899. Los valores constantes tipo fecha/hora son reconocidos por la clase java.sql.Timestamp y la funcin esttica valueOf permite transformar una constate con el formato: yyyy-mm-dd hh:mm:ss.fffffffff a una variable tipo TimeStamp. Utilizando la funcin valueOf se consigue que java reconozca en variables tipo Date o Timestamp definidas en el cdigo fuente Informix-4GL y en el estudio realizado en el apartado: Mapeo de tipos de datos entre Jdbc y java se sustenta el intercambio de datos fecha y fecha/hora entre este tipo de variables Java y el gestor de base de datos. Cada da de la semana tiene asociado una constante esttica entera en la clase java.util.Calendar de tal forma que java.util.Calendar.SUNDAY es 1, java.util.Calendar.MONDAY es 2 y as sucesivamente hasta java.util.Calendar.SATURDAY vale 7. Para que esta constante tenga el mismo significado que tena en el cdigo fuente se le ha de restar el valor 1.

CONCLUSIONES Y EJEMPLO DE CONFIGURACIN


Segn lo visto en los puntos anteriores se constata que existen elementos que, en funcin del gestor de base de datos, dependen del idioma en el cual este configurado el servidor, base de datos, clientes o usuarios, y estos elementos no son los mismos para cada gestor. Por ejemplo el delimitador de cadenas de caracteres es un valor que no depende en ningn gestor de la configuracin del mismo, existen otros como el nmero asociado al da de la semana que en algunos casos si depende y en otros no, y otros valores que siempre dependen de la configuracin de idioma como es el formato de fecha. Lo que esta claro es que lo que se debe conseguir es que los formatos que se mantenan en el gestor original y por tanto en el cdigo fuente original han de ser reconocidos de forma correcta por el resto de gestores y para eso se deben de hacer los cambios oportunos por un lado en la configuracin de los gestores sobre los cuales se pretende ejecutar el cdigo generado y por otro lado se ha de generar cdigo para atender a las peculiaridades que tiene cada gestor. Supongamos que Informix, gestor original, esta configurado con el idioma Ingles y formato de fecha dd/mm/yyyy, que SqlServer esta instalado en Ingles y con el usuario de conexin en idioma Espaol y Oracle y Db2 en Espaol. Los formatos que define cada gestor se muestran en la siguiente tabla: Elementos de formato Delimitador de cadenas Delimitador de decimal Informix Comilla simple/doble Punto SqlServer Comilla simple Punto Oracle Comilla simple Punto Db2 Comilla simple Punto

215 Formato de fecha Formato fecha/hora Delimitador fecha Das de la semana dd/mm/yyyy dd/mm/yyyy dd/mm/yyyy dd/mm/yyyy

yyyy-mm-dd hh:mm:ss.ffffff slash 0 domingo, lunes, ...., sbado slash 1 1 lunes, 6 martes, ...., domingo slash 2 1 lunes, 7 martes, ....., domingo slash 2 1 domingo, 2 7 lunes, ...., 7 sbado

Tabla 50: Ejemplo de configuracin de entornos Observando la tabla vemos tres problemas: Delimitador de Cadenas de caracteres. Informix admite la comilla doble y el resto de gestores no. Esto en s no es ningn problema ya que Informix admite tambin la comilla simple con lo cual a la hora de generar cdigo objeto toda comilla doble, del cdigo fuente, ser sustituida por comilla simple. Sqlserver interpreta las fechas de forma diferente que el gestor para el cual esta escrito el cdigo fuente original. La solucin aqu es sencilla, se cambia el idioma del usuario que va a ejecutar el cdigo destino a espaol. La interpretacin de los das de la semana. SqlServer y Oracle lo hacen en funcin de la configuracin del idioma establecido para el usuario/sesin que se conecta a la base de datos; sin embargo para Informix y DB2 estos valores son siempre los mismos. As, si el Idioma es Ingles (-1), SqlServer y Oracle proporcionan como das: lunes: 2, martes: 3, mircoles: 4, jueves: 5, viernes: 6, sbado: 7, y domingo: 1. Pero si el idioma es espaol (%7) proporcionan: lunes: 1, martes: 2, mircoles: 3, jueves: 4, viernes: 5, sbado: 6, y domingo: 7. Viendo estos posibles resultados y teniendo en cuenta los que ofrece Informix lo que se ha de hacer, a la hora de traducir el cdigo fuente a cdigo objeto aplicable sobre otros gestores, es que el resultado sea el mismo que el que dara Informix en todo caso lo cual permitir que los programas originales corran sobre cualquier gestor con la mima semntica con la que fueron diseados. Para ello ser necesario por aplicar correcciones a los resultados que proporcionan el resto de gestores para lo cual ser preciso, para los casos de los gestores de bases de datos Oracle y SqlServer saber con que idioma trabaja el usuario/sesin. El idioma con que trabajan los usuarios/sesiones ser un parmetro del fichero de configuracin de la conexin, ver apartado: Error! No se encuentra el origen de la referencia. Los casos que se pueden dar son: Da de la semana en formato Ingles (1 domingo, 2 lunes, 6 viernes, 7 sbado). En este caso en la traduccin del cdigo fuente habra que, adems de cambiar la funcin a ejecutar, restarle uno para que la ejecucin de la sentencia tenga el mismo significado que cuando se diseo. Ej.: Cdigo original: select weekday(campoX) into vble from tablaY #si es domingo if vble = 0 then ..... select funciondiadelasemana ( campoX) 1 into vble from tablaY #si es domingo if vble = 0 then .....

Sentencia final:

Da de la semana en formato Espaol (1 lunes, 2 martes, 6 sbado, 7 domingo). En este caso la formula que nos pasara el resultado generado por el gestor a un valor comparable

216 con una constante, que representa el nmero de da de la semana, del cdigo fuente sera la funcin mod, como se muestra a continuacin: Cdigo original: select weekday(campoX) into vble from tablaY #si es domingo if vble = 0 then ..... select funciondiadelasemana ( campoX) mod 7 into vble from tablaY #si es domingo if vble = 0 then .....

Sentencia final:

Como ejemplo prctico para el caso de que el idioma especificado, en aquellos gestores en los que el da de la semana no es fijo, sea espaol la traduccin el cdigo fuente a objeto quedara: Cdigo original: select weekday(campoX) into vble from tablaY #si es domingo if vble = 0 then .....

Sentencia final:

SqlServer:

Oracle:

select ( datepart(gw, campoX) #si es domingo if vble = 0 then .....

% 7) from tablaY

Db2:

select mod( campoX,'D') , 7) from tablaY; #si es domingo if vble = 0 then ..... select campoX,'D') - 1 from tablaY; #si es domingo if vble = 0 then .....

Como conclusin para el manejo correcto de los das de la semana en los programas generados resultado de la traduccin de cdigo fuente Informix necesitamos saber el idioma en que esta configurado el entorno del usuario que los ejecuta sobre el gestor de bases de datos destino. En el apartado: Ejemplo de funcion weekday, del Anexo I se muestra un ejemplo del trtamiento de esta funcin para cada gestor de baeses de datos. En este ejemplo se puede ver como se garantiza que el comportamiento final es el mismo que el que tiene el cdigo original sobre Infomix. NOTA: Con estos cambios en la configuracin de los usuarios, clientes o sesiones no estamos modificando en ningn momento la representacin interna que el gestor haga de cada tipo de datos sino el formato en que este espera recibir y retorna los valores almacenados en el mismo. En este momento ya se tiene claro que si se pretende que el cdigo objeto generado pueda ser ejecutado sobre un gestor destino con la misma semntica se ha saber el idioma del usuario/sesin que ejecuta los programas. Tambin se han proporcionado unas pequeas nociones de que elementos de la configuracin local se pueden ver afectados y como modificarlos.

TRATAMIENTO DE LAS FECHAS

Las fechas son un elemento bastante complicado de tratar porque en su procesamiento intervienen bastantes elementos y cada uno de ellos con posible diferente configuracin de formatos.

217

RECONOCIMIENTO DE LAS FECHAS


El primer punto de problema es el reconocer los literales tipo fecha a la hora de procesar el cdigo fuente ya que estos como literales no dejan de ser ms que cadenas de caracteres. Para ello en el analizador lxico si se lee una cadena de caracteres se comprobar si contiene el valor de una fecha. La forma de hacerlo es basndose en el formato de fecha establecido en el entorno del cliente o el que tenga por defecto el gestor sino se fijo este. Si tenemos fijado DBDATE=DMY4/ y se lee una cadena como sigue: 20/12/2003 al tratar dicha cadena se verifica que casa con el formato establecido para las fechas y en tal caso se interpreta que es una fecha, en caso contrario ser una cadena. Para este procesamiento se utiliza la clase de Java simpleDateFormat que recibe como parmetro un formato de fecha (ver JavaDoc para mas informacin sobre los parmetros utilizados para la representacin de los distintos formatos de fecha/hora) y luego permite utilizar alguno de sus mtodos que permite verificar si realmente se cumple el formato de fecha definido, vase el siguiente ejemplo: Leemos del cdigo fuente el token: 10/12/2003 SimpleDateFormat sdate = new SimpleDateFormat(dd/mm/yyyy); // correspondiente a: DBDATE=DMY4/ tokdat = sdate.parse(token,new ParsePosition(0)); Si retorna null o da una excepcin: NullPointerException entonces no se trata de una fecha, en caso contrario si. En el caso de que lo que estemos leyendo sea un literal Informix-SQL admite que en una cadena venga embebida tenga el siguiente formato: yyyy-MM-dd HH:mm:ss.ffffff. para el reconocimiento de las constantes tipo fecha, vase el fecha/hora el tratamiento es similar. un valor datetime siempre y cuando El tratamiento es similar al utilizado ejemplo:

Leerlo del cdigo fuente el token: 2007-08-30 10:12:34.44 SimpleDateFormat sdate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); tokdat = sdate.parse(token.substring(0,token.indexOf('.')),pos); Si el resultado de esta operacin es una excepcin significa que la cadena que estamos comparando no casa con un una constante tipo fecha/hora en caso contrario si. Si para definir el literal fecha/hora se utiliza la definicin: datetime ( <valor> ) <rango> reconoce el mismo en el anlisis sintctico. se

Para reconocer valores tipo fecha con formato nmero se ha de hacer a travs del anlisis semntico. Este se ha de aplicar en las asignaciones, comparaciones, operaciones aritmticas, funciones y sentencias SQL. En el caso de variables o campos e la base de datos se reconoce que son tipo fecha durante el anlisis semntico, para ello se mantendr una tabla de smbolos que guardar en las variables y sus tipos en el momento de su declaracin y los campos asociado a su tabla en el momento de su creacin. Si se hace referencia a un campo de una tabla que no se defini en el cdigo fuente se realizar una consulta a la base de datos para determinar el tipo del mismo.

MOSTRAR VALORES
Un segundo caso se plantea cuando leemos un valor del gestor de bases de datos, por defecto se almacena en una variable tipo java.sql.Date la cual mantiene la fecha en formato JDBC que es el siguiente: 'yyyy-mm-dd'. Este formato puede no coincidir con el formato establecido en el entorno de usuario. Lo que se ha de hacer antes de mostrar el valor de la variable es convertirla al formato especificado en el entorno del usuario usando para ello la funcin: java.text.SimpleDateFormat, vase el siguiente ejemplo: Recibimos la variable: java.sql.Date.fecha y el formato a mostrar es: dd/mm/yyyy el proceso a ejecutar ser:

218 java.text.SimpleDateFormat sdate = new java.text.SimpleDateFormat(dd/MM/yyyy); System.out.println sdate.format(fecha);

INTERCAMBIO DE DATOS ENTRE JAVA Y EL GESTOR


En las sentencias de programa siempre habr un intercambio de informacin entre el programa y la base de datos, este intercambio se har a travs de variables de programa, constantes y/o funciones SQL.

VARIABLES
Su uso ms comn es cuando en el cdigo fuente Informix-4GL se define una variable de tipo DATE, se le asigna un valor y luego se utiliza en una sentencia SQL. El tipo DATE de Informix se pasar a un tipo java.sql.Date de API JDBC de Java con lo cual el formato del valor de tipo fecha que almacena dicha variable, 'yyyy-mm-dd', puede no casar con el que se haya definido para el gestor. Para entender esta necesidad de cambio de formato hay que tener un conocimiento profundo de las funciones JDBC utilizas para intercambiar informacin con los gestor de bases de datos. Estas funciones suelen recibir una cadena de caracteres con la sentencia SQL a ejecutar y en dicha cadena ya deben de ir interpretadas las variables tipo fecha de tal forma que al ser ejecutada sobre el gestor destino esta sea procesada de forma correcta, vase el ejemplo: java.Sql.Date fecha = new Date ..... ...... executeUpdate("insert into prueba1 values ( 'esto es una prueba' , "+ fecha +" , 12 ) "); Si DBDATE esta fijado a DMY4/ al ejecutar esta sentencia nos dar el error siguiente: -1204: [Informix][Informix ODBC Driver][Informix]Invalid year in date, en Sentencia: insert into prueba1 values ( 'esto es una prueba' , '2006-08-05', 12 ) Como se ve el gestor ya recibe el valor de la variable tipo fecha y como no coincide con el formato que tiene establecido da error, para evitar este error habra que hacer un cambio de formato en tiempo de ejecucin. Para convertir las fechas que se pasan al gestor a travs de las sentencias SQL hay varias formas: uno de ellos consiste en definir un mtodo basado en la clase SimpleDateFormat que se ejecute en tiempo de ejecucin y haga la conversin de formato y la otra consiste en pasarle este trabajo al driver JDBC, esta segunda forma depende del mtodo que se utilice: executeQuery o prepareStatament, vanse los siguientes ejemplos: Conversin de formato va mtodo definido por el usuario y lanzado en tiempo ejecucin: java.sql.Date fecha; executeUpdate("insert into prueba1 values ( 'esto es una prueba' , "+ convierteFecha(fecha) +" , 12 ) ");

Evidentemente el mtodo convierteFecha debe estar en una clase accesible en tiempo de ejecucin y ha de estar preparado para convertir la fecha, que recibe como parmetro, al formato que espere el gestor de bases de datos sobre el cual se ejecuta la sentencia. Si se utiliza la sentencia prepareSatatment el propio driver JDBC se encarga de hacer las conversiones de formato de fecha basndose para ello en el entorno del cliente. Ejemplo: java.sql.Date fecha; PreparedStatement x = conn.prepareStatement x.setDate(1, fecha); x.executeUpdate(); ("insert into tabla values(?)");

Una tercera posibilidad es la utilizacin de la sintaxis SQL92 embebida. JDBC soporta un formato estndar ISO para los literales tipo fecha, hora y fecha/hora y para ello usa una

219 clusula de escape que le indica al driver que debe traducir el literal a la representacin del gestor de bases de datos. Una fecha se especifica en SQL JDBC mediante la sintaxis: {d `yyyy-mm-dd'}. En esta sintaxis, yyyy es el ao, mm es el mes y dd es el da. El driver reemplazar la clusula de escape por la representacin propia equivalente del gestor de bases de datos. Por ejemplo, el driver reemplazara {d 1999-02-28} por 28-FEB-99 si este es el formato apropiado para la base subyacente. Hay clusulas de escape anlogas para TIME y TIMESTAMP que son: {t `hh:mm:ss'} {ts `yyyy-mm-dd hh:mm:ss.f . . .'} La parte fraccional de los segundos (.f . . .) del TIMESTAMP puede omitirse (es opcional). Este sistema se aplica para el uso de variables de programa JAVA dentro de sentencias SQL ya que el formato de las variables tipo fecha de JAVA utilizan el formato ISO. La forma de utilizarlos se muestra en los siguientes ejemplos: Sentencia original con tipo de datos fecha: insert into prueba1 values (esto es un prueba, fecha, 12) Sentencia generada: x.executeUpdate("insert into prueba1 values ( 'esto es una prueba' , { d " + fecha + " } , 12 ) "); Sentencia original con tipo de datos fecha/hora: insert into prueba1 values (esto es un prueba, fechah, 12) Sentencia generada: x.executeUpdate("insert into prueba1 values ( 'esto es una prueba' , { ts " + fechah + " } , 12 ) "); Cualquiera de estas tres formas es posible para trabajar con variables de programa en sentencias SQL aunque son ms trasparentes las dos ultimas debido a que se cede todo el trabajo al Driver JDBC. A lo largo de los casos mostrados en el Anexo I se han plamado ejemplos del paso de fechas desde el lenguaje de programacin al gestor de bases de datos. java.sql.Timestamp fechah; define fechah datetime year to fraction java.sql.date fecha; define fecha date

CONSTANTES
Las constantes en el cdigo fuente vienen en formato Informix y son reconocidas durante el anlisis lxico o bien a travs del anlisis semntico. En el estudio realizado en el punto: expresiones de constantes, en el cual se tienen en consideracin la configuracin local, se indican las modificaciones que es preciso realizar para traducir cdigo fuente a cdigo objeto ejecutable sobre cada gestor de bases de datos. En la tabla siguiente se muestra un resumen: Cte. Informix Fecha: 37256 Cte. SqlServer convert(datetime, 37256 cte ,103); Cte. Oracle Cte. DB2

to_date( date(37256 cte) to_char(37256 cte, 99999999999),J)

220 Fecha: 31/12/2006 31/12/2006 dateadd(dd,0, datediff(dd,0, 31/12/2006)) FechaHora: datetime (2007-12-10 12:32:40) year to fraction Fecha-Hora: 2007-1210 12:32:40 31/12/2006 to_date(to_char(31/12 /2006,'dd/mm/yyyy')) 31/12/2006 date(31/12/2006)

Convert timestamp '2007-12-10 '2007-12-10 11:21:30' (datetime,'2007-12-10 11:21:30' 11:21:30 ',121) ) Convert timestamp '2007-12-10 '2007-12-10 11:21:30' (datetime,'2007-12-10 11:21:30' 11:21:30 ',121) )

Tabla 51: Uso de constantes tipo fecha en sentencias SQL Para convertir una constante numrica que representa una fecha de Informix-4GL a otro gestor hay que tener claro: por un lado que fecha representa un valor numrico en el gestor original y en el resto de gestores y por otro lado que factor de correccin hay que aplicar al valor numrico que aparece en el cdigo fuente para que se obtenga la misma fecha en el cdigo objeto. La interpretacin que hace cada gestor de una fecha en formato numrico es: Informix. Considera el nmero de das desde el 31/12/1899. SqlServer. Interpreta el nmero como los das que van desde el 01/01/1900. Oracle. Como el nmero de das desde 1 de enero del 4712 antes de Cristo. Y Db2 como el nmero de das desde el 01/01/0001.

En la siguiente tabla se muestran ejemplos de fechas y su representacin numrica en cada uno de los gestores de bases de datos: Fecha Da siguiente: 22/10/2007 Da actual: 21/10/2007 31/12/1899 01/01/1900 02/01/1900 03/01/1900 Informix 39376 39375 0 1 2 3 SqlServer 39375 39374 -1 0 1 2 Oracle 2454396 2454395 2415020 2415021 2415022 2415023 Db2 732971 732970 693595 693596 693597 693598

Tabla 52: Valores numricos asociados a una fecha en cada gestor Observando esta tabla se puede obtener el factor de correccin que habr que aplicar para dado una constante numrica, que representa una fecha en Informix, proporcionar el valor numrico que representa la misma fecha en el resto de gestores, este es: SqlServer: -1 Oracle: 2415020 Y Db2: 693595

Denotar que esta misma traduccin de las constantes numricas se debe hace para las variables numricas que se desea sean interpretadas como fechas. Las constantes cadena que representan fechas son interpretadas directamente por el gestor destino, si el entorno tiene fijado el mismo formato de fecha, aunque es recomendable utilizar las funciones de conversin explicita de cadena a fecha que define cada gestor define, estas funciones

221 se muestran en la tabla anterior: Tabla 51: Uso de constantes tipo fecha en sentencias SQL. Durante el proceso de traduccin de cdigo fuente a objeto en la parte referente a este tipo de constantes se han tenido que superar varios problemas: Reconocerlas. Este tipo de constantes, basndonos en que Informix trabaja con un formato de fecha bien definido explcitamente (con DBDATE) o implcitamente (mm/dd/yyyy), son reconocidas en el anlisis lxico. Tratarlas. En todo punto donde Informix permite operar con una fecha en formato cadena se ha conseguido que el programa objeto resultante de la traduccin tambin lo haga: asignacin a variables de programa, paso como parmetro a funciones, operaciones aritmticas y relacionales, etc. Para esto fue preciso pasar las constantes tipo cadena a valores tipo fecha definidos por cada gestor ya que en caso contrario ciertas operaciones que Informix-SQL si admita sobre este tipo de constantes algn otro gestor no. Como ejemplo Informix-SQL permite sumar un entero a una fecha aunque esta venga embebida en una cadena: select 31/12/2001 + campo1 from prueba1; Pero esta misma sentencia falla sobre otros gestores como por ejemplo: Oracle. La solucin fue al reconocer la fecha embebida en una cadena realizar una conversin explicita: select to_date(31/12/2001, dd/mm/yyyy) + campo1 from prueba1; Superar problemas de definicin de variables. Con esto se trata de hacer notar que Informix define las variables tipo DATE y DATETIME, la primera admite valores tipo fecha que especifican desde el ao hasta el da, y la segunda admite valores tipo fecha/hora que soporta indicar desde el ao hasta microsegundos. Al hacer el paso de cdigo fuente Informix-SQL a los gestores Oracle y SqlServer el tipo DATE se asocia a: DATE Y SMALLDATETIME respectivamente, estos dos tipos de datos en el gestor destino permiten representar desde el ao hasta el segundo lo cual supone un problema a la hora de operar con ellos, vanse los siguiente ejemplos: insert into prueba1 values (1,3, today) La traduccin bsica a Oracle y Sqlserver sera: insert into prueba1 values (1,3, sysdate) y insert into prueba1 values (1,3,getdate()) Haciendo esto el valor en base de datos tendra mayor precisin para Oracle y Sqlserver que para Informix y evidentemente afectara en el resultado de otras sentencias de programa como por ejemplo: select count(*) from prueba1 where campo3 > 25/12/2007 Si today = 25/12/2007 y el programa que contenga estas sentencias se ejecuta el resultado ser diferente para el gestor de bases de datos Informix que para Oracle y Sqlserver ya que en estos ltimos casos al considerar la parte hora de la fecha y para ellos campo3 si sera mayor que la fecha. La solucin ha este caso se dio despreciando la parte hora de estos valores, as en lugar de utilizar: sysdate se utilizar: to_date(to_char(sysdate,'dd/mm/yyyy)) y para Sqlserver en lugar de utiliza: getdate() se utilizar: dateadd(dd,0, datediff(dd,0,getdate() )). Las constantes tipo fecha/hora son reconocidas durante el anlisis lxico, se deben transformar dentro del proceso de traduccin a la forma en que son reconocidas por el gestor destino, siguiendo para ello la gua que se ve en la tabla anterior: Tabla 51: Uso de constantes tipo fecha en sentencias SQL. En el Anexo I, apartadao: Ejemplo de manejo de constantes tipo fecha se muestra un caso completo del cdigo fuente y objeto generado relativo al tratamiento de constantes tipo fecha para cada uno de los gestores de bases de datos.

FUNCIONES
El pasos de valores tipo fecha, fecha/hora retornados por funciones SQL ya se ha contemplado al estudiar las mismas (apartado: Funciones sql ) y la configuracin local (ver: Configuracin local )

222 En los ejemplos indicados en el punto anterior se pueden ver casos en los que se estas funciones reciben como parmetros valores constantes tipo fecha.

CREACIN DE OBJETOS: PROPIETARIO Y ACCESO

Todos los gestores de bases de datos proporcionan alguna forma de crear los usuarios que podrn acceder a la base de datos y de asignarles unos ciertos privilegios que determinen las acciones que pueden hacer sobre las mismas. Los dos tipos ms habituales de usuarios que pueden acceder a la base de datos suelen ser: usuarios dados de alta de forma explcita en el gestor, o usuarios del sistema operativo en el cual esta instalado el mismo. En esta seccin no se pretende indicar como se crean, administran y se asignan privilegios a usuarios7 sino, partiendo de que los usuarios esta bien definidos y tienen los suficientes privilegios, determinar a que objetos tienen acceso y de que forma. Se ha de intentar garantizar que si un objeto creado, en el gestor de bases de datos Informix, por un usuario X el cual era visible para el resto de usuarios que utilizan la aplicacin, y ahora dicha aplicacin se intenta se ejecute sobre cualquier gestor de bases de datos se mantenga ese nivel de acceso a los objetos de forma transparente al usuario. Para garantizar esto se va ha hacer un estudio sobe todos los gestores determinando cuando se crea un objeto quien es el propietario del mismo y que implicaciones tiene esto a nivel de acceso y visibilidad para el resto de usuarios.

OBJETOS CREADOS EN INFORMIX


Informix-SQL no define usuarios del propio gestor de bases de datos sino que trabaja con los usuarios definidos el servidor en el cual esta instalado. El usuario administrador del gestor es: Informix y se crea durante el procedimiento de instalacin del mismo como usuario del sistema operativo (esto puede variar en funcin de la plataforma: Windows, Unix). Los objetos de la base de datos que se crean toman como propietario el usuario que esta conectado a la misma. Inicialmente el objeto puede ser accedido por el propietario y por el administrador de la base de datos. Para que el resto de usuarios tengan acceso se les ha de otorgar permisos a nivel de base de datos o tabla (ver sentencia grant/revoke). Cuando se desea acceder a una objeto de la base de datos se puede acceder de dos formas: propietario.objeto o objeto el acceso ser admitido por el gestor si el usuario que trata de ganar el acceso a la objeto tiene los suficientes privilegios. Cualquier usuario puede acceder al objeto sin indicar propietario si sobre el mismo se han otorgado permisos. A diferencia de otros gestores no se permite que el mismo nombre de objeto este creado dos veces en una base de datos aunque el usuario que intenta crearlo sea diferente, sea si el usuario X cre el objeto Y, otro usuario Z no podr crear un objeto llamado Y, si lo intenta recibir un error del gestor de base de datos En el siguiente ejemplo se intentar dejar ms claro el concepto, ejemplo: el usuario X crea el objeto O1. Para acceder al objeto O1 el usuario X y el resto, si tienen los suficientes privilegios, pude hacer: X.O1 O1.

OBJETOS CREADOS EN SQLSERVER


El gestor de bases de datos SqlServer permite trabajar con usuario de sistema operativo o definidos en el propio gestor. El usuario administrador de la base de datos es: sa. Los objetos por defecto son creados con el propietario dbo, a no ser que el usuario actual tenga permisos para crearlos (db_creator) y no sea administrador del sistema. En tal caso los objetos tendrn como propietario el usuario conectado al gestor de bases de datos que lanza la sentencia de creacin de los mismos.

Referirse a los manuales de Administracin suministrados por los proveedores de bases de datos.

223 El usuario quien crea objetos de la base de datos (tablas, ndices, vistas, triggers, etc.) se llama propietario de objetos de la base de datos. Para que un usuario pueda crear objetos ha de tener permisos de propietario de base de datos o administrador del sistema. Los usuarios creadores de objetos de la base de datos no tienen ningn identificador de usuario (login) o password especial. Cuando un creador de objetos crea uno obtiene los permisos sobre el mismo de forma implcita, pero debe de dar permisos de forma explcita a otros usuarios que necesiten acceder al objeto. Cuando un usuario accede a un objeto creado por otro, el objeto debe de ser cualificado con el nombre del propietario del mismo; de otra forma no podramos saber a que objeto se accede debido a que SqlServer admite la creacin de varios objetos con el mismo nombre siempre y cuando hayan sido creado por diferentes propietarios. Sino se cualifica el objeto con el propietario cuando se hace referencia al mismo el servidor busca el objeto siguiendo el siguiente orden: Dentro de los objetos creados por el usuario actual. Dentro de los objetos creados por el usuario dbo.

Con el siguiente ejemplo tratar de afianzarse el concepto de propietario de un objeto en SqlServer, ejemplo: Si el usuario X tiene permisos de propietarios de base de datos y no los tiene de administrador del sistema y crea la tabla T1. Todos los usuarios, excepto X, que quieran acceder a la tabla T1 deben de cualificarla con el nombre X: X.T1. Si el acceso a T1 no se cualifica con el nombre X el servidor buscar una tabla llamada T1 cuyo propietario sea el usuario actual y luego cuyo propietario sea dbo. Si ninguno de los dos usuarios: actual y dbo tienen una tabla llamada T1 se producir un error, y si la tienen se estar trabajando con una tabla que no es la creada por el usuario X. Si estamos logados en el servidor con el usuario X y creamos una tabla T1 dicha tabla se crear con el propietario X y este podr acceder a ella con el nombre T1 X.T1. Cuando el usuario tiene permisos de administradores del sistema y crea una tabla T1 esta se crea con el propietario dbo y el acceso a la misma, siguiendo la regla anterior, ser como dbo.T1 o T1 aunque se este logrado como usuario X. Si en esta circunstancia se crea la tabla como X.T1 no se podr acceder a ella a no ser que en todo caso se refiera a la misma como X.T1 ya que se intento acceder, sin indicar el propietario, como T1 se producir un error debido a que el gestor ve al usuario como dbo al tener permisos de administrador del sistema.

OBJETOS CREADOS EN DB2


Db2 Trabaja tambin con usuarios de sistema operativo. El usuario administrador del gestor es: db2admin el cual se crea como usuario de sistema operativo en el momento de la instalacin del mismo. Los objetos creados en las bases de datos toman como propietario el usuario que los creo, que ser el usuario que esta conectado a la base de datos en el momento de lanzar la sentencia de creacin. En una base de datos puede haber dos objetos con el mismo nombre aunque creados por diferente usuario. El acceso a una tabla puede ser haciendo referencia a su nombre o a su propietario y despus el nombre, sino se indica propietario intentar el acceso a la tabla que haya sido creada por l. En el caso de que se trate de acceder a una tabla, sin indicar propietario, que no haya sido creada por el usuario que trata de ganar el acceso se producir un error. A continuacin se muestra un ejemplo aclaratorio: El usuario X crea el objeto O1. Todos los usuarios de la base de datos, con suficientes privilegios, pueden acceder al objeto con la notacin: X.O1, el usuario X puede acceder como: O1 o X.O1, pero si cualquier otro usuario intenta acceder al objeto como: O1 o le dar un error ya que el objeto creado por X no es visible para l o acceder a otro objeto distinto creado por el usuario en cuestin.

OBJETOS CREADOS EN ORACLE


En Oracle se pueden definir los usuarios dentro la base de datos (gestin interna de usuarios) o como usuarios del sistema operativo. El usuario administrador de la base de datos es: system en sistemas unix o miembro de ORA_DBA en sistemas Windows.

224 A nivel de acceso y visibilidad de objetos Oracle es similar a DB2.

CONCLUSIONES
Como paso previo se ha de tener en cuenta que el estudio realizado en los puntos anteriores para cada gestor puede tener leves variaciones en funcin de la versin del gestor de bases de datos con lo cual se debe de tomar con cierta precaucin. Lo que se ha de tratar es que el acceso a las tablas sea posible sin para ello tener que modificar el cdigo que se genera. Dadas las caractersticas de Informix-SQL en el tratamiento del propietario de los objetos de la base de datos el problema se simplifica bastante. Es importante que se definan bien los permisos de acceso a la base de datos y a los objetos de la misa (ver sentencia grant). A continuacin se presentan dos de los casos ms probables que nos encontremos en los entornos donde esta la aplicacin que queremos tratar y un posible tratamiento para el problema de acceso a los objetos de la base de datos: Todos los objetos creados con el usuario X y todos los usuarios acceden a la aplicacin con el usuario X. Como la conexin se configurar para todos los gestores, indicando usuario y contrasea, se puede hacer que todos los usuarios clientes tengan el mismo fichero de configuracin con lo cual todos accedern a la aplicacin con el usuario X lo que implica que las tablas se crean siempre con dicho propietario y desde todos los clientes sern visibles todas las tablas. El acceso a cualquier tabla indicando el propietario no plantea ningn problema. Para todos los gestores se encontrar los objetos definidos bien como: X.obj obj. Todas las tablas creadas con el usuario X y todos los usuarios acceden a la aplicacin con su usuario local. Aqu al mantener cada usuario diferente se nos plantean problemas en todos los gestores de bases de datos, a excepcin de Informix, ya que por muchos permisos que demos a nivel de base de datos o tablas un usuario Y no podr ver las tablas creadas por otro usuario X a no ser que todos los accesos, en el cdigo fuente, sean: X.tabla lo cual no es muy habitual. La solucin a proponer depende de cada gestor. SqlServer. En este gestor existe una solucin sencilla que consiste en definir alias de usuarios, con esto se consigue que aunque los usuarios que se logan sean diferentes el gestor los vea todos como uno solo. De esta forma se elimina el problema de los propietarios de las tablas ya que siempre ser el mismo y estamos en primera situacin planteada. Supongamos que el usuario X es el principal y que el usuario Y cualquier otro que trabaja con la aplicacin, ambos usuarios deben de estar definidos a nivel de gestor de bases de datos, pero a nivel de la base de datos solo figurar el usuario X con privilegios de creador de base de datos. Entonces para que el/los usuario/s Y puedan trabajar con la base de datos se crea el alias como sigue: sp_addalias @loginame = 'Y', @name_in_db = 'X' A partir de este momento el usuario Y ya podr trabajar con la base de datos e internamente el gestor lo trata como X lo que implica que solo habr tablas creadas por X. Oracle. Para este gestor lo que se puede hacer para que el usuario Y pueda ver las tablas creadas por el usuario X es crear sinnimos. Ejemplo: Usuario X: create table prueba (uno smallint) El usuario X podr acceder a ella, pero el usuario Y no (a no ser que use la terminologa (propietario.tabla)

225 Si creamos un sinnimo como sigue: create synonym prueba for X.prueba desde el usuario Y (para lo cual a de tener los privilegios necesarios) a partir de este momento el usuario Y ya puede acceder a la tabla como si fuese el usuario X (sin usar el nombre de propietario) Db2. La solucin podra ser la misma que para el caso de Oracle. Estas soluciones propuestas son validas partiendo de dos hechos bastante comunes: primero las tablas siempre las suele crear un nico usuario bien administrador de la base de datos o de la aplicacin y segundo todos los usuarios tienen los suficientes permisos a nivel de base de datos. Para otras situaciones habra que estudiar cada una con detenimiento.

CONFIGURACIN DE LA CONEXIN

En la seccin anterior: Configuracin local, se indic que podra ser preciso fijar algn valor de alguna variable de entorno del servidor para que los valores constantes sean entendidos por el gestor de bases de datos. La cuestin es: como las utiliza nuestro programa en Java?, sea como le indica al servidor que una cierta variable tiene un cierto valor y, an ms, como sabe que hay una variable de entorno que tiene que notificar al servidor. La forma de hacer que el programa que se conecta a la base de datos tenga en cuenta las variables de entorno es fijando en el driver utilizado para establecer la conexin. En funcin del driver utilizado JDBC o ODBC (va JDBC) y del proveedor del mismo la forma de establecerlas ser diferente, con lo cual es necesario referirse a la informacin proporcionada por cada proveedor. Para el caso de Informix, si la conexin se establece va ODBC, es suficiente con fijar las variables de entorno va lnea de comandos aunque el proveedor proporciona entre el software cliente una herramienta que permite fijar estas variables de forma global sin tener que utilizar variables de entorno (setnet32). En el caso de que la conexin se establezca va JDBC las variables de entorno se deben establecer en la cadena de conexin. Ejemplo: Cadena de conexin bsica: jdbc:Informix-SQLi://asg:1528/datos:informixserver=ol_asg Aadir variable DBPATH: jdbc:Informix-SQLi://asg:1528/datos:informixserver=ol_asg;DBDATE=DMY4/ Estas dos formas de fijar las variables de entorno a los Drivers proporcionados por el proveedor suelen ser las ms estandarizadas (variables de entorno del sistema, variables a aadir a la cadena de conexin) con lo cual, para el caso de conexiones JDBC, ser preciso proporcionar un sistema que nos permita aadir estas variables a la cadena de conexin sin necesidad de modificar los programas generados. La forma que se utiliza es a travs de la utilizacin de un fichero de configuracin en el cual se establecen todos los parmetros necesarios para la ejecucin del programa de traduccin de cdigo y de los programas generados con l mismo (ver seccin: Error! No se encuentra el origen de la referencia.). En el caso de SqlServer el usuario de conexin determina el idioma y con este todos los elementos de configuracin local. El idioma se fija, como se indica en el punto creacin de objetos: propietario y acceso, a nivel de usuario de bases de datos. Si la conexin se establece va JDBC se entiende que es un usuario de bases de datos, pero si se establece va ODBC se debe de indicar en el DSN que la conexin se realiza con un usuario de bases de datos. En el caso de que se trabaje con Oracle estos valores se fijan en los parmetros de sesin: nls_session_parameters. Y en el caso de Db2 dependen de totalmente del idioma de la base de datos.

226

PLANIFICACIN Y PRESUPUESTO

A continuacin se muestran la lista de tareas y diagrama gantt de las tareas que comprende la realizacin de este proyecto. Las fechas aunque no son realistas, ya que se considera que no hubo discontinuidad en la elaboracin del mismo, la duracin de las tareas si es objetiva.

227 Figura 14: Lista te tareas del proyecto

Figura 15: Diagrama Gantt de tareas del proyecto En la tabla que se muestra a continuacin se plasma el coste del proyecto. Para su realizacin se han considerado dos costes:

228 Un tcnico cuyo coste hora se estima en 15 hora. Equipamiento que cubre equipo, software, costes variables, etc. que se estima en 1 hora.

Nombre de tarea 1 Definicin del Proyecto 2 Recopilacin de Informacin 4 Creacin del Analizador lxico 5 Creacin del Analizador sintctico 6 Aadir semntica, tabla de smbolos y gestin de errores 7 Desarrollo mdulos generadores de cdigo 9 Estudio sentencias SQL de distintos gestores 10 Incorporacin de sentencias al generador de cdigo 11 Pruebas 12 Customizacin Total
Tabla 53: Coste del proyecto

Costo total 1.272,00 3.840,00 1.280,00 15.360,00 3.840,00 7.680,00 7.680,00 5.120,00 3.840,00 11.520,00 61.432,00

Coste Satisfecho 1.272,00 3.840,00 1.280,00 15.360,00 3.840,00 7.680,00 7.680,00 5.120,00 3.840,00 0 49.912,00

Coste Restante 0 0 0 0 0 0 0 0 0 11.520,00 11.520,00

229

MANUAL DE USUARIO

El uso del traductor es muy sencillo, para su utilizacin es suficiente con lanzar la ejecucin de un programa desde lnea de comandos con una serie de parmetros y como resultado de la ejecucin del mismo se genera el cdigo objeto deseado. An as es preciso tener preparado el entorno y el software preciso instalado. Tambin se proporcionan una serie de scripts que facilitan an ms el uso. El manual de usuario se estructurar en las siguientes partes: Requisitos hardware Requisitos software Configuracin Ejecucin

REQUISITOS HARDWARE
El hardware mnimo necesario para ejecutar el traductor es: Equipo P III 1 GHZ. 256 Mb. de memoria RAM. 10 GB. de disco duro.

Esta ha sido la plataforma mnima con la que se ha probado el traductor con resultados satisfactorios. Evidentemente y teniendo en cuenta que el/los gestores de bases de datos pueden estar instalados en la misma maquina se recomienda un sistema con mejores prestaciones.

REQUISITOS SOFTWARE
Los requisitos software han de abarcar varios mbitos: Sistema operativo Gestores de bases de datos JAVA y JDBC

REQUISITOS DE SISTEMA OPERATIVO


El sistema operativo sobre el cual se ejecuta el traductor, al estar este desarrollado en JAVA, tiene muy pocas limitaciones pudiendo ser: Windows: 98, NT, Me, XP, W2000, w2003, o superior. Linux: RedHat, Suse, Ubuntu, etc. Unix: SCO, Solaris, HP-UX, etc.

La nica limitacin que ha de cumplir el sistema operativo es que soporte la versin JDK de JAVA requerida.

REQUISITOS DE LOS GESTORES DE BASES DE DATOS


Los gestores de bases de datos soportados y sus versiones mnimas requeridas son: Informix visin 4.10 o superior. SqlServer versin 2005 o superior. Oracle versin 9i o superior.

230 Db2 versin 8 o superior.

Cada gestor de bases de datos puede requerir alguna configuracin especial, sobre todo en la parte correspondiente a usuarios y configuracin local. Las configuraciones mnimas necesarias son comentadas en los puntos adecuados dentro del anlisis de las sentencias SQL.

REQUISITOS DE JAVA Y API JDBC


En el equipo donde se ejecute el traductor ha de haber instalada una versin del JRE de JAVA versin 1.3 o superior. Se recomienda instalar el JDK para as poder probar los programas generados por el traductor. En cuanto a los Drivers de conexin con la base de datos, al poder ser esta va JDBC o ODBC sobre JDBC, podrn ser: Si la conexin es va ODBC: Instalar el cliente de conexin con la bases de datos. Este software viene con el propio software de instalacin del gestor de bases de datos y su versin ser acorde con el mismo. Si la conexin es va JDBC se requieran los Drivers estndares proporcionados por el proveedor del gestor de bases de datos en funcin de la versin del mismo.

CONFIGURACIN
Una vez instalados los componentes software necesarios se ha de configurar el entorno de trabajo y crear el fichero de configuracin utilizado por el traductor.

ENTORNO DE TRABAJO
El entorno de trabajo ha de tener definidos los siguientes elementos: Fijar variables de entorno: CLASSPATH. Indicando en la misma el directorio base de instalacin de JDK, directorio base de las API JDBC necesarias, directorio base las clases y packages pertenecientes al traductor, y directorio base de los fuentes generados (si se desean probar estos). FUENTES. Indica el camino donde se encuentras los .class del traductor y los ficheros de configuracin necesarios para su correcto funcionamiento. PATH. Aadir al PATH el camino al directorio bin dentro del JDK de JAVA y el valor de la variable de entorno FUENTES.

Ubicar los programas fuentes. La ubicacin de los programas fuente utilizados no tiene mayor importancia siempre y cuando las variables de entorno estn bien fijadas. El traductor entiende que los programas fuente estn en el directorio desde el cual se laza la ejecucin del mismo. Ubicacin de mdulos objeto generados. Por defecto del traductor genera los programas objeto en el directorio desde el cual se lanza su ejecucin.

FICHERO DE CONFIGURACIN
Para que se pueda lanzar la ejecucin del traductor es preciso tener definidos una serie de parmetros. Estos parmetros proporcionan independencia al traductor respecto a la plataforma desde la cual se utilice, sobre que gestor de bases de datos vaya a trabajar, y adems de fija una serie de valores que determinan su comportamiento. Este fichero se llama: conexion.cfg, y consta de una serie de campos separados por una barra vertical (|). Aunque tiene una estructura prefijada no tienen porque tomar valor todos los campos definidos ya que estos dependern del tipo de conexin a establecer y el gestor destino. El fichero de configuracin consta de los siguientes elementos: Tipo de conexin a la base de datos. Indica, con un valor numrico, contra que tipo de base datos se ejecutar el programa. Estos valores numricos se definen en el fichero de constantes SQL: GlobalSql.java y puede tomar los valores:
NO_BD = -1

231
BD_ODBC = BD_Oracle = BD_Informix = BD_InformixOL = BD_InformixSE = BD_Sybase = BD_Sqlserver = BD_Db2 = BD_Ingres = BD_Mysql = 0 1 2 3 9 4 5 6 7 8

Destacar que si toma el valor 0 indicar que se trata de una conexin ODBC sobre JDBC. DBdriver. Es el driver de conexin JDBC contra el gestor de base de datos, puede tomar los valores: Para conexiones ODBC: sun.jdbc.odbc.JdbcOdbcDriver Para Informix: com.informix.jdbc.IfxDriver Para SqlServer: com.microsoft.sqlserver.jdbc.SQLServerDriver Para Oracle: oracle.jdbc.driver.OracleDriver Para Db2: com.ibm.db2.jcc.DB2Drive

Estos valores se obtienen de la informacin proporcionada por el proveedor del driver JDBC. Driver. Contiene la URL de conexin con la base de datos, este valor depender de cada Driver JDBC. Para los Drivers considerados en este estudio los valores usados son: Informix: SqlServer: Oracle: Db2: jdbc:Informix-SQLi jdbc:sqlserver: jdbc:oracle:thin:@ jdbc:db2:

Si se usa una Driver ODBC sobre JDBC en este campo se indica el nombre del controlador ODBC, ejemplos: {INFORMIX 3.32 32 BIT} {SQL Server} {Oracle ODBC Driver} {IBM DB2 ODBC DRIVER}

Origen ODBC. Este campo solo se rellenar si se ha especificado una conexin va ODBC y contendr el nombre del origen ODBC indicado en el origen de datos dentro del Administrador de orgenes de datos ODBC. Path. Indica el camino completo de la base de datos. Solo se utiliza este campo en el caso de que estemos trabajando contra un gestor de bases de datos Informix-SE (Standard Engine). Base de datos. Es el nombre de la base de datos. Host: contiene la IP de la maquina donde esta instalado el gestor de bases de datos o el nombre en el caso de que este sea resuelto va hosts, dns, etc. Puerto: es el puerto en el que esta escuchando el servicio del servidor de bases de datos. Informixserver. Campo que indica el nombre de la instancia del servidor. Solo se utiliza en gestores de bases de datos Informix. Usuario. Indica el usuario de conexin a la base de datos.

232 Password. Es la password del usuario de conexin a la base de datos. Generacin de cdigo. ste campo es utilizado, durante el proceso de traduccin, para indicar para que gestor de bases de datos se esta haciendo la traduccin de cdigo fuente a cdigo objeto. Puede tomar los mismos valores que el campo: Tipo de conexin a la base de datos, explicado anteriormente. Idioma SGDB destino. Especifica el idioma del gestor de bases de datos destino, puede tomar los valores: E: espaol, U: americano (USA), A: ANSI, G: Alemn, I: Italiano. Este dato se utiliza, entre otras cosas, para calcular el nmero asociado al da de la semana y el formato de fecha en aquellas funciones de casting explicito en las que es preciso indicar el formato. Esta definicin del idioma no va en ningn caso sustituir las necesidades de configuracin local que sea preciso realizar, simplemente son un complemento necesario para garantizar que ciertas operaciones se puedan llevar a cabo correctamente. Un caso claro de la utilidad de este campo es en el procesamiento de las constantes tipo fecha por los gestores de bases de datos SqlServer y Oracle, sino se indica en que formato viene la cadena a convertir pueden no ser bien interpretada. Ejemplos de cmo aplicarla: to_date(31/12/2007,dd/mm/yyyy); convert(datetime,31/12/2007,103); Para el valor asociado al da de la semana solo se contemplan los idiomas espaol y americano. Para el formato de fecha se contemplan todos los indicados. El formato de fecha en funcin de cada uno se muestra en la siguiente tabla: Cdigo de idioma E U A G I Formato Informix DMY4/ dd/mm/yyyy MDY4/ mm/dd/yyyy Y4MD. yyyy.mm.dd DMY4. dd.mm.yyyy DMY4- dd-mm-yyyy Formato Oracle y Db2 dd/mm/yyyy mm/dd/yyyy yyyy.mm.dd dd.mm.yyyy dd-mm-yyyy Formato SqlServer 103 101 102 104 105

Tabla 54: Formato de fecha en funcin del idioma establecido Utilizando esta variable de idioma tambin se fijar el formato de fecha que reconoce JAVA. Para JAVA el formato ser igual que para Informix solo que sustituyendo el mm por MM (ver clase SimpleDateFormat). Variables de entorno: Permite especificar variables de entorno que se fijarn en la cadena de conexin a la base de datos. Generacin de cdigo. Indica si el cdigo generado por el traductor proporcionar un interface grafico o no.

Seguidamente se muestras varios ejemplos de fichero de configuracin. El primer caso es un fichero de configuracin utilizado para generar cdigo objeto que pueda ser lanzado contra el gestor de bases de datos Oracle, el tipo de conexin es JDBC, y no se genera un interface grafico. 1| oracle.jdbc.driver.OracleDriver| jdbc:oracle:thin:@| | | datos| asg| 1521| #Tipo conexion a la base de datos #DBdriver #Driver #Origen ODBC (opcional) #path (opcional) #Base de datos #Host #Puerto

233 | informix| informix| 1| E| | 0| #Informixserver (opcional) #Usuario #Passwd #Generacin de codigo #Idioma #Vbles entorno #Modo grafico o no

En este segundo caso el cdigo objeto generado se podr ejecutar sobre un gestor de bases de datos Informix, la conexin a establecer es tipo JDBC y se proporcionar un interface grafico estilo Windows. 0| sun.jdbc.odbc.JdbcOdbcDriver| {INFORMIX 3.32 32 BIT}| ifxdatos| | datos| asg| 1528| | informix| informix| 2| E| | 1| #Tipo conexion a la base de datos #DBdriver #Driver #Origen ODBC (opcional) #path (opcional) #Base de datos #Host #Puerto #Informixserver (opcional) #Usuario #Passwd #Generacin de codigo #Idiosma #Entorno #Modo grafico o no

EJECUCIN DEL TRADUCTOR


EL traductor se ejecuta desde lnea de comando, previa carga de las variables de entorno precisas. En funcin de si se est traduciendo un programa multimdulo o monomdulo se lanzar uno u otro programa.

TRADUCCIN DE PROGRAMAS MONOMDULO


Para traducir un programa monomdulo se ejecutar: java ASGprog <fuente> [ traza ] El fichero fuente puede ir con o sin extensin. Si como segundo parmetro se pone el valor numrico 1 se generar un fichero de traza. Este fichero se llamar igual al nombre del fichero fuente con la extensin .log, y guardar todas las producciones por la que pasa el traductor en su proceso de traduccin. En caso de el programa fuente tenga algn error, lo cual no se debera de dar, el fichero de traza se generara de forma automtica. Como resultado de la ejecucin del traductor se genera un fichero objeto que se llama igual que el fichero fuente pero con la extensin .java.

TRADUCCIN DE PROGRAMAS MONOMDULO


En el caso de que el programa conste de varios mdulos ser preciso disponer de un fichero makefile nombrado como: ASGmakefile en el cual se definan los mdulos que constituyen el programa. El fichero ASGmakefile se deduce fcilmente del fichero makefile original de Informix-4GL. En l se pueden definir ms de un programa multimdulo y tendr la siguiente estrucura:
NombreMduloPrincipal = Mdulo1.4gl Mdulo2.4gl Mdulo3.4gl

234
MduloN.4gl exe: NombreMduloPrincipal NombreOtroMduloPrincipal = OtroMdulo1.4gl OtroMdulo2.4gl OtroMdulo3.4gl OtroMduloN.4gl exe: NombreMduloOtroPrincipal

Para lanzar la traduccin de un programa mutimdulo se ejecuta: java ASGmake NombreMduloPrincipal [ parmetros opcionales ] El fichero ASGmakefile del cual se obtiene la informacin para realizar el proceso de traduccin debe de estar en el mismo directorio que los mdulos que constituyen el programa multimdulo. Como parmetros opcionales puede recibir los nmeros: 1 2 Indica que se genere archivo de traza para cada mdulo. Fuerza la re-traduccin de todos los mdulos. El comportamiento normal del programa ASGmake es que si un el mdulo objeto es ms reciente que el mdulo fuente ste no se re-traduce. Indica se genere archivo de traza y se re-traduzcan todos los mdulos del programa.

Como resultado de la ejecucin del programa se generaran un mdulo objeto por cada uno de los mdulos fuente que constituyen el programa y en ocasiones un mdulo adicional que contendr variables globales accesibles desde cualquiera de los mdulos objeto.

VERIFICACIN DE FUNCIONAMIENTO
La forma ms sencilla para verificar el correcto comportamiento del traductor es ejecutar los programas generados. En ocasiones durante el proceso de traduccin se lanzaran avisos que pueden sugerir revisar el cdigo objeto generado. Si se trata de un programa monomdulo la comprobacin consistir en: Compilar el cdigo objeto generado javac codigo_objeto.java java codigo_objeto Ejecutar el resultado de la compilacin anterior

Si se trata de un programa multimdulo la comprobacin ser la misma pero aplicando los dos pasos anteriores sobre el mdulo principal ya que el JAVA compilar todos aquellos mdulos que precise de forma automtica.

ANEXO I: FUENTES
database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2), campo11 smallint , campo21 char(10) , campo31 decimal(4,2) )

EJEMPLO SENTENCIA ALTER TABLE


CDIGO FUENTE INFORMIX-4GL: ALTERTABLE.4GL

alter index indice1 to not cluster alter table tabla1 modify(campo2 int unique ) alter table tabla1 modify(campo1 int not null unique constraint constr1, campo21 decimal(5,0), campo3 char ), add(campo4 int not null distinct constraint constr2, campo5 decimal(5,2) distinct constraint constr3 ), drop(campo11,campo21,campo31), add constraint unique (campo1,campo2,campo3), add constraint unique (campo1,campo2) constraint constr4 alter table tabla1 drop constraint (constr2,constr4) alter table informix.tabla1 modify(campo1 int) alter table "informix".tabla1 modify(campo1 int) end main

CDIGO OBEJTO: ALTERTABLE.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class altertable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo2 integer unique ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer not null unique constraint constr1 ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo21 decimal(5,0) ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo3 char(1) ) "); ASGcondb.exeUpdate("alter table tabla1 add ( campo4 integer not null unique constraint constr2 ) "); ASGcondb.exeUpdate("alter table tabla1 add ( campo5 decimal(5,2) unique constraint constr3 ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo11 ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo21 ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo31 ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint unique ( campo1 , campo2 , campo3 ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint unique ( campo1 , campo2 ) constraint constr4 "); ASGcondb.exeUpdate("alter table tabla1 drop constraint ( constr2 ) "); ASGcondb.exeUpdate("alter table tabla1 drop constraint ( constr4 ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer ) "); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class altertable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos");

ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("alter table tabla1 alter column campo2 integer "); ASGcondb.exeUpdate("alter table tabla1 add unique (campo2)"); ASGcondb.exeUpdate("alter table tabla1 alter column campo1 integer not null "); ASGcondb.exeUpdate("alter table tabla1 add constraint constr1 unique (campo1)"); ASGcondb.exeUpdate("alter table tabla1 alter column campo21 decimal(5,0) "); ASGcondb.exeUpdate("alter table tabla1 alter column campo3 char(1) "); ASGcondb.exeUpdate("alter table tabla1 add campo4 integer not null constraint constr2 unique "); ASGcondb.exeUpdate("alter table tabla1 add campo5 decimal(5,2) constraint constr3 unique "); ASGcondb.exeUpdate("alter table tabla1 drop column campo11 "); ASGcondb.exeUpdate("alter table tabla1 drop column campo21 "); ASGcondb.exeUpdate("alter table tabla1 drop column campo31 "); ASGcondb.exeUpdate("alter table tabla1 add unique ( campo1 , campo2 , campo3 ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint constr4 unique ( campo1 , campo2 ) "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr2 "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr4 "); ASGcondb.exeUpdate("alter table tabla1 alter column campo1 integer "); ASGcondb.exeUpdate("alter table tabla1 alter column campo1 integer "); } }

236

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class altertable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo2 integer ) "); ASGcondb.exeUpdate("alter table tabla1 add unique (campo2)"); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer not null ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint constr1 unique (campo1)"); ASGcondb.exeUpdate("alter table tabla1 modify ( campo21 decimal(5,0) ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo3 char(1) ) "); ASGcondb.exeUpdate("alter table tabla1 add ( campo4 integer not null constraint constr2 unique ) "); ASGcondb.exeUpdate("alter table tabla1 add ( campo5 decimal(5,2) constraint constr3 unique ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo11 ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo21 ) "); ASGcondb.exeUpdate("alter table tabla1 drop ( campo31 ) "); ASGcondb.exeUpdate("alter table tabla1 add unique ( campo1 , campo2 , campo3 ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint constr4 unique ( campo1 , campo2 ) "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr2 "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr4 "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer ) "); ASGcondb.exeUpdate("alter table tabla1 modify ( campo1 integer ) "); } }

CODIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class altertable1 { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 varchar(10) not null , campo3 decimal(4,2) not null , campo11 smallint ) "); ASGcondb.exeUpdate("alter table tabla1 alter column campo2 set data type varchar(12) "); ASGcondb.exeUpdate("alter table tabla1 add campo4 integer not null default constraint constr2 unique "); ASGcondb.exeUpdate("alter table tabla1 add campo5 decimal(5,2) constraint constr3 unique not null default "); ASGcondb.exeUpdate("alter table tabla1 add unique ( campo1 , campo3 ) "); ASGcondb.exeUpdate("alter table tabla1 add constraint constr4 unique ( campo1 , campo2 ) "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr2 "); ASGcondb.exeUpdate("alter table tabla1 drop constraint constr4 "); ASGcondb.exeUpdate("alter table tabla1 alter column campo2 set data type char(12) ");

} }

ASGcondb.exeUpdate("alter table tabla1 add unique (campo2)"); ASGcondb.exeUpdate("alter table tabla1 add unique ( campo11 ) ");

237

EJEMPLO SENTENCIAS CONEXIN/DESCONEXIN


CDIGO FUENTE INFORMIX-4GL: CONNECTDB.4GL
database datos main whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 integer ) close database connect to datos2 whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(4,2) , campo4 decimal(2,0), campo5 int ) close database end main

CDIGO OBEJTO: CONNECTDB.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class connectdb { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 integer ) "); ASGcondb.finConexionDB(); ASGcondb.iniConexionDB("datos2"); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo4 decimal(2,0) , campo5 integer ) "); ASGcondb.finConexionDB(); } }

EJEMPLO SENTENCIAS DE TRATAMIENTO DE TRANSACCIONES


CDIGO FUENTE INFORMIX-4GL: TRANSAC.4GL
database datos main define cuenta smallint whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 varchar(10) not null, campo3 char(50), campo4 decimal(5,2) ) select count(*) into cuenta from tabla1 message "Nmero de filas: ", cuenta begin work insert into tabla1 values(1,"1","2",2) commit work select count(*) into cuenta from tabla1

message "Nmero de filas: ", cuenta begin work insert into tabla1 values(2,"2","3",3) rollback work select count(*) into cuenta from tabla1 message "Nmero de filas: ", cuenta begin work alter table tabla1 modify(campo2 varchar(12)) rollback work end main

238

CDIGO OBJETO: TRANSAC.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class TRANSAC { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int cuenta ; cuenta = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 varchar(10) not null , campo3 char(50) , campo4 decimal(5,2) ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select count ( * ) from tabla1 "); try { ASG_r1.next(); cuenta = ASG_r1.getInt(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Nmero de filas: " + cuenta ); ASGcondb.inicioTransac(); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , '2' , 2 ) "); ASGcondb.finTransacOK(); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select count ( * ) from tabla1 "); try { ASG_r2.next(); cuenta = ASG_r2.getInt(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Nmero de filas: " + cuenta ); ASGcondb.inicioTransac(); ASGcondb.exeUpdate("insert into tabla1 values ( 2 , '2' , '3' , 3 ) "); ASGcondb.finTransacKO(); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( * ) from tabla1 "); try { ASG_r3.next(); cuenta = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Nmero de filas: " + cuenta ); ASGcondb.inicioTransac(); ASGcondb.exeUpdate("alter table tabla1 modify ( campo2 varchar(12) ) "); ASGcondb.finTransacKO(); } }

EJEMPLO SENTENCIA CREACION INDICE


CDIGO FUENTE INFORMIX-4GL: CREATEINDEX.4GL
database datos main whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(4,2) ) create distinct cluster index indice1 on tabla1 (campo1 ASC, campo2 DESC) close database end main

CDIGO OBJETO: CREATEINDEX.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

239

public class createindex { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create unique index indice1 on tabla1 ( campo1 asc , campo2 desc ) "); ASGcondb.finConexionDB(); } }

EJEMPLO SENTENCIA CREACION DE SINONIMOS


CDIGO FUENTE INFORMIX-4GL: SINONIMO.4GL
main define uno,tres integer, dos char(10) whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 integer ) insert into tabla1 values (1,"1",1)

create synonym sinonimo1 for tabla1 insert into sinonimo1 values (2,"2",2) select * into uno,dos,tres from sinonimo1 where campo1 = 1 message "valores fila 1: ",uno," ",dos," ",tres select * into uno,dos,tres from sinonimo1 where campo1 = 2 message "valores fila 2: ",uno," ",dos," ",tres drop table tabla1 select * into uno,dos,tres from sinonimo1 where campo1 = 2 message "valores fila 2: ",uno," ",dos," ",tres end main

CDIGO OBJETO: SINONIMO.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class sinonimo { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , tres ; String dos ; uno = 0; tres = 0; dos = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 integer ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.exeUpdate("insert into sinonimo1 values ( 2 , '2' , 2 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from sinonimo1 where campo1 = 1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getString(2); tres = ASG_r1.getInt(3); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close();

} }

System.out.println("valores fila 1: " + uno + " " + dos + " " + tres Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from sinonimo1 where try { ASG_r2.next(); uno = ASG_r2.getInt(1); dos = ASG_r2.getString(2); tres = ASG_r2.getInt(3); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ASGcondb.exeUpdate("drop table tabla1 "); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select * from sinonimo1 where try { ASG_r3.next(); uno = ASG_r3.getInt(1); dos = ASG_r3.getString(2); tres = ASG_r3.getInt(3); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres

); campo1 = 2 ");

240

); campo1 = 2 ");

);

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class sinonimo { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , tres ; String dos ; uno = 0; tres = 0; dos = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 integer ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.exeUpdate("insert into sinonimo1 values ( 2 , '2' , 2 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from sinonimo1 where campo1 = 1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getString(2); tres = ASG_r1.getInt(3); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("valores fila 1: " + uno + " " + dos + " " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from sinonimo1 where campo1 = 2 "); try { ASG_r2.next(); uno = ASG_r2.getInt(1); dos = ASG_r2.getString(2); tres = ASG_r2.getInt(3); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ); ASGcondb.exeUpdate("drop table tabla1 "); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select * from sinonimo1 where campo1 = 2 "); try { ASG_r3.next(); uno = ASG_r3.getInt(1); dos = ASG_r3.getString(2); tres = ASG_r3.getInt(3); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ); } }

CDIGO OBJETO ORACLE


import java.sql.*;

import ASGdb.*; import ASGdbutil.*; import ASGutil.*; public class sinonimo { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , tres ; String dos ; uno = 0; tres = 0; dos = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 integer ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop public synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create public synonym sinonimo1 for tabla1 "); ASGcondb.exeUpdate("insert into sinonimo1 values ( 2 , '2' , 2 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from sinonimo1 where campo1 = 1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getString(2); tres = ASG_r1.getInt(3); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("valores fila 1: " + uno + " " + dos + " " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from sinonimo1 where campo1 = 2 "); try { ASG_r2.next(); uno = ASG_r2.getInt(1); dos = ASG_r2.getString(2); tres = ASG_r2.getInt(3); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select * from sinonimo1 where campo1 = 2 "); try { ASG_r3.next(); uno = ASG_r3.getInt(1); dos = ASG_r3.getString(2); tres = ASG_r3.getInt(3); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ); } }

241

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class sinonimo { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , tres ; String dos ; uno = 0; tres = 0; dos = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 integer ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop alias sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.exeUpdate("insert into sinonimo1 values ( 2 , '2' , 2 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from sinonimo1 where campo1 = 1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getString(2); tres = ASG_r1.getInt(3);

} }

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("valores fila 1: " + uno + " " + dos + " " + tres Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from sinonimo1 where try { ASG_r2.next(); uno = ASG_r2.getInt(1); dos = ASG_r2.getString(2); tres = ASG_r2.getInt(3); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres ASGcondb.exeUpdate("drop table tabla1 "); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select * from sinonimo1 where try { ASG_r3.next(); uno = ASG_r3.getInt(1); dos = ASG_r3.getString(2); tres = ASG_r3.getInt(3); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("valores fila 2: " + uno + " " + dos + " " + tres

242

); campo1 = 2 ");

); campo1 = 2 ");

);

EJEMPLO SENTENCIA CREACION DE TABLA


CDIGO FUENTE INFORMIX-4GL: CREATETABLE.4GL
database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint not null, campo2 char(10) unique, distinct (campo1) constraint constr1, campo3 decimal(4,2) distinct constraint constr2, unique (campo1,campo3) constraint constr3, campo4 decimal(2,0) not null, distinct (campo4), campo5 int, campo6 date, campo7 datetime hour to minute ) close database end main

CDIGO OBJETO: CREATETABLE.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createtable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , unique ( campo1 ) constraint constr1 , campo3 decimal(4,2) unique constraint constr2 , unique ( campo1 , campo3 ) constraint constr3 , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 datetime hour to minute ) "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO SQLSERVER


import java.sql.*; import ASGdb.*; import ASGdbutil.*;

import ASGutil.*; public class createtable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 datetime , campo7 datetime ) "); ASGcondb.finConexionDB(); } }

243

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createtable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createtable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) not null unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique not null default , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.finConexionDB(); } }

EJEMPLO SENTENCIAS CREACION TABLA TEMPORAL


CDIGO FUENTE INFORMIX-4GL: CREATETTABLE.4GL
database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 whenever error stop create temp table tabla1 ( campo1 smallint not null, campo2 char(10) unique, distinct (campo1) , campo3 decimal(4,2) distinct,

unique (campo1,campo3), campo4 decimal(2,0) not null, distinct (campo4), campo5 int, campo6 date, campo7 datetime hour to minute

244

close database end main

CDIGO OBJETO: CREATETTABLE.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createttable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create temp table tabla1 ( campo1 smallint not null , campo2 char(10) unique , unique ( campo1 ) , campo3 decimal(4,2) unique , unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 datetime hour to minute ) "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createttable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table #tabla1 ( campo1 smallint not null , campo2 char(10) unique , unique ( campo1 ) , campo3 decimal(4,2) unique , unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 datetime , campo7 datetime ) "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createttable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create global temporary table tabla1 ( campo1 smallint not null , campo2 char(10) unique , unique ( campo1 ) , campo3 decimal(4,2) unique , unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.finConexionDB(); }

245

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createttable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("declare global temporary table tabla1 ( campo1 smallint not null , campo2 char(10) decimal(4,2) , campo4 decimal(2,0) not null , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.finConexionDB(); } }

, campo3

EJEMPLO SENTENCIA CREACION VISTA


CDIGO FUENTE INFORMIX-4GL: CREATEVIEW.4GL
database datos main define uno,dos integer whenever error continue drop table tabla1 drop table tabla2 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(4,2) ) create table tabla2 ( campo1 int, campo2 char(10), campo3 smallint ) insert into tabla1 values(1,"1",1.0) insert into tabla2 values(2,"2",2) create view vista1 (vcampo1,vcampo2) as select t.campo1, p.campo1 from tabla1 t, tabla2 p select * into uno,dos from vista1 message "campos de la vista: ",uno," end main ", dos

CDIGO OBJETO: CREATEVIEW.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createview { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , dos ; dos = 0; uno = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 integer , campo2 char(10) , campo3 smallint ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.exeUpdate("insert into tabla2 values ( 2 , '2' , 2 ) "); ASGcondb.exeUpdate("create view vista1 ( vcampo1 , vcampo2 ) as select t.campo1 , p.campo1 from tabla1 t , tabla2 p "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from vista1 "); try { ASG_r1.next();

} }

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campos de la vista: " + uno + "

uno = ASG_r1.getInt(1); dos = ASG_r1.getInt(2);

246

" + dos );

CDIGO OBJETO SQLSERVER/DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createview { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , dos ; dos = 0; uno = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 integer , campo2 char(10) , campo3 smallint ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.exeUpdate("insert into tabla2 values ( 2 , '2' , 2 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 ( vcampo1 , vcampo2 ) as select t.campo1 , p.campo1 from tabla1 t , tabla2 p "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from vista1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getInt(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campos de la vista: " + uno + " " + dos ); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class createview { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno , dos ; dos = 0; uno = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.exeUpdate("drop table tabla2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 integer , campo2 char(10) , campo3 smallint ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , '1' , 1 ) "); ASGcondb.exeUpdate("insert into tabla2 values ( 2 , '2' , 2 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 ( vcampo1 , vcampo2 ) as select t.campo1 , p.campo1 from tabla1 t , tabla2 p "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select * from vista1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); dos = ASG_r1.getInt(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campos de la vista: " + uno + " " + dos ); } }

EJEMPLO SENTENCIA DELETE


CDIGO FUENTE INFORMIX-4GL: DELETE.4GL
database datos main define uno integer whenever error stop drop table tabla1 whenever error continue create table tabla1 ( campo1 smallint, campo2 smallint ) insert insert insert insert into into into into tabla1 tabla1 tabla1 tabla1 values values values values (1,1) (2,2) (3,3) (4,4)

247

create view vista1 (vcampo1,vcampo2) as select * from tabla1 create synonym sinonimo1 for tabla1 select count(*) into uno from vista1 message "Nmero de filas: ", uno delete from vista1 where vcampo1 = 1 select count(*) into uno from sinonimo1 message "Nmero de filas: ", uno delete from sinonimo1 where campo1 = 2 select count(*) into uno from tabla1 message "Nmero de filas: ", uno delete from sinonimo1 where campo1 = 3 select count(*) into uno from tabla1 message "Nmero de filas: ", uno end main

CDIGO OBJETO: DELETE.JAVA


Aunque los cdigos objeto, del ejemplo, no son iguales en funcin del gestor de bases de datos destino la diferencia viene marcada por sentencias adicionales a la que se trata de ejemplificar.
import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class delete { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int uno ; uno = 0; ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.activaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 smallint ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , 1 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 2 , 2 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 3 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 4 , 4 ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 ( vcampo1 , vcampo2 ) as select * from tabla1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop public synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create public synonym sinonimo1 for tabla1 "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select count ( * ) from vista1 "); try { ASG_r1.next(); uno = ASG_r1.getInt(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Nmero de filas: " + uno ); ASGcondb.exeUpdate("delete from vista1 where vcampo1 = 1 "); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select count ( * ) from sinonimo1 "); try { ASG_r2.next(); uno = ASG_r2.getInt(1); }

} }

catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Nmero de filas: " + uno ); ASGcondb.exeUpdate("delete from sinonimo1 where campo1 Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( try { ASG_r3.next(); uno = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Nmero de filas: " + uno ); ASGcondb.exeUpdate("delete from sinonimo1 where campo1 Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( try { ASG_r4.next(); uno = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("Nmero de filas: " + uno );

248

= 2 * )

"); from tabla1 ");

= 3 * )

"); from tabla1 ");

EJEMPLO SENTENCIA DROP INDEX


CDIGO FUENTE INFORMIX-4GL: DROPINDEX.4GL
database datos main whenever error continue drop table tabla1 drop table tabla2 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(4,2) ) create table tabla2 ( campo1 smallint ) create distinct cluster index indice1 on tabla1 (campo1 ASC, campo2 DESC) create index indice2 on tabla1 (campo1) drop index indice2 close database end main

CDIGO OBJETO: DROPINDEX.JAVA CDIGO OBJETO INFORMIX/ORACLE/DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class dropindex { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.exeUpdate("create unique index indice1 on tabla1 ( campo1 asc , campo2 desc ) "); ASGcondb.exeUpdate("create index indice2 on tabla1 ( campo1 asc ) "); ASGcondb.exeUpdate("drop index indice2 "); ASGcondb.finConexionDB(); } }

CODIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class dropindex {

private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.exeUpdate("create unique index indice1 on tabla1 ( campo1 asc , campo2 desc ) "); ASGcondb.exeUpdate("create index indice2 on tabla1 ( campo1 asc ) "); ASGcondb.exeUpdate("drop index "+ASGfaux.tablaindice(ASGcondb,"indice2")+""); ASGcondb.finConexionDB(); } }

249

EJEMPLO SENTENCIA DROP OBJETO


CDIGO FUENTE INFORMIX-4GL: DROPALL.4GL
database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 drop table tabla2 whenever error stop create table tabla1 ( campo1 smallint not null, campo2 char(10) unique, distinct (campo1) constraint constr1, #campo3 decimal(4,2) not null distinct constraint constr2, campo3 decimal(4,2) distinct constraint constr2, unique (campo1,campo3) constraint constr3, campo4 decimal(2,0) not null, distinct (campo4), campo5 int, campo6 date, campo7 datetime hour to minute ) create synonym sinonimo1 for tabla1 create view vista1 as select * from tabla1 drop synonym sinonimo1 drop table tabla1 create table tabla2 (campo1 smallint) create synonym sinonimo1 for tabla2 create view vista1 as select * from tabla2 drop view vista1 close database end main

CDIGO OBJETO: DROPALL.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class dropall { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , unique ( campo1 ) constraint constr1 , campo3 decimal(4,2) unique constraint constr2 , unique ( campo1 , campo3 ) constraint constr3 , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 datetime hour to minute ) "); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.exeUpdate("create view vista1 as select * from tabla1 "); ASGcondb.exeUpdate("drop synonym sinonimo1 "); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla2 "); ASGcondb.exeUpdate("create view vista1 as select * from tabla2 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.finConexionDB(); }

250

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class dropall { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 datetime , campo7 datetime ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla1 "); ASGcondb.exeUpdate("drop synonym sinonimo1 "); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla2 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla2 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class dropall { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.exeUpdate("drop table tabla2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop public synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create public synonym sinonimo1 for tabla1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla1 "); ASGcondb.exeUpdate("drop public synonym sinonimo1 "); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop public synonym sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create public synonym sinonimo1 for tabla2 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla2 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.finConexionDB(); } }

CDIGO OBJETO DB2


import java.sql.*; import ASGdb.*; import ASGdbutil.*;

import ASGutil.*;

251

public class dropall { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint not null , campo2 char(10) not null unique , constraint constr1 unique ( campo1 ) , campo3 decimal(4,2) constraint constr2 unique not null default , constraint constr3 unique ( campo1 , campo3 ) , campo4 decimal(2,0) not null , unique ( campo4 ) , campo5 integer , campo6 date , campo7 timestamp ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop alias sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla1 "); ASGcondb.exeUpdate("drop alias sinonimo1 "); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop alias sinonimo1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create synonym sinonimo1 for tabla2 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 as select * from tabla2 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.finConexionDB(); } }

EJEMPLO SENTENCIA GRANT


main grant dba to public grant insert on tabla1 end main

CDIGO FUENTE INFORMIX-4GL: GRANT.4GL


to public

CDIGO OBJETO: GRANT.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class grant { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.exeUpdate("grant insert on tabla1 to public "); } }

EJEMPLO SENTENCIA INSERT


database datos main whenever error continue drop table tabla1 drop table tabla2 whenever error stop create table tabla1 ( campo1 smallint, campo2 decimal(2,0), campo3 char(10) ) create table tabla2 ( campo1 smallint, campo2 decimal(2,0) ) insert into tabla1 values (1,1,"1"); insert into tabla1 values (2,2,"2");

CDIGO FUENTE INFORMIX-4GL: INSERT.4GL

create view vista1 (campo1,campo2,campo3) as select r.campo1,r.campo2, 3 insert into tabla2 select campo3, campo2 from vista1

from tabla1 r

252
end main

CDIGO OBJETO: INSERT.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class insert { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.exeUpdate("drop table tabla2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 decimal(2,0) , campo3 char(10) ) "); ASGcondb.exeUpdate("create table tabla2 ( campo1 smallint , campo2 decimal(2,0) ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , 1 , '1' ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 2 , 2 , '2' ) "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create view vista1 ( campo1 , campo2 , campo3 ) as select r.campo1 , r.campo2 from tabla1 r "); ASGcondb.exeUpdate("insert into tabla2 select campo3 , campo2 from vista1 "); } }

EJEMPLO SENTENCIA LOAD/UNLOAD


database datos main define fichero char(50) whenever error continue drop table tabla2 whenever error stop create table tabla2 ( campo1 decimal(5,2), campo2 char(5), campo3 date ) create index i1_tabla2 on tabla2(campo1) insert into tabla2 values(1,"yo","31/12/2003")

CDIGO FUENTE INFORMIX-4GL: LOADUNLOAD.4GL

let fichero = "|" load from "insert1.unl" delimiter fichero insert into tabla2 let fichero = "insert2.unl" load from fichero delimiter ";" insert into tabla2 let fichero = "insert into tabla2(pp,manolo)" load from "insert1.unl" fichero unload to "insert4.unl" select * from tabla2 end main

CDIGO OBJETO: LOADUNLOAD.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class loadunload { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String fichero ; fichero = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla2 ( campo1 decimal(5,2) , campo2 char(5) , campo3 datetime ) "); ASGcondb.exeUpdate("create index i1_tabla2 on tabla2 ( campo1 asc ) "); ASGcondb.exeUpdate("insert into tabla2 values ( 1 , 'yo' , convert(datetime,'31/12/2003',103) ) "); fichero = "|" ; ASGcondb.load("insert1.unl" ,fichero ,"insert into tabla2 "); fichero = "insert2.unl" ; ASGcondb.load(fichero ,";" ,"insert into tabla2 "); fichero = "insert into tabla2" ; ASGcondb.load("insert1.unl" ,"|" ,fichero ); ASGcondb.unload("insert4.unl" ,"|" ,"select * from tabla2 "); } }

EJEMPLO SENTENCIA LOCK/UNLOCK


CDIGO FUENTE INFORMIX-4GL: LOCK.4GL
database datos main whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 decimal(2,0), campo3 char(10) ) insert into tabla1 values (1,1,"uno"); insert into tabla1 values (2,2,"dos"); lock table tabla1 in exclusive mode insert into tabla1 values (3,3,"tres"); update tabla1 set campo2 = 4 where campo1 = 1 unlock table tabla1 end main

253

CDIGO OBJETO: LOCK.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class lock { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 decimal(2,0) , campo3 char(10) ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , 1 , 'uno' ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 2 , 2 , 'dos' ) "); ASGcondb.inicioTransac(); ASGcondb.exeUpdate("lock table tabla1 in exclusive mode "); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 3 , 'tres' ) "); ASGcondb.exeUpdate("update tabla1 set campo2 = 4 where campo1 = 1 "); ASGcondb.exeUpdate("unlock table tabla1 "); ASGcondb.finTransacOK(); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class lock { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 ASGcondb.exeUpdate("insert into tabla1 values ( 1 ASGcondb.exeUpdate("insert into tabla1 values ( 2 ASGcondb.inicioTransac(); ASGcondb.exeUpdate("insert into tabla1 values ( 3 ASGcondb.exeUpdate("update tabla1 set campo2 = 4 ASGcondb.finTransacOK(); } }

smallint , campo2 decimal(2,0) , campo3 char(10) ) "); , 1 , 'uno' ) "); , 2 , 'dos' ) "); , 3 , 'tres' ) "); where campo1 = 1 ");

CDIGO OBJETO ORACLE/DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class lock { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac();

ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 decimal(2,0) , campo3 char(10) ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 1 , 1 , 'uno' ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 2 , 2 , 'dos' ) "); ASGcondb.inicioTransac(); ASGcondb.exeUpdate("lock table tabla1 in exclusive mode "); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 3 , 'tres' ) "); ASGcondb.exeUpdate("update tabla1 set campo2 = 4 where campo1 = 1 "); ASGcondb.finTransacOK();

254

EJEMPLO SENTENCIA RENAME COLUMN


CDIGO FUENTE INFORMIX-4GL: RENAMECOLUMN.4GL
database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2), campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) rename column tabla1.campo31 TO campo22 end main

CDIGO OBJETO: RENAMECOLUMN.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class renamecolumn { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("rename column tabla1.campo31 to campo22"); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class renamecolumn { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("sp_rename 'tabla1.campo31', 'campo22', 'COLUMN'"); } }

CDIGO OBJETO ORACLE


import java.sql.*; import ASGdb.*;

import ASGdbutil.*; import ASGutil.*; public class renamecolumn { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("alter table tabla1 rename column campo31 to campo22"); } }

255

EJEMPLO SENTENCIA RENAME TABLA


database datos main define yo,a,b,c smallint whenever error continue drop table tabla1 drop table tabla11 whenever error stop create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2), campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) rename table tabla1 TO tabla11 end main

CDIGO FUENTE INFORMIX-4GL: RENAMETABLE.4GL

CDIGO OBJETO: RENAMETABLE.JAVA CDIGO OBJETO INFORMIX/ORACLE/DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class renametable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla11 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("rename table tabla1 to tabla11"); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class renametable { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int yo , a , b , c ; c = 0; a = 0; yo = 0; b = 0;

ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop table tabla11 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(4,2) , campo11 smallint , campo21 char(10) , campo31 decimal(4,2) ) "); ASGcondb.exeUpdate("sp_rename 'tabla1', 'tabla11'"); } }

256

EJEMPLO SENTENCIA PREPARE/EXECUTE PREPARE/DECLARE


CDIGO FUENTE INFORMIX-4GL: PREPAREDECLARE.4GL
database datos define vcuatro smallint main define vuno, vuno1,vuno2 smallint, vdos decimal (10,3), vtres,vcuatro char(20), cad char(200) whenever error continue drop table tabla1 drop view vista1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(2,0) ) prepare s1 from "insert into tabla1 values (1,'1',1)" execute s1 let vtres = "tabla1" let cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as ", "select * from ",vtres message cad prepare s2 from cad execute s2 let vuno = let vdos = prepare s3 execute s3 2 2.0 from "insert into tabla1 values (?,?,?)" using vuno,vtres,vdos

prepare s4 from "select count(*) from tabla1" declare c4 cursor for s4 open c4 fetch c4 into vuno close c4 message vuno declare c5 cursor for select max(campo1) from tabla1 open c5 fetch c5 into vuno close c5 message vuno end main

CDIGO OBJETO: PREPAREEXECUTE.JAVA CDIGO OBJETO INFORMIX/SQLSERVER/ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class preparedeclare { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); } }

257

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class preparedeclare { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno );

Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); } }

258

EJEMPLO SENTENCIA DECLAREFORUPDATE


database datos

CDIGO FUENTE INFORMIX-4GL: DECLAREFORUPDATE.4GL


define vcuatro smallint main define vuno, vuno1,vuno2 smallint, vdos decimal (10,3), vtres,vcuatro char(20), cad char(200) whenever error continue drop table tabla1 drop view vista1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(2,0) ) prepare s1 from "insert into tabla1 values (1,'1',1)" execute s1 let vtres = "tabla1" let cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as ", "select * from ",vtres message cad prepare s2 from cad execute s2 let vuno = let vdos = prepare s3 execute s3 2 2.0 from "insert into tabla1 values (?,?,?)" using vuno,vtres,vdos

prepare s4 from "select count(*) from tabla1" declare c4 cursor for s4 open c4 fetch c4 into vuno close c4 message vuno declare c5 cursor for select campo1 from tabla1 open c5 fetch c5 into vuno close c5 message vuno declare c6 cursor for select * from tabla1 where campo1 = 1 for update open c6 fetch c6 into vuno update tabla1 set campo1 = 4, campo2 = "cuatro" #delete from tabla1 where current of c6 close c6

where current of c6

update statistics declare c7 cursor for select * from tabla1 where campo1 != 4 for update open c7 fetch c7 into vuno delete from tabla1 close c7 update statistics end main

where current of c7

CDIGO OBJETO: DECLAREFORUPDATE.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class declareforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception {

ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select campo1 from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 = 1 for update"); try { ASG_rsp_c6.next(); vuno = ASG_rsp_c6.getInt(1); } catch (SQLException e) {} ASGcondb.exeUpdate("update tabla1 set campo1 = 4 , campo2 = 'cuatro' where current of "+ ASG_rsp_c6.getCursorName() ); ASG_rsp_c6.close(); ASG_sp_c6.close(); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 where campo1 != 4 for update"); try { ASG_rsp_c7.next(); vuno = ASG_rsp_c7.getInt(1); } catch (SQLException e) {} ASGcondb.exeUpdate("delete from tabla1 where current of "+ ASG_rsp_c7.getCursorName() ); ASG_rsp_c7.close(); ASG_sp_c7.close(); } }

259

CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class declareforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0;

vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select campo1 from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 = 1 "); try { ASG_rsp_c6.next(); vuno = ASG_rsp_c6.getInt(1); } catch (SQLException e) {} ASG_rsp_c6.updateShort("campo1",(short)4); ASG_rsp_c6.updateString("campo2","cuatro"); ASG_rsp_c6.updateRow(); ASG_rsp_c6.close(); ASG_sp_c6.close(); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 where campo1 != 4 "); try { ASG_rsp_c7.next(); vuno = ASG_rsp_c7.getInt(1); } catch (SQLException e) {} ASG_rsp_c7.deleteRow(); ASG_rsp_c7.close(); ASG_sp_c7.close(); } }

260

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class declareforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError();

ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select campo1 from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select CAMPO1,CAMPO2,CAMPO3 from tabla1 where campo1 = 1 "); try { ASG_rsp_c6.next(); vuno = ASG_rsp_c6.getInt(1); } catch (SQLException e) {} ASG_rsp_c6.updateObject("campo1",4); ASG_rsp_c6.updateString("campo2","cuatro"); ASG_rsp_c6.updateRow(); ASG_rsp_c6.close(); ASG_sp_c6.close(); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select CAMPO1,CAMPO2,CAMPO3 from tabla1 where campo1 != 4 "); try { ASG_rsp_c7.next(); vuno = ASG_rsp_c7.getInt(1); } catch (SQLException e) {} ASG_rsp_c7.deleteRow(); ASG_rsp_c7.close(); ASG_sp_c7.close(); } }

261

CDIGO OBJETO DB2


import ASGdb.*; import ASGdbutil.*; import ASGutil.*;

import java.sql.*;

public class declareforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.exeUpdate("drop view vista1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'1',1)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);

ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vtres = "tabla1" ; cad = "create view vista1 (vcamp1,vcamp2,vcamp3) as " + "select * from " + vtres ; System.out.println(cad ); PreparedStatement ASG_sp_s2 = ASGcondb.retCon().prepareStatement(cad ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s2.executeUpdate(); ASG_sp_s2.close(); vuno = 2 ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println(vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select campo1 from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println(vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 = 1 "); try { ASG_rsp_c6.next(); vuno = ASG_rsp_c6.getInt(1); } catch (SQLException e) {} ASGcondb.exeUpdate("update tabla1 set campo1 = 4 , campo2 = 'cuatro' where current of "+ ASG_rsp_c6.getCursorName() ); ASG_rsp_c6.close(); ASG_sp_c6.close(); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 where campo1 != 4 "); try { ASG_rsp_c7.next(); vuno = ASG_rsp_c7.getInt(1); } catch (SQLException e) {} ASGcondb.exeUpdate("delete from tabla1 where current of "+ ASG_rsp_c7.getCursorName() ); ASG_rsp_c7.close(); ASG_sp_c7.close(); } }

262

EJEMPLO SENTENCIA FOREACH-FORUPDATE


database datos

CDIGO FUENTE INFORMIX-4GL: FOREACHFORUPDATE.4GL


define vcuatro smallint main define vuno, vuno1,vuno2 smallint, vdos decimal (10,3), vtres,vcuatro char(20), cad char(200) whenever error continue drop table tabla1 whenever error stop create table tabla1 ( campo1 smallint, campo2 char(10), campo3 decimal(2,0) ) prepare s1 from "insert into tabla1 values (1,'uno',1)" execute s1 let vuno = 2 let vtres = "dos" let vdos = 2.0 prepare s3 from "insert into tabla1 values (?,?,?)" execute s3 using vuno,vtres,vdos insert insert insert insert insert into into into into into tabla1 tabla1 tabla1 tabla1 tabla1 values values values values values (3,'tres',3) (4,'cuatro',4) (5,'cinco',5) (6,'seis',6) (7,'siete',7)

prepare s4 from "select count(*) from tabla1" declare c4 cursor for s4 open c4 fetch c4 into vuno close c4 message "Nmero de filas: " ,vuno declare c5 cursor for select max(campo1) from tabla1 open c5 fetch c5 into vuno close c5 message "maximo campo1: " ,vuno declare c6 cursor for select * from tabla1 where campo1 > 4 for update of campo1 foreach c6 into vuno,vtres,vdos message "campos: ", vuno," ",vtres,vdos update tabla1 set campo1 = 8 where current of c6 end foreach message "borro fila com campo1 = 4" declare c7 cursor for select * from tabla1 for update foreach c7 into vuno,vtres,vdos message "campos: ", vuno," ",vtres,vdos if vuno = 4 then delete from tabla1 where current of c7 end if end foreach message prepare declare foreach "Estado final" s8 from "select * from tabla1" c8 cursor for s8 c8 into vuno,vtres,vdos message "campos: ", vuno," ",vtres,vdos end foreach end main

263

CDIGO OBJETO: FOREACHFOR.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class foreachforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'uno',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vuno = 2 ; vtres = "dos" ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 'tres' , 3 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 4 , 'cuatro' , 4 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 5 , 'cinco' , 5 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 6 , 'seis' , 6 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 7 , 'siete' , 7 ) "); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println("Nmero de filas: " + vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try {

} catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println("maximo campo1: " + vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 > 4 for update"); while ( ASG_rsp_c6.next() ) try { vuno = ASG_rsp_c6.getInt(1); vtres = ASG_rsp_c6.getString(2); vdos = ASG_rsp_c6.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); ASGcondb.exeUpdate("update tabla1 set campo1 = 8 where current of "+ ASG_rsp_c6.getCursorName() ); } catch (SQLException e) {} ASG_rsp_c6.close(); ASG_sp_c6.close(); System.out.println("borro fila com campo1 = 4" ); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 for update"); while ( ASG_rsp_c7.next() ) try { vuno = ASG_rsp_c7.getInt(1); vtres = ASG_rsp_c7.getString(2); vdos = ASG_rsp_c7.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); if ( vuno == 4 ) { ASGcondb.exeUpdate("delete from tabla1 where current of "+ ASG_rsp_c7.getCursorName() ); } } catch (SQLException e) {} ASG_rsp_c7.close(); ASG_sp_c7.close(); System.out.println("Estado final" ); PreparedStatement ASG_sp_s8 = ASGcondb.retCon().prepareStatement("select * from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c8 = ASG_sp_s8.executeQuery(); while ( ASG_rsp_c8.next() ) try { vuno = ASG_rsp_c8.getInt(1); vtres = ASG_rsp_c8.getString(2); vdos = ASG_rsp_c8.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); } catch (SQLException e) {} ASG_rsp_c8.close(); ASG_sp_s8.close(); } }

ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1);

264

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class foreachforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'uno',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vuno = 2 ; vtres = "dos" ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 'tres' , 3 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 4 , 'cuatro' , 4 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 5 , 'cinco' , 5 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 6 , 'seis' , 6 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 7 , 'siete' , 7 ) "); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println("Nmero de filas: " + vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println("maximo campo1: " + vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 > 4 "); while ( ASG_rsp_c6.next() ) try { vuno = ASG_rsp_c6.getInt(1); vtres = ASG_rsp_c6.getString(2); vdos = ASG_rsp_c6.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); ASG_rsp_c6.updateShort("campo1",(short)8); ASG_rsp_c6.updateRow(); } catch (SQLException e) {} ASG_rsp_c6.close(); ASG_sp_c6.close(); System.out.println("borro fila com campo1 = 4" ); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 "); while ( ASG_rsp_c7.next() ) try { vuno = ASG_rsp_c7.getInt(1); vtres = ASG_rsp_c7.getString(2); vdos = ASG_rsp_c7.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); if ( vuno == 4 ) { ASG_rsp_c7.deleteRow(); } } catch (SQLException e) {} ASG_rsp_c7.close(); ASG_sp_c7.close(); System.out.println("Estado final" ); PreparedStatement ASG_sp_s8 = ASGcondb.retCon().prepareStatement("select * from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c8 = ASG_sp_s8.executeQuery(); while ( ASG_rsp_c8.next() ) try { vuno = ASG_rsp_c8.getInt(1); vtres = ASG_rsp_c8.getString(2); vdos = ASG_rsp_c8.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); } catch (SQLException e) {} ASG_rsp_c8.close(); ASG_sp_s8.close(); } }

265

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class foreachforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0; vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'uno',1)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vuno = 2 ; vtres = "dos" ;

vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 'tres' , 3 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 4 , 'cuatro' , 4 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 5 , 'cinco' , 5 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 6 , 'seis' , 6 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 7 , 'siete' , 7 ) "); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println("Nmero de filas: " + vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println("maximo campo1: " + vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select CAMPO1,CAMPO2,CAMPO3 from tabla1 where campo1 > 4 "); while ( ASG_rsp_c6.next() ) try { vuno = ASG_rsp_c6.getInt(1); vtres = ASG_rsp_c6.getString(2); vdos = ASG_rsp_c6.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); ASG_rsp_c6.updateObject("campo1",8); ASG_rsp_c6.updateRow(); } catch (SQLException e) {} ASG_rsp_c6.close(); ASG_sp_c6.close(); System.out.println("borro fila com campo1 = 4" ); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select CAMPO1,CAMPO2,CAMPO3 from tabla1 "); while ( ASG_rsp_c7.next() ) try { vuno = ASG_rsp_c7.getInt(1); vtres = ASG_rsp_c7.getString(2); vdos = ASG_rsp_c7.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); if ( vuno == 4 ) { ASG_rsp_c7.deleteRow(); } } catch (SQLException e) {} ASG_rsp_c7.close(); ASG_sp_c7.close(); System.out.println("Estado final" ); PreparedStatement ASG_sp_s8 = ASGcondb.retCon().prepareStatement("select * from tabla1" ,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c8 = ASG_sp_s8.executeQuery(); while ( ASG_rsp_c8.next() ) try { vuno = ASG_rsp_c8.getInt(1); vtres = ASG_rsp_c8.getString(2); vdos = ASG_rsp_c8.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); } catch (SQLException e) {} ASG_rsp_c8.close(); ASG_sp_s8.close(); } }

266

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class foreachforupdate { static int vcuatro ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); int vuno , vuno1 , vuno2 ; double vdos ; String vtres , vcuatro ; String cad ; vuno = 0; vdos = 0.0;

vuno1 = 0; vtres = ""; vuno2 = 0; vcuatro = ""; cad = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla1 ( campo1 smallint , campo2 char(10) , campo3 decimal(2,0) ) "); PreparedStatement ASG_sp_s1 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (1,'uno',1)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s1.executeUpdate(); ASG_sp_s1.close(); vuno = 2 ; vtres = "dos" ; vdos = 2 ; PreparedStatement ASG_sp_s3 = ASGcondb.retCon().prepareStatement("insert into tabla1 values (?,?,?)" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ASG_sp_s3.setInt(1,vuno); ASG_sp_s3.setString(2,vtres); ASG_sp_s3.setDouble(3,vdos); ASG_sp_s3.executeUpdate(); ASG_sp_s3.close(); ASGcondb.exeUpdate("insert into tabla1 values ( 3 , 'tres' , 3 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 4 , 'cuatro' , 4 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 5 , 'cinco' , 5 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 6 , 'seis' , 6 ) "); ASGcondb.exeUpdate("insert into tabla1 values ( 7 , 'siete' , 7 ) "); PreparedStatement ASG_sp_s4 = ASGcondb.retCon().prepareStatement("select count(*) from tabla1" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c4 = ASG_sp_s4.executeQuery(); try { ASG_rsp_c4.next(); vuno = ASG_rsp_c4.getInt(1); } catch (SQLException e) {} ASG_rsp_c4.close(); ASG_sp_s4.close(); System.out.println("Nmero de filas: " + vuno ); Statement ASG_sp_c5 = ASGcondb.retCon().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c5 = ASG_sp_c5.executeQuery("select max ( campo1 ) from tabla1 "); try { ASG_rsp_c5.next(); vuno = ASG_rsp_c5.getInt(1); } catch (SQLException e) {} ASG_rsp_c5.close(); ASG_sp_c5.close(); System.out.println("maximo campo1: " + vuno ); Statement ASG_sp_c6 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c6 = ASG_sp_c6.executeQuery("select * from tabla1 where campo1 > 4 "); while ( ASG_rsp_c6.next() ) try { vuno = ASG_rsp_c6.getInt(1); vtres = ASG_rsp_c6.getString(2); vdos = ASG_rsp_c6.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); ASGcondb.exeUpdate("update tabla1 set campo1 = 8 where current of "+ ASG_rsp_c6.getCursorName() ); } catch (SQLException e) {} ASG_rsp_c6.close(); ASG_sp_c6.close(); System.out.println("borro fila com campo1 = 4" ); Statement ASG_sp_c7 = ASGcondb.retCon().createStatement(ResultSet.TYPE_FORWARD_ONLY,ResultSet.CONCUR_UPDATABLE); ResultSet ASG_rsp_c7 = ASG_sp_c7.executeQuery("select * from tabla1 "); while ( ASG_rsp_c7.next() ) try { vuno = ASG_rsp_c7.getInt(1); vtres = ASG_rsp_c7.getString(2); vdos = ASG_rsp_c7.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); if ( vuno == 4 ) { ASGcondb.exeUpdate("delete from tabla1 where current of "+ ASG_rsp_c7.getCursorName() ); } } catch (SQLException e) {} ASG_rsp_c7.close(); ASG_sp_c7.close(); System.out.println("Estado final" ); PreparedStatement ASG_sp_s8 = ASGcondb.retCon().prepareStatement("select * from tabla1" ,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); ResultSet ASG_rsp_c8 = ASG_sp_s8.executeQuery(); while ( ASG_rsp_c8.next() ) try { vuno = ASG_rsp_c8.getInt(1); vtres = ASG_rsp_c8.getString(2); vdos = ASG_rsp_c8.getDouble(3); System.out.println("campos: " + vuno + " " + vtres + vdos ); } catch (SQLException e) {} ASG_rsp_c8.close(); ASG_sp_s8.close(); } }

267

EJEMPLO SENTENCIA TIPOS DE DATOS


#tipos de datos admitidos database datos

CDIGO FUENTE INFORMIX-4GL: TIPOSDATOS.4GL

main whenever error continue drop table tabla99 whenever error stop create table tabla99 ( campo1 byte, campo2 char, campo3 char(10), campo4 char(9000), campo5 date, campo6 datetime year to day, campo7 datetime hour to second, campo8 datetime year to second, campo9 decimal, campo10 decimal(10), campo11 decimal(10,2), campo12 float, campo13 integer, campo14 money, campo15 real, campo16 smallint, campo17 text, campo18 varchar(30) ) select campo1,campo2,campo3,campo4,campo5,campo6,campo7,campo8,campo9,campo10,campo11, campo12,campo13,campo14,campo15,campo16,campo17,campo18 from tabla99; end main

268

CDIGO OBJETO: TIPOSDATOS.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class tiposdatos { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla99 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla99 ( campo1 byte , campo2 char(1) , campo3 char(10) , campo4 char(9000) , campo5 date , campo6 date , campo7 datetime hour to second , campo8 datetime year to second , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 text , campo18 varchar(30) ) "); ASGcondb.exeSelectSimple("select campo1 , campo2 , campo3 , campo4 , campo5 , campo6 , campo7 , campo8 , campo9 , campo10 , campo11 , campo12 , campo13 , campo14 , campo15 , campo16 , campo17 , campo18 from tabla99 "); } }

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class tiposdatos { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla99 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla99 ( campo1 image , campo2 char(1) , campo3 char(10) , campo4 text , campo5 datetime , campo6 datetime , campo7 datetime , campo8 datetime , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 text , campo18 varchar(30) ) "); ASGcondb.exeSelectSimple("select campo1 , campo2 , campo3 , campo4 , campo5 , campo6 , campo7 , campo8 , campo9 , campo10 , campo11 , campo12 , campo13 , campo14 , campo15 , campo16 , campo17 , campo18 from tabla99 "); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class tiposdatos { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla99 cascade constraints"); ASGcondb.desactivaControlError();

ASGcondb.exeUpdate("create table tabla99 ( campo1 blob , campo2 char(1) , campo3 char(10) , campo4 long , campo5 date , campo6 date , campo7 date , campo8 timestamp , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 clob , campo18 varchar(30) ) "); ASGcondb.exeSelectSimple("select campo1 , campo2 , campo3 , campo4 , campo5 , campo6 , campo7 , campo8 , campo9 , campo10 , campo11 , campo12 , campo13 , campo14 , campo15 , campo16 , campo17 , campo18 from tabla99 "); } }

269

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class tiposdatos { private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table tabla99 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table tabla99 ( campo1 blob , campo2 char(1) , campo3 char(10) , campo4 long varchar , campo5 date , campo6 date , campo7 time , campo8 timestamp , campo9 decimal(16,0) , campo10 decimal(10,0) , campo11 decimal(10,2) , campo12 float , campo13 integer , campo14 decimal(16,2) , campo15 real , campo16 smallint , campo17 clob , campo18 varchar(30) ) "); ASGcondb.exeSelectSimple("select campo1 , campo2 , campo3 , campo4 , campo5 , campo6 , campo7 , campo8 , campo9 , campo10 , campo11 , campo12 , campo13 , campo14 , campo15 , campo16 , campo17 , campo18 from tabla99 "); } }

EJEMPLO DE MANEJO DE COLUMNAS Y CONSTANTES PREDEFINIDAS


CDIGO FUENTE INFORMIX-4GL: EXPRSQL1.4GL
#Expresiones SQL #expresion de manejo de columnas #rowid, acceso campos, subsrting database datos define hola char(30) main define uno char(20), dos date, tres datetime year to fraction whenever error continue drop table prueba1 whenever error stop create table prueba1 ( campo1 char(20), campo2 date, campo3 datetime year to second ) insert into prueba1 values ("esto es una prueba",today,current) select campo1[1,3] into uno from prueba1 message "Primeros tres caracteres del campo: ", uno select informix.prueba1.campo1[2,4] into uno from prueba1 message "Caracteres del 2 al 4 del campo: ", uno select rowid into hola from prueba1 message "Rowid: ", hola end main

CDIGO OBJETO: EXPRSQL1.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql1 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; uno = ""; dos = null; tres = null; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 ");

ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 datetime year to second ) "); ASGcondb.exeUpdate("insert into prueba1 values ( user , today , current ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , campo1[1,3] from prueba1 "); try { ASG_r1.next(); usuario = ASG_r1.getString(1); uno = ASG_r1.getString(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Primeros tres caracteres del campo: " + usuario + "son: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select informix.prueba1.campo1[2,4] from prueba1 "); try { ASG_r2.next(); uno = ASG_r2.getString(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Caracteres del 2 al 4 del campo: " + uno ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select rowid from prueba1 "); try { ASG_r3.next(); hola = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Rowid: " + hola );

270

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql1 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; uno = ""; dos = null; tres = null; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 datetime , campo3 datetime ) "); ASGcondb.exeUpdate("insert into prueba1 values ( user , dateadd(dd,0, datediff(dd,0,getdate())) , getdate() ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , substring(campo1,1,3) from prueba1 "); try { ASG_r1.next(); usuario = ASG_r1.getString(1); uno = ASG_r1.getString(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Primeros tres caracteres del campo: " + usuario + "son: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select substring(informix.prueba1.campo1,2,3) from prueba1 "); try { ASG_r2.next(); uno = ASG_r2.getString(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Caracteres del 2 al 4 del campo: " + uno ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select rowid from prueba1 "); try { ASG_r3.next(); hola = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Rowid: " + hola ); } }

OBJETO ORACLE
import java.sql.*; import ASGdb.*; import ASGdbutil.*;

import ASGutil.*; public class exprsql1 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno , usuario ; java.sql.Date dos ; java.sql.Timestamp tres ; uno = ""; dos = null; tres = null; usuario = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 timestamp ) "); ASGcondb.exeUpdate("insert into prueba1 values ( user , to_date(to_char(sysdate,'dd/mm/yyyy')) , sysdate ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , substr(campo1,1,3) from prueba1 "); try { ASG_r1.next(); usuario = ASG_r1.getString(1); uno = ASG_r1.getString(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Primeros tres caracteres del campo: " + usuario + "son: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select substr(informix.prueba1.campo1,2,3) from informix.prueba1 "); try { ASG_r2.next(); uno = ASG_r2.getString(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Caracteres del 2 al 4 del campo: " + uno ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select rowid from prueba1 "); try { ASG_r3.next(); hola = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Rowid: " + hola ); } }

271

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql1 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; uno = ""; dos = null; tres = null; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 timestamp ) "); ASGcondb.exeUpdate("insert into prueba1 values ( user , current date , current timestamp ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , substr(campo1,1,3) from prueba1 "); try { ASG_r1.next(); usuario = ASG_r1.getString(1); uno = ASG_r1.getString(2); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Primeros tres caracteres del campo: " + usuario + "son: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select substr(informix.prueba1.campo1,2,3) from prueba1 "); try { ASG_r2.next(); uno = ASG_r2.getString(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close();

System.out.println("Caracteres del 2 al 4 del campo: " + uno ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select rowid from prueba1 "); try { ASG_r3.next(); hola = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Rowid: " + hola );

272

EJEMPLO DE MANEJO DE LITERALES, CONSTANTES Y VARIABLES


CDIGO FUENTE INFORMIX-4GL: EXPRSQL2.4GL
#Expresiones SQL #expresion de manejo de constantes #literales, vbles, y ctes. database datos define hola char(30) main define uno char(20), dos,fecha date, tres datetime year to fraction, cuatro integer, cinco decimal(12,2)

let let let let let let let let

uno = "hola mundo" cuatro = 24 dos = today; tres = current; cinco = cuatro; tres = "2007-07-22 12:33:20.444"; dos = "22/07/2007"; fecha = 40000 "campo1: ", uno "campo2: ", dos "campo3: ", tres "campo4: ", cuatro "campo5: ", cinco "--------------------------"

message message message message message message

whenever error continue drop table prueba1 whenever error stop create table prueba1 ( campo1 char(20), campo2 date, campo3 datetime year to fraction, campo4 integer, campo5 decimal(12,2) ) insert insert insert insert insert into into into into into prueba1 prueba1 prueba1 prueba1 prueba1 values values values values values ("esto es una prueba",today,current,12,12.3) (uno,dos,tres,cuatro,12.3) (uno,fecha,tres,cuatro,1.3) (uno,"15/08/2006","2007-07-21 13:44:30.23",cuatro,12.3) (uno,"15/08/2006",datetime (2007-07-22 12:33:20.444) year to fraction,cuatro,12.3)

select campo1,campo2,campo3,campo4,campo5 into uno,dos,tres,cuatro,cinco from prueba1 message "campo1: ", uno message "campo2: ", dos message "campo3: ", tres message "campo4: ", cuatro message "campo5: ", cinco end main

CDIGO OBJETO: EXPRSQL2.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql2 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos , fecha ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; fecha = null;

uno = ""; dos = null; tres = null; uno = "hola mundo" ; cuatro = 24 ; dos = new Date(new java.util.Date().getTime()) ; tres = new Timestamp(new java.util.Date().getTime()) ; cinco = cuatro ; tres = ASGfaux.fechahora("2007-07-22 12:33:20.444") ; dos = ASGfaux.fecha("22/07/2007") ; fecha = ASGfaux.cteIntToFechaJ(40000) ; System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); System.out.println("--------------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 datetime year to fraction , campo4 integer , campo5 decimal(12,2) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , today , current , 12 , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ dos +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ fecha +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 1.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , '15/08/2006' , '2007-07-21 13:44:30.23' , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , '15/08/2006' , datetime ( 2007-7-22 12:33:20.444 ) year to fraction , "+ cuatro +" , 12.3 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , campo2 , campo3 , campo4 , campo5 from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); dos = ASG_r1.getDate(2); tres = ASG_r1.getTimestamp(3); cuatro = ASG_r1.getInt(4); cinco = ASG_r1.getDouble(5); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); } }

273

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql2 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos , fecha ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; fecha = null; uno = ""; dos = null; tres = null; uno = "hola mundo" ; cuatro = 24 ; dos = new Date(new java.util.Date().getTime()) ; tres = new Timestamp(new java.util.Date().getTime()) ; cinco = cuatro ; tres = ASGfaux.fechahora("2007-07-22 12:33:20.444") ; dos = ASGfaux.fecha("22/07/2007") ; fecha = ASGfaux.cteIntToFechaJ(40000) ; System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); System.out.println("--------------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 datetime , campo3 datetime , campo4 integer , campo5 decimal(12,2) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , dateadd(dd,0, datediff(dd,0,getdate())) , getdate() , 12 , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ dos +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ fecha +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 1.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , convert(datetime,'15/08/2006',103) , convert(datetime,'2007-07-21 13:44:30.23',121) , "+ cuatro +" , 12.3 ) ");

ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , convert(datetime,'15/08/2006',103) , convert(datetime,'2007-7-22 12:33:20.444 ',121) , "+ cuatro +" , 12.3 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , campo2 , campo3 , campo4 , prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); dos = ASG_r1.getDate(2); tres = ASG_r1.getTimestamp(3); cuatro = ASG_r1.getInt(4); cinco = ASG_r1.getDouble(5); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); } }

274
campo5 from

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql2 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos , fecha ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; fecha = null; uno = ""; dos = null; tres = null; uno = "hola mundo" ; cuatro = 24 ; dos = new Date(new java.util.Date().getTime()) ; tres = new Timestamp(new java.util.Date().getTime()) ; cinco = cuatro ; tres = ASGfaux.fechahora("2007-07-22 12:33:20.444") ; dos = ASGfaux.fecha("22/07/2007") ; fecha = ASGfaux.cteIntToFechaJ(40000) ; System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); System.out.println("--------------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 timestamp , campo4 integer , campo5 decimal(12,2) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , to_date(to_char(sysdate,'dd/mm/yyyy')) , sysdate , 12 , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ dos +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ fecha +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 1.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , to_date('15/08/2006','dd/mm/yyyy') , timestamp '200707-21 13:44:30.23' , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , to_date('15/08/2006','dd/mm/yyyy') , timestamp '2007-722 12:33:20.444 ' , "+ cuatro +" , 12.3 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , campo2 , campo3 , campo4 , campo5 from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); dos = ASG_r1.getDate(2); tres = ASG_r1.getTimestamp(3); cuatro = ASG_r1.getInt(4); cinco = ASG_r1.getDouble(5); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); } }

CDIGO OBJETO DB2


import java.sql.*; import ASGdb.*; import ASGdbutil.*;

import ASGutil.*;

275

public class exprsql2 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos , fecha ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; fecha = null; uno = ""; dos = null; tres = null; uno = "hola mundo" ; cuatro = 24 ; dos = new Date(new java.util.Date().getTime()) ; tres = new Timestamp(new java.util.Date().getTime()) ; cinco = cuatro ; tres = ASGfaux.fechahora("2007-07-22 12:33:20.444") ; dos = ASGfaux.fecha("22/07/2007") ; fecha = ASGfaux.cteIntToFechaJ(40000) ; System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); System.out.println("--------------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 date , campo3 timestamp , campo4 integer , campo5 decimal(12,2) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , current date , current timestamp , 12 , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ dos +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , {d '"+ fecha +"'} , {ts '"+ tres +"'} , "+ cuatro +" , 1.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , date('15/08/2006') , '2007-07-21 13:44:30.23' , "+ cuatro +" , 12.3 ) "); ASGcondb.exeUpdate("insert into prueba1 values ( '"+ uno +"' , date('15/08/2006') , '2007-7-22 12:33:20.444 ' , "+ cuatro +" , 12.3 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo1 , campo2 , campo3 , campo4 , campo5 from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); dos = ASG_r1.getDate(2); tres = ASG_r1.getTimestamp(3); cuatro = ASG_r1.getInt(4); cinco = ASG_r1.getDouble(5); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("campo1: " + uno ); System.out.println("campo2: " + ASGfaux.formato_fecha(dos) ); System.out.println("campo3: " + tres ); System.out.println("campo4: " + cuatro ); System.out.println("campo5: " + cinco ); } }

EJEMPLO FUNCIONES DE MANEJO DE FECHAS


CDIGO FUENTE INFORMIX-4GL: EXPRSQL4.4GL
#Expresiones SQL #Funciones Sql trtamientod e fechas #day,year,month,weekday,date,mdy,etc. database datos define hola char(30) main define fecha1,fecha2 date, fecha3 datetime year to fraction, dia,mes,diaw,anio integer, cinco decimal(12,2)

let let let let let let let let

dia = day(today) mes = month(today); diaw = weekday(today) anio = year(today) fecha1 = date("31/12/2006") fecha1 = date(today) fecha2 = mdy(month(today),dia,year(today)) fecha3 = datetime (2007-07-22 12:33:20.444) year to fraction "dia: ", dia "mes: ", mes "dia de la semana: ", diaw "ao: ", anio "fecha: ", fecha1

message message message message message

message "fecha: ", fecha2 message "fecha: ", fecha3 message "-----------------------" whenever error continue drop table prueba2 whenever error stop create table prueba2 ( dia smallint, mes smallint, diaw smallint, anio smallint, fecha1 date, fecha2 date ) insert into prueba2 values(11,1,1,2005,today,today) insert into prueba2 values(11,1,1,2005,"31/12/2006",'31/12/2006') select day(today),month(today),weekday(today),year(today) ,date("31/12/2006") ,mdy(12,31,2006) into dia,mes,diaw,anio,fecha1,fecha2 from prueba2 message message message message message message "dia: ", dia "mes: ", mes "dia de la semana: ", diaw "ao: ", anio "fecha: ", fecha1 "fecha: ", fecha2

276

update prueba2 set dia = day(today), mes = month(today), diaw = weekday(today), anio = year(today), fecha1 = date("31/12/2006"), fecha2 = mdy(3,dia,anio) select * into dia,mes,diaw,anio,fecha1,fecha2 from prueba2 message message message message message message message end main "-----------------------" "dia: ", dia "mes: ", mes "dia de la semana: ", diaw "ao: ", anio "fecha: ", fecha1 "fecha: ", fecha2

CDIGO OBJETO: EXPRSQL4JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql4 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; java.sql.Timestamp fecha3 ; int dia , mes , diaw , anio ; double cinco ; cinco = 0.0; fecha3 = null; fecha2 = null; mes = 0; diaw = 0; fecha1 = null; dia = 0; anio = 0; dia = ASGfaux.day( new Date(new java.util.Date().getTime()) ) ; mes = ASGfaux.month( new Date(new java.util.Date().getTime()) ) ; diaw = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; anio = ASGfaux.year( new Date(new java.util.Date().getTime()) ) ; fecha1 = ASGfaux.fecha( ASGfaux.fecha("31/12/2006") ) ; fecha1 = ASGfaux.fecha( new Date(new java.util.Date().getTime()) ) ; fecha2 = ASGfaux.mdy ( ASGfaux.month( new Date(new java.util.Date().getTime()) ) , dia , ASGfaux.year( new Date(new java.util.Date().getTime()) ) ) ; fecha3 = ASGfaux.fechahora ( "2007-7-22 12:33:20.444" ) ; System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); System.out.println("fecha: " + fecha3 ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date , fecha2 date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , today , today ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , '31/12/2006' , '31/12/2006' ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement();

ResultSet ASG_r1 = ASG_st1.executeQuery("select day ( today ) , month ( today , year ( today ) , date( '31/12/2006' ) , mdy( 12 ,31 ,2006 ) from prueba2 "); try { ASG_r1.next(); dia = ASG_r1.getInt(1); mes = ASG_r1.getInt(2); diaw = ASG_r1.getInt(3); anio = ASG_r1.getInt(4); fecha1 = ASG_r1.getDate(5); fecha2 = ASG_r1.getDate(6); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); ASGcondb.exeUpdate("update prueba2 set dia = day ( today ) , mes = month ( today , anio = year ( today ) , fecha1 = date( '31/12/2006' ) , fecha2 = mdy( 3 ,dia ,anio ) "); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from prueba2 "); try { ASG_r2.next(); dia = ASG_r2.getInt(1); mes = ASG_r2.getInt(2); diaw = ASG_r2.getInt(3); anio = ASG_r2.getInt(4); fecha1 = ASG_r2.getDate(5); fecha2 = ASG_r2.getDate(6); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("-----------------------" ); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); }

weekday ( today

277

, diaw = weekday ( today

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql4 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; java.sql.Timestamp fecha3 ; int dia , mes , diaw , anio ; double cinco ; cinco = 0.0; fecha3 = null; fecha2 = null; mes = 0; diaw = 0; fecha1 = null; dia = 0; anio = 0; dia = ASGfaux.day( new Date(new java.util.Date().getTime()) ) ; mes = ASGfaux.month( new Date(new java.util.Date().getTime()) ) ; diaw = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; anio = ASGfaux.year( new Date(new java.util.Date().getTime()) ) ; fecha1 = ASGfaux.fecha( ASGfaux.fecha("31/12/2006") ) ; fecha1 = ASGfaux.fecha( new Date(new java.util.Date().getTime()) ) ; fecha2 = ASGfaux.mdy ( ASGfaux.month( new Date(new java.util.Date().getTime()) ) , dia , ASGfaux.year( new Date(new java.util.Date().getTime()) ) ) ; fecha3 = ASGfaux.fechahora ( "2007-7-22 12:33:20.444" ) ; System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); System.out.println("fecha: " + fecha3 ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 datetime , fecha2 datetime ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , dateadd(dd,0, datediff(dd,0,getdate())) , dateadd(dd,0, datediff(dd,0,getdate())) ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , convert(datetime,'31/12/2006',103) , convert(datetime,'31/12/2006',103) ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select day ( dateadd(dd,0, datediff(dd,0,getdate())) ) , month ( dateadd(dd,0, datediff(dd,0,getdate())) ) , datepart ( dw, dateadd(dd,0, datediff(dd,0,getdate())) ) % 7 , year ( dateadd(dd,0, datediff(dd,0,getdate())) ) , convert(datetime, convert(datetime,'31/12/2006',103) ,103) , convert(datetime, '"+31+'/'+12+'/'+2006+"',103 ) from prueba2 "); try {

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); ASGcondb.exeUpdate("update prueba2 set dia = day ( dateadd(dd,0, datediff(dd,0,getdate())) dateadd(dd,0, datediff(dd,0,getdate())) ) , diaw = datepart ( dw, dateadd(dd,0, datediff(dd,0,getdate())) ( dateadd(dd,0, datediff(dd,0,getdate())) ) , fecha1 = convert(datetime, convert(datetime,'31/12/2006',103) convert(datetime, '"+dia+'/'+3+'/'+anio+"',103 ) "); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from prueba2 "); try { ASG_r2.next(); dia = ASG_r2.getInt(1); mes = ASG_r2.getInt(2); diaw = ASG_r2.getInt(3); anio = ASG_r2.getInt(4); fecha1 = ASG_r2.getDate(5); fecha2 = ASG_r2.getDate(6); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("-----------------------" ); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); } }

ASG_r1.next(); dia = ASG_r1.getInt(1); mes = ASG_r1.getInt(2); diaw = ASG_r1.getInt(3); anio = ASG_r1.getInt(4); fecha1 = ASG_r1.getDate(5); fecha2 = ASG_r1.getDate(6);

278

) , mes = month ( ) % 7 , anio = year ,103) , fecha2 =

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql4 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; java.sql.Timestamp fecha3 ; int dia , mes , diaw , anio ; double cinco ; cinco = 0.0; fecha3 = null; fecha2 = null; mes = 0; diaw = 0; fecha1 = null; dia = 0; anio = 0; dia = ASGfaux.day( new Date(new java.util.Date().getTime()) ) ; mes = ASGfaux.month( new Date(new java.util.Date().getTime()) ) ; diaw = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; anio = ASGfaux.year( new Date(new java.util.Date().getTime()) ) ; fecha1 = ASGfaux.fecha( ASGfaux.fecha("31/12/2006") ) ; fecha1 = ASGfaux.fecha( new Date(new java.util.Date().getTime()) ) ; fecha2 = ASGfaux.mdy ( ASGfaux.month( new Date(new java.util.Date().getTime()) ) , dia , ASGfaux.year( new Date(new java.util.Date().getTime()) ) ) ; fecha3 = ASGfaux.fechahora ( "2007-7-22 12:33:20.444" ) ; System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); System.out.println("fecha: " + fecha3 ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date , fecha2 date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date(to_char(sysdate,'dd/mm/yyyy')) ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , to_date('31/12/2006','dd/mm/yyyy') , to_date('31/12/2006','dd/mm/yyyy') ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'DD' ) , to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'MM' ) , mod(to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'D' ),7) , to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'YYYY' ) , to_date( to_date('31/12/2006','dd/mm/yyyy') ,'dd/mm/yyyy') , to_date( '"+31+'/'+12+'/'+2006+"' ) from prueba2 "); try { ASG_r1.next(); dia = ASG_r1.getInt(1);

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); ASGcondb.exeUpdate("update prueba2 set dia = to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'DD' ) , mes = to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'MM' ) , diaw = mod(to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'D' ),7) , anio = to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'YYYY' ) , fecha1 = to_date( to_date('31/12/2006','dd/mm/yyyy') ,'dd/mm/yyyy') , fecha2 = to_date( '"+dia+'/'+3+'/'+anio+"' ) "); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from prueba2 "); try { ASG_r2.next(); dia = ASG_r2.getInt(1); mes = ASG_r2.getInt(2); diaw = ASG_r2.getInt(3); anio = ASG_r2.getInt(4); fecha1 = ASG_r2.getDate(5); fecha2 = ASG_r2.getDate(6); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("-----------------------" ); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); } }

mes = ASG_r1.getInt(2); diaw = ASG_r1.getInt(3); anio = ASG_r1.getInt(4); fecha1 = ASG_r1.getDate(5); fecha2 = ASG_r1.getDate(6);

279

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql4 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; java.sql.Timestamp fecha3 ; int dia , mes , diaw , anio ; double cinco ; cinco = 0.0; fecha3 = null; fecha2 = null; mes = 0; diaw = 0; fecha1 = null; dia = 0; anio = 0; dia = ASGfaux.day( new Date(new java.util.Date().getTime()) ) ; mes = ASGfaux.month( new Date(new java.util.Date().getTime()) ) ; diaw = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; anio = ASGfaux.year( new Date(new java.util.Date().getTime()) ) ; fecha1 = ASGfaux.fecha( ASGfaux.fecha("31/12/2006") ) ; fecha1 = ASGfaux.fecha( new Date(new java.util.Date().getTime()) ) ; fecha2 = ASGfaux.mdy ( ASGfaux.month( new Date(new java.util.Date().getTime()) ) , dia , ASGfaux.year( new Date(new java.util.Date().getTime()) ) ) ; fecha3 = ASGfaux.fechahora ( "2007-7-22 12:33:20.444" ) ; System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); System.out.println("fecha: " + fecha3 ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date , fecha2 date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , current date , current date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 11 , 1 , 1 , 2005 , date('31/12/2006') , date('31/12/2006') ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select day ( current date ) , month ( current date ) , dayofweek ( current date ) - 1 , year ( current date ) , date( date('31/12/2006') ) , date( '"+31+'/'+12+'/'+2006+"' ) from prueba2 "); try { ASG_r1.next(); dia = ASG_r1.getInt(1); mes = ASG_r1.getInt(2); diaw = ASG_r1.getInt(3); anio = ASG_r1.getInt(4); fecha1 = ASG_r1.getDate(5); fecha2 = ASG_r1.getDate(6);

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); ASGcondb.exeUpdate("update prueba2 set dia = day ( current date ) , mes = month ( current date ) , diaw = dayofweek ( current date ) - 1 , anio = year ( current date ) , fecha1 = date( date('31/12/2006') ) , fecha2 = date( '"+dia+'/'+3+'/'+anio+"' ) "); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select * from prueba2 "); try { ASG_r2.next(); dia = ASG_r2.getInt(1); mes = ASG_r2.getInt(2); diaw = ASG_r2.getInt(3); anio = ASG_r2.getInt(4); fecha1 = ASG_r2.getDate(5); fecha2 = ASG_r2.getDate(6); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("-----------------------" ); System.out.println("dia: " + dia ); System.out.println("mes: " + mes ); System.out.println("dia de la semana: " + diaw ); System.out.println("ao: " + anio ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha1) ); System.out.println("fecha: " + ASGfaux.formato_fecha(fecha2) ); } }

280

EJEMPLO DE FUNCIONES MATEMTICAS


CDIGO FUENTE INFORMIX-4GL: EXPRSQL5.4GL
#Expresiones SQL #Funciones Sql #length, hex, round, trunc database datos define hola char(30) main define uno char(20), dos,cuatro decimal(10,2), tres char(2) whenever error continue drop table prueba1 whenever error stop create table prueba1 ( campo1 char(20), campo2 decimal(10,2), campo3 int ) insert into prueba1 values ("esto es una prueba",10.55,16) select length(campo1) into uno from prueba1 message "Longitud del campo: ", uno select round(campo2), trunc(campo2) into dos,cuatro from prueba1 message "Redondeo: ", dos, " Truncado: ",cuatro select hex(campo3) into tres from prueba1 message "hex: ", tres end main

CDIGO OBJETO: EXPRSQL5.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql5 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; double dos , cuatro ; String tres ; cuatro = 0.0; uno = ""; dos = 0.0; tres = ""; ASGcondb.activaControlError();

ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 decimal(10,2) , campo3 integer ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10.55 , 16 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select length( campo1 ) from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Longitud del campo: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select round ( campo2 ,0 ) , trunc ( campo2 ,0 ) from prueba1 "); try { ASG_r2.next(); dos = ASG_r2.getDouble(1); cuatro = ASG_r2.getDouble(2); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Redondeo: " + dos + " Truncado: " + cuatro ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select hex ( campo3 ) from prueba1 "); try { ASG_r3.next(); tres = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("hex: " + tres );

281

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql5 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; double dos , cuatro ; String tres ; cuatro = 0.0; uno = ""; dos = 0.0; tres = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 decimal(10,2) , campo3 integer ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10.55 , 16 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select len( campo1 ) from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Longitud del campo: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select round ( campo2 ,0 ) , round ( campo2 ,0 ,1 ) from prueba1 "); try { ASG_r2.next(); dos = ASG_r2.getDouble(1); cuatro = ASG_r2.getDouble(2); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Redondeo: " + dos + " Truncado: " + cuatro ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select dbo.inttohex ( campo3 ) from prueba1 "); try { ASG_r3.next(); tres = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("hex: " + tres ); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

282

public class exprsql5 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; double dos , cuatro ; String tres ; cuatro = 0.0; uno = ""; dos = 0.0; tres = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 decimal(10,2) , campo3 integer ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10.55 , 16 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select length(rtrim( campo1 ) ) from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Longitud del campo: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select round ( campo2 ,0 ) , trunc ( campo2 ,0 ) from prueba1 "); try { ASG_r2.next(); dos = ASG_r2.getDouble(1); cuatro = ASG_r2.getDouble(2); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Redondeo: " + dos + " Truncado: " + cuatro ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select to_char ( campo3 ,'XXXXXXXX' ) from prueba1 "); try { ASG_r3.next(); tres = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("hex: " + tres ); } }

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql5 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; double dos , cuatro ; String tres ; cuatro = 0.0; uno = ""; dos = 0.0; tres = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 decimal(10,2) , campo3 integer ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10.55 , 16 ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select length(rtrim( campo1 ) ) from prueba1 "); try { ASG_r1.next(); uno = ASG_r1.getString(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Longitud del campo: " + uno ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select round ( campo2 ,0 ) , trunc ( campo2 ,0 ) from prueba1 "); try { ASG_r2.next();

} catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Redondeo: " + dos + " Truncado: " + cuatro ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select hex ( campo3 ) try { ASG_r3.next(); tres = ASG_r3.getString(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("hex: " + tres );

dos = ASG_r2.getDouble(1); cuatro = ASG_r2.getDouble(2);

283

from prueba1 ");

EJEMPLO DE FUNCIONES AGREGADAS


CDIGO FUENTE INFORMIX-4GL: EXPRSQL6.4GL
#Expresiones SQL #Funciones Sql agregadas #count,max,min,sum, y avg database datos define hola char(30) main define uno char(20), dos,cuatro decimal(10,2), tres char(20) whenever error continue drop table prueba1 whenever error stop create table prueba1 ( campo1 char(20), campo2 decimal(10,2), campo3 char(20) ) insert insert insert insert insert insert into into into into into into prueba1 prueba1 prueba1 prueba1 prueba1 prueba1 values values values values values values ("esto ("esto ("esto ("esto ("esto ("esto es es es es es es una una una una una una prueba",10,"16") prueba",20,"16") prueba",20,"16") prueba",20,"16") prueba",10,"16") prueba",10,"16")

select count(*) into dos from prueba1 message "Nmero de filas: ", dos select count(unique campo1) into dos from prueba1 message "Nmero de filas con campo1 diferente: ", dos select avg(campo2) into dos from prueba1 message "Valor medio campo2: ",dos select max(campo2) into dos from prueba1 message "Valor maximo campo2: ",dos select min(campo2) into dos from prueba1 message "Valor minimo campo2: ",dos select sum(campo2) into dos from prueba1 message "Suma valores campo2: ",dos end main

CDIGO OBJETO: EXPRSQL6.JAVA


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql6 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; double dos , cuatro ; String tres ; cuatro = 0.0; uno = ""; dos = 0.0; tres = ""; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select count ( * )

campo2 decimal(10,2) , campo3 char(20) ) "); prueba' , 10 , '16' ) "); prueba' , 20 , '16' ) "); prueba' , 20 , '16' ) "); prueba' , 20 , '16' ) "); prueba' , 10 , '16' ) "); prueba' , 10 , '16' ) "); from prueba1 ");

try {

284
ASG_r1.next(); dos = ASG_r1.getDouble(1);

} catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("Nmero de filas: " + dos ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select count ( distinct campo1 ) from prueba1 "); try { ASG_r2.next(); dos = ASG_r2.getDouble(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("Nmero de filas con campo1 diferente: " + dos ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select avg ( campo2 ) from prueba1 "); try { ASG_r3.next(); dos = ASG_r3.getDouble(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("Valor medio campo2: " + dos ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select max ( campo2 ) from prueba1 "); try { ASG_r4.next(); dos = ASG_r4.getDouble(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("Valor maximo campo2: " + dos ); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select min ( campo2 ) from prueba1 "); try { ASG_r5.next(); dos = ASG_r5.getDouble(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println("Valor minimo campo2: " + dos ); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select sum ( campo2 ) from prueba1 "); try { ASG_r6.next(); dos = ASG_r6.getDouble(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println("Suma valores campo2: " + dos );

EJEMPLO DE FUNCION WEEKDAY


CDIGO FUENTE INFORMIX-4GL: EXPRSQL7.4GL
#Expresiones SQL #Funciones Sql #Tratamiento de weekday database datos define hola char(30) main define fecha1, fecha2 date, l,m,x,j,v,s,d,h integer, cinco decimal(12,2)

let let let let let let let let

l m x j v s d h

= weekday("03/09/2007") =weekday("04/09/2007") =weekday("05/09/2007") =weekday("06/09/2007") =weekday("07/09/2007") =weekday("08/09/2007") =weekday("09/09/2007") =weekday(today) "lunes: ",l "martes: ",m "miercoles: ",x "jueves: ",j "viernes: ",v "sabado: ",s "domingo: ",d "hoy: ",h "-----------------------"

message message message message message message message message message

whenever error continue drop table prueba2

whenever error stop create table prueba2 ( dia smallint, mes smallint, diaw smallint, anio smallint, fecha1 date, fecha2 date ) insert into prueba2 values(1,1,1,1,today,today)

285

select weekday("03/09/2007"),weekday("04/09/2007"),weekday("05/09/2007"),weekday("06/09/2007"),weekday("07/09/2007"),weekday("08/09/2007"),weekd ay("09/09/2007"),weekday(today) into l,m,x,j,v,s,d,h from prueba2 message message message message message message message message end main "lunes: ",l "martes: ",m "miercoles: ",x "jueves: ",j "viernes: ",v "sabado: ",s "domingo: ",d "hoy: ",h

CDIGO OBJETO: EXPRSQL7.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql7 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; int l , m , x , j , v , s , d , h ; double cinco ; d = 0; m = 0; cinco = 0.0; v = 0; h = 0; l = 0; fecha2 = null; x = 0; j = 0; fecha1 = null; s = 0; l = ASGfaux.dayweek( ASGfaux.fecha("03/09/2007") ) - 1 ; m = ASGfaux.dayweek( ASGfaux.fecha("04/09/2007") ) - 1 ; x = ASGfaux.dayweek( ASGfaux.fecha("05/09/2007") ) - 1 ; j = ASGfaux.dayweek( ASGfaux.fecha("06/09/2007") ) - 1 ; v = ASGfaux.dayweek( ASGfaux.fecha("07/09/2007") ) - 1 ; s = ASGfaux.dayweek( ASGfaux.fecha("08/09/2007") ) - 1 ; d = ASGfaux.dayweek( ASGfaux.fecha("09/09/2007") ) - 1 ; h = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date , fecha2 date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 1 , 1 , 1 , 1 , today , today ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select weekday ( '03/09/2007' ) , weekday ( '04/09/2007' ) , weekday ( '05/09/2007' ) , weekday ( '06/09/2007' ) , weekday ( '07/09/2007' ) , weekday ( '08/09/2007' ) , weekday ( '09/09/2007' ) , weekday ( today ) from prueba2 "); try { ASG_r1.next(); l = ASG_r1.getInt(1); m = ASG_r1.getInt(2); x = ASG_r1.getInt(3); j = ASG_r1.getInt(4); v = ASG_r1.getInt(5); s = ASG_r1.getInt(6); d = ASG_r1.getInt(7); h = ASG_r1.getInt(8); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x );

System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h );

286

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql7 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; int l , m , x , j , v , s , d , h ; double cinco ; d = 0; m = 0; cinco = 0.0; v = 0; h = 0; l = 0; fecha2 = null; x = 0; j = 0; fecha1 = null; s = 0; l = ASGfaux.dayweek( ASGfaux.fecha("03/09/2007") ) - 1 ; m = ASGfaux.dayweek( ASGfaux.fecha("04/09/2007") ) - 1 ; x = ASGfaux.dayweek( ASGfaux.fecha("05/09/2007") ) - 1 ; j = ASGfaux.dayweek( ASGfaux.fecha("06/09/2007") ) - 1 ; v = ASGfaux.dayweek( ASGfaux.fecha("07/09/2007") ) - 1 ; s = ASGfaux.dayweek( ASGfaux.fecha("08/09/2007") ) - 1 ; d = ASGfaux.dayweek( ASGfaux.fecha("09/09/2007") ) - 1 ; h = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 datetime , fecha2 datetime ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 1 , 1 , 1 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , dateadd(dd,0, datediff(dd,0,getdate())) ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select datepart ( dw, convert(datetime,'03/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'04/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'05/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'06/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'07/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'08/09/2007',103) ) % 7 , datepart ( dw, convert(datetime,'09/09/2007',103) ) % 7 , datepart ( dw, dateadd(dd,0, datediff(dd,0,getdate())) ) % 7 from prueba2 "); try { ASG_r1.next(); l = ASG_r1.getInt(1); m = ASG_r1.getInt(2); x = ASG_r1.getInt(3); j = ASG_r1.getInt(4); v = ASG_r1.getInt(5); s = ASG_r1.getInt(6); d = ASG_r1.getInt(7); h = ASG_r1.getInt(8); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); } }

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql7 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos");

, fecha2 date ) ");

ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; int l , m , x , j , v , s , d , h ; double cinco ; d = 0; m = 0; cinco = 0.0; v = 0; h = 0; l = 0; fecha2 = null; x = 0; j = 0; fecha1 = null; s = 0; l = ASGfaux.dayweek( ASGfaux.fecha("03/09/2007") ) - 1 ; m = ASGfaux.dayweek( ASGfaux.fecha("04/09/2007") ) - 1 ; x = ASGfaux.dayweek( ASGfaux.fecha("05/09/2007") ) - 1 ; j = ASGfaux.dayweek( ASGfaux.fecha("06/09/2007") ) - 1 ; v = ASGfaux.dayweek( ASGfaux.fecha("07/09/2007") ) - 1 ; s = ASGfaux.dayweek( ASGfaux.fecha("08/09/2007") ) - 1 ; d = ASGfaux.dayweek( ASGfaux.fecha("09/09/2007") ) - 1 ; h = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) ) - 1 ; System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date

287

ASGcondb.exeUpdate("insert into prueba2 values ( 1 , 1 , 1 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date(to_char(sysdate,'dd/mm/yyyy')) ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select mod(to_char ( to_date('03/09/2007','dd/mm/yyyy') ,'D' ),7) mod(to_char ( to_date('04/09/2007','dd/mm/yyyy') ,'D' ),7) , mod(to_char ( to_date('05/09/2007','dd/mm/yyyy') ,'D' ),7) mod(to_char ( to_date('06/09/2007','dd/mm/yyyy') ,'D' ),7) , mod(to_char ( to_date('07/09/2007','dd/mm/yyyy') ,'D' ),7) mod(to_char ( to_date('08/09/2007','dd/mm/yyyy') ,'D' ),7) , mod(to_char ( to_date('09/09/2007','dd/mm/yyyy') ,'D' ),7) mod(to_char ( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'D' ),7) from prueba2 "); try { ASG_r1.next(); l = ASG_r1.getInt(1); m = ASG_r1.getInt(2); x = ASG_r1.getInt(3); j = ASG_r1.getInt(4); v = ASG_r1.getInt(5); s = ASG_r1.getInt(6); d = ASG_r1.getInt(7); h = ASG_r1.getInt(8); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); } }

, , , ,

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class exprsql7 { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); java.sql.Date fecha1 , fecha2 ; int l , m , x , j , v , s , d , h ; double cinco ; d = 0; m = 0; cinco = 0.0; v = 0; h = 0; l = 0; fecha2 = null; x = 0; j = 0; fecha1 = null; s = 0; l = ASGfaux.dayweek( ASGfaux.fecha("03/09/2007") ) - 1 ; m = ASGfaux.dayweek( ASGfaux.fecha("04/09/2007") ) - 1 ; x = ASGfaux.dayweek( ASGfaux.fecha("05/09/2007") ) - 1 ; j = ASGfaux.dayweek( ASGfaux.fecha("06/09/2007") ) - 1 ; v = ASGfaux.dayweek( ASGfaux.fecha("07/09/2007") ) - 1 ; s = ASGfaux.dayweek( ASGfaux.fecha("08/09/2007") ) - 1 ; d = ASGfaux.dayweek( ASGfaux.fecha("09/09/2007") ) - 1 ; h = ASGfaux.dayweek( new Date(new java.util.Date().getTime()) )

- 1 ;

, fecha2 date ) ");

System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); System.out.println("-----------------------" ); ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba2 ( dia smallint , mes smallint , diaw smallint , anio smallint , fecha1 date

288

ASGcondb.exeUpdate("insert into prueba2 values ( 1 , 1 , 1 , 1 , current date , current date ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select dayofweek ( date('03/09/2007') ) - 1 , dayofweek ( date('04/09/2007') ) - 1 , dayofweek ( date('05/09/2007') ) - 1 , dayofweek ( date('06/09/2007') ) - 1 , dayofweek ( date('07/09/2007') ) - 1 , dayofweek ( date('08/09/2007') ) - 1 , dayofweek ( date('09/09/2007') ) - 1 , dayofweek ( current date ) - 1 from prueba2 "); try { ASG_r1.next(); l = ASG_r1.getInt(1); m = ASG_r1.getInt(2); x = ASG_r1.getInt(3); j = ASG_r1.getInt(4); v = ASG_r1.getInt(5); s = ASG_r1.getInt(6); d = ASG_r1.getInt(7); h = ASG_r1.getInt(8); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("lunes: " + l ); System.out.println("martes: " + m ); System.out.println("miercoles: " + x ); System.out.println("jueves: " + j ); System.out.println("viernes: " + v ); System.out.println("sabado: " + s ); System.out.println("domingo: " + d ); System.out.println("hoy: " + h ); } }

EJEMPLO DE MANEJO DE OPERACIONES SOBRE EXPRESIONES


CDIGO FUENTE INFORMIX-4GL: OPERSQL.4GL
#Operaciones sobre expresiones Sql database datos define hola char(20) main define uno char(20), dos smallint, tres decimal(10,2), fecha, fecha2 date whenever error continue drop table prueba1 drop table prueba2 whenever error stop create table prueba1 ( campo1 char(20), campo2 smallint, campo3 decimal(10,2), campo4 date, campo5 date ) create table prueba2 ( campo5 char(20), campo4 smallint, campo1 decimal(10,2), campo2 date, campo3 date ) insert insert insert insert into into into into prueba1 prueba1 prueba1 prueba2 values values values values ("prueba",1,8.2,today,"31/12/2007") ("otra Cosa",2,3,today,"31/12/2007") ("Prueba",3,1,today,today) ("prueba",2,10,today,today)

select tabla99.campo2 from informix.tabla99 select prueba1.campo2 from prueba1 select informix.tabla99.campo2 from tabla99 select informix.prueba1.campo2 from informix.prueba1 select e.campo1, f.campo1, g.campo1 from prueba1 e, prueba2 f, tabla99 g select CAMPO3 + campo2 + 1 into tres from prueba1 where campo2 = 1 message "resultado sumar dos nmeros: ", tres select campo4 + campo2 + 1 into fecha from prueba1 where campo2 = 1 message "resultado sumar fecha y entero: ", fecha let dos = 2 select campo4 + dos into fecha from prueba1 where campo2 = 1 message "resultado sumar fecha y entero: ", fecha select "31/12/2007" - campo4 into dos from prueba1 where campo2 = 1

message "resultado restar dos fechas: ",dos select fecha - campo4 into dos from prueba1 where campo2 = 1 message "resultado restar dos fechas: ",dos insert into prueba1 values ("prueba",3,5,fecha,today) select fecha - campo4 into dos from prueba1 where campo2 = 2 message "resultado de restar dos fechas: ", dos select campo5 - campo4 into dos from prueba1 where campo2 = 2 message "resultado de restar dos fechas: ", dos select fecha - today into dos from prueba1 where campo2 = 2 message "resultado de restar dos fechas: ", dos select campo4 into fecha2 from prueba1 where campo2 = 1 message "fecha fila1: ", fecha2 select campo4 into fecha2 from prueba1 where campo2 = 2 message "fecha fila2: ", fecha2 select campo4 into fecha2 from prueba1 where campo2 = 3 message "fecha fila3: ", fecha2 select count(campo2) into dos from prueba1 where campo4 < fecha message "nmero de filas con fecha menor que: ", fecha, " = ", dos select count(*) into dos from prueba1 where campo2 between 1 and 2 message "nmero de filas con campo2 entre 1 y 2: ",dos select campo3 into tres from prueba1 where exists (select campo2 from prueba2 where campo4 = prueba1.campo2) message "resultado exist: ", tres select campo3 into tres from prueba1 where campo2 in (select campo4 from prueba2) message "resultado in: ", tres select sum(campo3) into tres from prueba1 where campo2 in (1,2,3,4,6) message "resultado in: ", tres select sum(campo3) into tres from prueba1 where campo2 not in (select campo4 from prueba2) message "resultado not in: ", tres select count(*) into dos from prueba1 where campo1 is null message "filas con valores nulos: ",dos select count(*) into dos from prueba1 where campo1 is not null message "filas con valores no nulos: ",dos select sum(campo3) into tres from prueba1 where campo2 > any (select campo4 from prueba2 where campo4 = prueba1.campo2) message "resultado any: ", tres select sum(campo3) into tres from prueba1 where campo2 >= some (select campo4 from prueba2 where campo4 = prueba1.campo2) message "resultado some: ", tres select sum(campo3) into tres from prueba1 where campo2 > all (select campo4 from prueba2 where campo4 = prueba1.campo2) message "resultado all: ", tres select count(campo2) into dos from prueba1 where campo1 matches "P*" escape '$' message "filas que cumplen la condicion matches P* escape $ : ",dos select count(*) into dos from prueba1 where campo1 not like "P%" message "filas que cumplen la condicion not like P% : ",dos select count(*) into dos from prueba1 where campo1 not like "_rueba" message "filas que cumplen la condicion not like _rueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[a-z]ueba" message "filas que cumplen la condicion matches ?[a-z]ueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[^r-s]ueba" message "filas que cumplen la condicion matches ?[^r-s]ueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[rs]ueba" message "filas que cumplen la condicion matches ?[rs]ueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[^rs]ueba" message "filas que cumplen la condicion matches ?[^rs]ueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[a-z123456789A-Z]ueba" message "filas que cumplen la condicion matches ?[a-z123456789A-Z]ueba : ",dos select count(*) into dos from prueba1 where campo1 matches "?[a-zA-Z123456789]ueba" message "filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : ",dos end main

289

CDIGO OBJETO: OPERSQL.4GL CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class opersql { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos");

campo5 date ) "); campo3 date ) ");

ASGcondb.HayTransac(); String uno ; int dos ; double tres ; java.sql.Date fecha , fecha2 ; fecha2 = null; fecha = null; uno = ""; dos = 0; tres = 0.0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 smallint , campo3 decimal(10,2) , campo4 date , ASGcondb.exeUpdate("create table prueba2 ( campo5 char(20) , campo4 smallint , campo1 decimal(10,2) , campo2 date ,

290

");

ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 1 , 8.2 , today , '31/12/2007' ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'otra Cosa' , 2 , 3 , today , '31/12/2007' ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'Prueba' , 3 , 1 , today , today ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 'prueba' , 2 , 10 , today , today ) "); ASGcondb.exeSelectSimple("select tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select informix.tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select informix.prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select e.campo1 , f.campo1 , g.campo1 from prueba1 e , prueba2 f , tabla99 g "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo3 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r1.next(); tres = ASG_r1.getDouble(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("resultado sumar dos nmeros: " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select campo4 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); dos = 2 ; Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select campo4 + "+ dos +" from prueba1 where campo2 = 1 "); try { ASG_r3.next(); fecha = ASG_r3.getDate(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select '31/12/2007' - campo4 from prueba1 where campo2 = 1 "); try { ASG_r4.next(); dos = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("resultado restar dos fechas: " + dos ); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select {d '"+ fecha +"'} - campo4 from prueba1 where campo2 = 1 try {

");

} catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println("resultado restar dos fechas: " + dos ); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 3 , 5 , {d '"+ fecha +"'} , today ) "); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select {d '"+ fecha +"'} - campo4 from prueba1 where campo2 try {

ASG_r5.next(); dos = ASG_r5.getInt(1);

= 2

ASG_r6.next(); dos = ASG_r6.getInt(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select campo5 - campo4 try { ASG_r7.next(); dos = ASG_r7.getInt(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st8 = ASGcondb.retCon().createStatement();

from prueba1 where campo2

= 2

");

");

ResultSet ASG_r8 = ASG_st8.executeQuery("select try {

{d '"+ fecha +"'}

- today

from prueba1 where campo2

= 2

291

");

ASG_r8.next(); dos = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select campo4 from prueba1 where campo2 = 1 "); try { ASG_r9.next(); fecha2 = ASG_r9.getDate(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println("fecha fila1: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select campo4 from prueba1 where campo2 = 2 "); try { ASG_r10.next(); fecha2 = ASG_r10.getDate(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println("fecha fila2: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select campo4 from prueba1 where campo2 = 3 "); try { ASG_r11.next(); fecha2 = ASG_r11.getDate(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println("fecha fila3: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo2 ) from prueba1 where campo4 < {d '"+ fecha +"'} try {

ASG_r12.next(); dos = ASG_r12.getInt(1); } catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println("nmero de filas con fecha menor que: " + ASGfaux.formato_fecha(fecha) + " = " + dos ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( * ) from prueba1 where campo2 between 1 and 2 "); try { ASG_r13.next(); dos = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println("nmero de filas con campo2 entre 1 y 2: " + dos ); Statement ASG_st14 = ASGcondb.retCon().createStatement(); ResultSet ASG_r14 = ASG_st14.executeQuery("select campo3 from prueba1 where exists ( select campo2 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r14.next(); tres = ASG_r14.getDouble(1); } catch (SQLException e) {} ASG_r14.close(); ASG_st14.close(); System.out.println("resultado exist: " + tres ); Statement ASG_st15 = ASGcondb.retCon().createStatement(); ResultSet ASG_r15 = ASG_st15.executeQuery("select campo3 from prueba1 where campo2 in ( select campo4 from prueba2 ) "); try { ASG_r15.next(); tres = ASG_r15.getDouble(1); } catch (SQLException e) {} ASG_r15.close(); ASG_st15.close(); System.out.println("resultado in: " + tres ); Statement ASG_st16 = ASGcondb.retCon().createStatement(); ResultSet ASG_r16 = ASG_st16.executeQuery("select sum ( campo3 ) from prueba1 where campo2 in ( 1 , 2 , 3 , 4 , 6 ) "); try { ASG_r16.next(); tres = ASG_r16.getDouble(1); } catch (SQLException e) {} ASG_r16.close(); ASG_st16.close(); System.out.println("resultado in: " + tres ); Statement ASG_st17 = ASGcondb.retCon().createStatement(); ResultSet ASG_r17 = ASG_st17.executeQuery("select sum ( campo3 ) from prueba1 where campo2 not in ( select campo4 from prueba2 ) "); try { ASG_r17.next();

campo4

campo4

campo4

");

} catch (SQLException e) {} ASG_r17.close(); ASG_st17.close(); System.out.println("resultado not in: " + tres ); Statement ASG_st18 = ASGcondb.retCon().createStatement(); ResultSet ASG_r18 = ASG_st18.executeQuery("select count ( * ) from try { ASG_r18.next(); dos = ASG_r18.getInt(1); } catch (SQLException e) {} ASG_r18.close(); ASG_st18.close(); System.out.println("filas con valores nulos: " + dos ); Statement ASG_st19 = ASGcondb.retCon().createStatement(); ResultSet ASG_r19 = ASG_st19.executeQuery("select count ( * ) from try { ASG_r19.next(); dos = ASG_r19.getInt(1); } catch (SQLException e) {} ASG_r19.close(); ASG_st19.close(); System.out.println("filas con valores no nulos: " + dos ); Statement ASG_st20 = ASGcondb.retCon().createStatement(); ResultSet ASG_r20 = ASG_st20.executeQuery("select sum ( campo3 ) from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r20.next(); tres = ASG_r20.getDouble(1); } catch (SQLException e) {} ASG_r20.close(); ASG_st20.close(); System.out.println("resultado any: " + tres ); Statement ASG_st21 = ASGcondb.retCon().createStatement(); ResultSet ASG_r21 = ASG_st21.executeQuery("select sum ( campo3 ) from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r21.next(); tres = ASG_r21.getDouble(1); } catch (SQLException e) {} ASG_r21.close(); ASG_st21.close(); System.out.println("resultado some: " + tres ); Statement ASG_st22 = ASGcondb.retCon().createStatement(); ResultSet ASG_r22 = ASG_st22.executeQuery("select sum ( campo3 ) from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r22.next(); tres = ASG_r22.getDouble(1); } catch (SQLException e) {} ASG_r22.close(); ASG_st22.close(); System.out.println("resultado all: " + tres ); Statement ASG_st23 = ASGcondb.retCon().createStatement(); ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) try { ASG_r23.next(); dos = ASG_r23.getInt(1); } catch (SQLException e) {} ASG_r23.close(); ASG_st23.close(); System.out.println("filas que cumplen la condicion matches P* escape $ Statement ASG_st24 = ASGcondb.retCon().createStatement(); ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from try {

tres = ASG_r17.getDouble(1);

292

prueba1 where campo1

is null ");

prueba1 where campo1

is not null ");

from prueba1 where campo2

> any ( select

from prueba1 where campo2

>= some ( select

from prueba1 where campo2

> all ( select

from prueba1 where campo1

matches 'P*'

");

: " + dos ); prueba1 where campo1 not like 'P%' escape '\\'

'\\'

");

ASG_r24.next(); dos = ASG_r24.getInt(1); } catch (SQLException e) {} ASG_r24.close(); ASG_st24.close(); System.out.println("filas que cumplen la condicion not like P% : " + dos ); Statement ASG_st25 = ASGcondb.retCon().createStatement(); ResultSet ASG_r25 = ASG_st25.executeQuery("select count ( * ) from prueba1 where campo1 not try {

like '_rueba' escape

ASG_r25.next(); dos = ASG_r25.getInt(1); } catch (SQLException e) {} ASG_r25.close(); ASG_st25.close(); System.out.println("filas que cumplen la condicion not like _rueba : " + dos ); Statement ASG_st26 = ASGcondb.retCon().createStatement(); ResultSet ASG_r26 = ASG_st26.executeQuery("select count ( * ) from prueba1 where campo1 try { ASG_r26.next(); dos = ASG_r26.getInt(1); } catch (SQLException e) {} ASG_r26.close(); ASG_st26.close();

matches '?[a-z]ueba'

");

");

System.out.println("filas que cumplen la condicion matches ?[a-z]ueba : " + dos ); Statement ASG_st27 = ASGcondb.retCon().createStatement(); ResultSet ASG_r27 = ASG_st27.executeQuery("select count ( * ) from prueba1 where campo1 try {

293
matches '?[^r-s]ueba'

Z]ueba'

");

ASG_r27.next(); dos = ASG_r27.getInt(1); } catch (SQLException e) {} ASG_r27.close(); ASG_st27.close(); System.out.println("filas que cumplen la condicion matches Statement ASG_st28 = ASGcondb.retCon().createStatement(); ResultSet ASG_r28 = ASG_st28.executeQuery("select count ( try { ASG_r28.next(); dos = ASG_r28.getInt(1); } catch (SQLException e) {} ASG_r28.close(); ASG_st28.close(); System.out.println("filas que cumplen la condicion matches Statement ASG_st29 = ASGcondb.retCon().createStatement(); ResultSet ASG_r29 = ASG_st29.executeQuery("select count ( try { ASG_r29.next(); dos = ASG_r29.getInt(1); } catch (SQLException e) {} ASG_r29.close(); ASG_st29.close(); System.out.println("filas que cumplen la condicion matches Statement ASG_st30 = ASGcondb.retCon().createStatement(); ResultSet ASG_r30 = ASG_st30.executeQuery("select count ( try {

?[^r-s]ueba : " + dos ); * ) from prueba1 where campo1 matches '?[rs]ueba' ");

?[rs]ueba : " + dos ); * ) from prueba1 where campo1 matches '?[^rs]ueba' ");

?[^rs]ueba : " + dos ); * ) from prueba1 where campo1 matches '?[a-z123456789A-

Z123456789]ueba'

ASG_r30.next(); dos = ASG_r30.getInt(1); } catch (SQLException e) {} ASG_r30.close(); ASG_st30.close(); System.out.println("filas que cumplen la condicion matches ?[a-z123456789A-Z]ueba : " + dos ); Statement ASG_st31 = ASGcondb.retCon().createStatement(); ResultSet ASG_r31 = ASG_st31.executeQuery("select count ( * ) from prueba1 where campo1 matches '?[a-zA"); try { ASG_r31.next(); dos = ASG_r31.getInt(1); } catch (SQLException e) {} ASG_r31.close(); ASG_st31.close(); System.out.println("filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : " + dos );

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class opersql { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; int dos ; double tres ; java.sql.Date fecha , fecha2 ; fecha2 = null; fecha = null; uno = ""; dos = 0; tres = 0.0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 smallint , campo3 decimal(10,2) , campo4 datetime , campo5 datetime ) "); ASGcondb.exeUpdate("create table prueba2 ( campo5 char(20) , campo4 smallint , campo1 decimal(10,2) , campo2 datetime , campo3 datetime ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 1 , 8.2 , dateadd(dd,0, datediff(dd,0,getdate())) , convert(datetime,'31/12/2007',103) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'otra Cosa' , 2 , 3 , dateadd(dd,0, datediff(dd,0,getdate())) , convert(datetime,'31/12/2007',103) ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'Prueba' , 3 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , dateadd(dd,0, datediff(dd,0,getdate())) ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 'prueba' , 2 , 10 , dateadd(dd,0, datediff(dd,0,getdate())) , dateadd(dd,0, datediff(dd,0,getdate())) ) "); ASGcondb.exeSelectSimple("select tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select informix.tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select informix.prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select e.campo1 , f.campo1 , g.campo1 from prueba1 e , prueba2 f , tabla99 g "); Statement ASG_st1 = ASGcondb.retCon().createStatement();

");

ResultSet ASG_r1 = ASG_st1.executeQuery("select try {

campo3

+ campo2

+ 1

from prueba1 where campo2

= 1

294

ASG_r1.next(); tres = ASG_r1.getDouble(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("resultado sumar dos nmeros: " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select campo4 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); dos = 2 ; Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select campo4 + "+ dos +" from prueba1 where campo2 = 1 "); try { ASG_r3.next(); fecha = ASG_r3.getDate(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select datediff(dd,campo4 ,convert(datetime,'31/12/2007',103) ) from prueba1 where campo2 = 1 "); try { ASG_r4.next(); dos = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("resultado restar dos fechas: " + dos ); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select datediff(dd,campo4 ,{d '"+ fecha +"'} ) from prueba1 where campo2 = 1 "); try { ASG_r5.next(); dos = ASG_r5.getInt(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println("resultado restar dos fechas: " + dos ); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 3 , 5 , {d '"+ fecha +"'} , dateadd(dd,0, datediff(dd,0,getdate())) ) "); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select datediff(dd,campo4 ,{d '"+ fecha +"'} ) from prueba1 where campo2 = 2 "); try { ASG_r6.next(); dos = ASG_r6.getInt(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select datediff(dd,campo4 ,campo5 ) from prueba1 where campo2 = 2 "); try { ASG_r7.next(); dos = ASG_r7.getInt(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select datediff(dd,dateadd(dd,0, datediff(dd,0,getdate())) ,{d '"+ fecha +"'} ) from prueba1 where campo2 = 2 "); try { ASG_r8.next(); dos = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select campo4 from prueba1 where campo2 = 1 "); try { ASG_r9.next(); fecha2 = ASG_r9.getDate(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println("fecha fila1: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select campo4 from prueba1 where campo2 = 2 ");

try {

295
ASG_r10.next(); fecha2 = ASG_r10.getDate(1);

");

} catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println("fecha fila2: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select campo4 from prueba1 where campo2 = 3 "); try { ASG_r11.next(); fecha2 = ASG_r11.getDate(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println("fecha fila3: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo2 ) from prueba1 where campo4 < {d '"+ fecha +"'} try {

} catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println("nmero de filas con fecha menor que: " + ASGfaux.formato_fecha(fecha) + " = " + dos ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( * ) from prueba1 where campo2 between 1 and 2 "); try { ASG_r13.next(); dos = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println("nmero de filas con campo2 entre 1 y 2: " + dos ); Statement ASG_st14 = ASGcondb.retCon().createStatement(); ResultSet ASG_r14 = ASG_st14.executeQuery("select campo3 from prueba1 where exists ( select campo2 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r14.next(); tres = ASG_r14.getDouble(1); } catch (SQLException e) {} ASG_r14.close(); ASG_st14.close(); System.out.println("resultado exist: " + tres ); Statement ASG_st15 = ASGcondb.retCon().createStatement(); ResultSet ASG_r15 = ASG_st15.executeQuery("select campo3 from prueba1 where campo2 in ( select campo4 from prueba2 ) "); try { ASG_r15.next(); tres = ASG_r15.getDouble(1); } catch (SQLException e) {} ASG_r15.close(); ASG_st15.close(); System.out.println("resultado in: " + tres ); Statement ASG_st16 = ASGcondb.retCon().createStatement(); ResultSet ASG_r16 = ASG_st16.executeQuery("select sum ( campo3 ) from prueba1 where campo2 in ( 1 , 2 , 3 , 4 , 6 ) "); try { ASG_r16.next(); tres = ASG_r16.getDouble(1); } catch (SQLException e) {} ASG_r16.close(); ASG_st16.close(); System.out.println("resultado in: " + tres ); Statement ASG_st17 = ASGcondb.retCon().createStatement(); ResultSet ASG_r17 = ASG_st17.executeQuery("select sum ( campo3 ) from prueba1 where campo2 not in ( select campo4 from prueba2 ) "); try { ASG_r17.next(); tres = ASG_r17.getDouble(1); } catch (SQLException e) {} ASG_r17.close(); ASG_st17.close(); System.out.println("resultado not in: " + tres ); Statement ASG_st18 = ASGcondb.retCon().createStatement(); ResultSet ASG_r18 = ASG_st18.executeQuery("select count ( * ) from prueba1 where campo1 is null "); try { ASG_r18.next(); dos = ASG_r18.getInt(1); } catch (SQLException e) {} ASG_r18.close(); ASG_st18.close(); System.out.println("filas con valores nulos: " + dos ); Statement ASG_st19 = ASGcondb.retCon().createStatement(); ResultSet ASG_r19 = ASG_st19.executeQuery("select count ( * ) from prueba1 where campo1 is not null "); try { ASG_r19.next(); dos = ASG_r19.getInt(1); }

ASG_r12.next(); dos = ASG_r12.getInt(1);

campo4

campo4

campo4

");

catch (SQLException e) {} ASG_r19.close(); ASG_st19.close(); System.out.println("filas con valores no nulos: " + dos ); Statement ASG_st20 = ASGcondb.retCon().createStatement(); ResultSet ASG_r20 = ASG_st20.executeQuery("select sum ( campo3 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r20.next(); tres = ASG_r20.getDouble(1); } catch (SQLException e) {} ASG_r20.close(); ASG_st20.close(); System.out.println("resultado any: " + tres ); Statement ASG_st21 = ASGcondb.retCon().createStatement(); ResultSet ASG_r21 = ASG_st21.executeQuery("select sum ( campo3 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r21.next(); tres = ASG_r21.getDouble(1); } catch (SQLException e) {} ASG_r21.close(); ASG_st21.close(); System.out.println("resultado some: " + tres ); Statement ASG_st22 = ASGcondb.retCon().createStatement(); ResultSet ASG_r22 = ASG_st22.executeQuery("select sum ( campo3 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r22.next(); tres = ASG_r22.getDouble(1); } catch (SQLException e) {} ASG_r22.close(); ASG_st22.close(); System.out.println("resultado all: " + tres ); Statement ASG_st23 = ASGcondb.retCon().createStatement(); ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 try {

296

from prueba1 where campo2

> any ( select

from prueba1 where campo2

>= some ( select

from prueba1 where campo2

> all ( select

from prueba1 where campo1

like 'P%' escape '$'

");

} catch (SQLException e) {} ASG_r23.close(); ASG_st23.close(); System.out.println("filas que cumplen la condicion matches P* escape $ : " + dos ); Statement ASG_st24 = ASGcondb.retCon().createStatement(); ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not try {

ASG_r23.next(); dos = ASG_r23.getInt(1);

like 'P%' escape '\\'

'\\'

");

} catch (SQLException e) {} ASG_r24.close(); ASG_st24.close(); System.out.println("filas que cumplen la condicion not like P% : " + dos ); Statement ASG_st25 = ASGcondb.retCon().createStatement(); ResultSet ASG_r25 = ASG_st25.executeQuery("select count ( * ) from prueba1 where campo1 not try {

ASG_r24.next(); dos = ASG_r24.getInt(1);

like '_rueba' escape

'\\'

");

ASG_r25.next(); dos = ASG_r25.getInt(1); } catch (SQLException e) {} ASG_r25.close(); ASG_st25.close(); System.out.println("filas que cumplen la condicion not like _rueba : " + dos ); Statement ASG_st26 = ASGcondb.retCon().createStatement(); ResultSet ASG_r26 = ASG_st26.executeQuery("select count ( * ) from prueba1 where campo1 try {

like '_[a-z]ueba' escape

'\\'

");

} catch (SQLException e) {} ASG_r26.close(); ASG_st26.close(); System.out.println("filas que cumplen la condicion matches ?[a-z]ueba : " + dos ); Statement ASG_st27 = ASGcondb.retCon().createStatement(); ResultSet ASG_r27 = ASG_st27.executeQuery("select count ( * ) from prueba1 where campo1 try {

ASG_r26.next(); dos = ASG_r26.getInt(1);

like '_[^r-s]ueba' escape

'\\'

");

ASG_r27.next(); dos = ASG_r27.getInt(1); } catch (SQLException e) {} ASG_r27.close(); ASG_st27.close(); System.out.println("filas que cumplen la condicion matches ?[^r-s]ueba : " + dos ); Statement ASG_st28 = ASGcondb.retCon().createStatement(); ResultSet ASG_r28 = ASG_st28.executeQuery("select count ( * ) from prueba1 where campo1 try {

like '_[rs]ueba' escape

ASG_r28.next(); dos = ASG_r28.getInt(1); } catch (SQLException e) {}

'\\'

");

ASG_r28.close(); ASG_st28.close(); System.out.println("filas que cumplen la condicion matches ?[rs]ueba : " + dos ); Statement ASG_st29 = ASGcondb.retCon().createStatement(); ResultSet ASG_r29 = ASG_st29.executeQuery("select count ( * ) from prueba1 where campo1 try {

297

like '_[^rs]ueba' escape

} catch (SQLException e) {} ASG_r29.close(); ASG_st29.close(); System.out.println("filas que cumplen la condicion matches Statement ASG_st30 = ASGcondb.retCon().createStatement(); ResultSet ASG_r30 = ASG_st30.executeQuery("select count ( Z]ueba' escape '\\' "); try { ASG_r30.next(); dos = ASG_r30.getInt(1); } catch (SQLException e) {} ASG_r30.close(); ASG_st30.close(); System.out.println("filas que cumplen la condicion matches Statement ASG_st31 = ASGcondb.retCon().createStatement(); ResultSet ASG_r31 = ASG_st31.executeQuery("select count ( Z123456789]ueba' escape '\\' "); try { ASG_r31.next(); dos = ASG_r31.getInt(1); } catch (SQLException e) {} ASG_r31.close(); ASG_st31.close(); System.out.println("filas que cumplen la condicion matches } }

ASG_r29.next(); dos = ASG_r29.getInt(1);

?[^rs]ueba : " + dos ); * ) from prueba1 where campo1 like '_[a-z123456789A-

?[a-z123456789A-Z]ueba : " + dos ); * ) from prueba1 where campo1 like '_[a-zA-

?[a-zA-Z123456789]ueba : " + dos );

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class opersql { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; int dos ; double tres ; java.sql.Date fecha , fecha2 ; fecha2 = null; fecha = null; uno = ""; dos = 0; tres = 0.0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 cascade constraints"); ASGcondb.exeUpdate("drop table prueba2 cascade constraints"); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 smallint , campo3 decimal(10,2) , campo4 date , campo5 date ) "); ASGcondb.exeUpdate("create table prueba2 ( campo5 char(20) , campo4 smallint , campo1 decimal(10,2) , campo2 date , campo3 date ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 1 , 8.2 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date('31/12/2007','dd/mm/yyyy') ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'otra Cosa' , 2 , 3 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date('31/12/2007','dd/mm/yyyy') ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'Prueba' , 3 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date(to_char(sysdate,'dd/mm/yyyy')) ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 'prueba' , 2 , 10 , to_date(to_char(sysdate,'dd/mm/yyyy')) , to_date(to_char(sysdate,'dd/mm/yyyy')) ) "); ASGcondb.exeSelectSimple("select tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select informix.tabla99.campo2 from informix.tabla99 "); ASGcondb.exeSelectSimple("select informix.prueba1.campo2 from informix.prueba1 "); ASGcondb.exeSelectSimple("select e.campo1 , f.campo1 , g.campo1 from prueba1 e , prueba2 f , tabla99 g "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo3 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r1.next(); tres = ASG_r1.getDouble(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("resultado sumar dos nmeros: " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select campo4 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close();

campo2

= 1

");

System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); dos = 2 ; Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select campo4 + "+ dos +" from prueba1 where campo2 = 1 "); try { ASG_r3.next(); fecha = ASG_r3.getDate(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select to_date('31/12/2007','dd/mm/yyyy') - campo4 from prueba1 where try {

298

");

} catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("resultado restar dos fechas: " + dos ); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select {d '"+ fecha +"'} try {

ASG_r4.next(); dos = ASG_r4.getInt(1);

- campo4

from prueba1 where campo2

= 1

ASG_r5.next(); dos = ASG_r5.getInt(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println("resultado restar dos fechas: " + dos ); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 3 , 5 , {d '"+ fecha +"'} , to_date(to_char(sysdate,'dd/mm/yyyy')) ) "); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select {d '"+ fecha +"'} - campo4 from prueba1 where campo2 "); try { ASG_r6.next(); dos = ASG_r6.getInt(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select campo5 - campo4 from prueba1 where campo2 = 2 "); try { ASG_r7.next(); dos = ASG_r7.getInt(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select {d '"+ fecha +"'} - to_date(to_char(sysdate,'dd/mm/yyyy')) prueba1 where campo2 = 2 "); try { ASG_r8.next(); dos = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select campo4 from prueba1 where campo2 = 1 "); try { ASG_r9.next(); fecha2 = ASG_r9.getDate(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println("fecha fila1: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select campo4 from prueba1 where campo2 = 2 "); try { ASG_r10.next(); fecha2 = ASG_r10.getDate(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println("fecha fila2: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select campo4 from prueba1 where campo2 = 3 "); try { ASG_r11.next(); fecha2 = ASG_r11.getDate(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println("fecha fila3: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st12 = ASGcondb.retCon().createStatement();

= 2

from

+"'}

");

ResultSet ASG_r12 = ASG_st12.executeQuery("select try {

count ( campo2 )

from prueba1 where campo4

< {d '"+ fecha

299

ASG_r12.next(); dos = ASG_r12.getInt(1); } catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println("nmero de filas con fecha menor que: " + ASGfaux.formato_fecha(fecha) + " = " + dos ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( * ) from prueba1 where campo2 between 1 and 2 "); try { ASG_r13.next(); dos = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println("nmero de filas con campo2 entre 1 y 2: " + dos ); Statement ASG_st14 = ASGcondb.retCon().createStatement(); ResultSet ASG_r14 = ASG_st14.executeQuery("select campo3 from prueba1 where exists ( select campo2 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r14.next(); tres = ASG_r14.getDouble(1); } catch (SQLException e) {} ASG_r14.close(); ASG_st14.close(); System.out.println("resultado exist: " + tres ); Statement ASG_st15 = ASGcondb.retCon().createStatement(); ResultSet ASG_r15 = ASG_st15.executeQuery("select campo3 from prueba1 where campo2 in ( select campo4 from prueba2 ) "); try { ASG_r15.next(); tres = ASG_r15.getDouble(1); } catch (SQLException e) {} ASG_r15.close(); ASG_st15.close(); System.out.println("resultado in: " + tres ); Statement ASG_st16 = ASGcondb.retCon().createStatement(); ResultSet ASG_r16 = ASG_st16.executeQuery("select sum ( campo3 ) from prueba1 where campo2 in ( 1 , 2 , 3 , 4 , 6 ) "); try { ASG_r16.next(); tres = ASG_r16.getDouble(1); } catch (SQLException e) {} ASG_r16.close(); ASG_st16.close(); System.out.println("resultado in: " + tres ); Statement ASG_st17 = ASGcondb.retCon().createStatement(); ResultSet ASG_r17 = ASG_st17.executeQuery("select sum ( campo3 ) from prueba1 where campo2 not in ( select campo4 from prueba2 ) "); try { ASG_r17.next(); tres = ASG_r17.getDouble(1); } catch (SQLException e) {} ASG_r17.close(); ASG_st17.close(); System.out.println("resultado not in: " + tres ); Statement ASG_st18 = ASGcondb.retCon().createStatement(); ResultSet ASG_r18 = ASG_st18.executeQuery("select count ( * ) from prueba1 where campo1 is null "); try { ASG_r18.next(); dos = ASG_r18.getInt(1); } catch (SQLException e) {} ASG_r18.close(); ASG_st18.close(); System.out.println("filas con valores nulos: " + dos ); Statement ASG_st19 = ASGcondb.retCon().createStatement(); ResultSet ASG_r19 = ASG_st19.executeQuery("select count ( * ) from prueba1 where campo1 is not null "); try { ASG_r19.next(); dos = ASG_r19.getInt(1); } catch (SQLException e) {} ASG_r19.close(); ASG_st19.close(); System.out.println("filas con valores no nulos: " + dos ); Statement ASG_st20 = ASGcondb.retCon().createStatement(); ResultSet ASG_r20 = ASG_st20.executeQuery("select sum ( campo3 ) from prueba1 where campo2 > any ( select campo4 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r20.next(); tres = ASG_r20.getDouble(1); } catch (SQLException e) {} ASG_r20.close(); ASG_st20.close(); System.out.println("resultado any: " + tres ); Statement ASG_st21 = ASGcondb.retCon().createStatement(); ResultSet ASG_r21 = ASG_st21.executeQuery("select sum ( campo3 ) from prueba1 where campo2 >= some ( select campo4 from prueba2 where campo4 = prueba1.campo2 ) "); try {

campo4

");

} catch (SQLException e) {} ASG_r21.close(); ASG_st21.close(); System.out.println("resultado some: " + tres ); Statement ASG_st22 = ASGcondb.retCon().createStatement(); ResultSet ASG_r22 = ASG_st22.executeQuery("select sum ( campo3 ) from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r22.next(); tres = ASG_r22.getDouble(1); } catch (SQLException e) {} ASG_r22.close(); ASG_st22.close(); System.out.println("resultado all: " + tres ); Statement ASG_st23 = ASGcondb.retCon().createStatement(); ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) try {

ASG_r21.next(); tres = ASG_r21.getDouble(1);

300

from prueba1 where campo2

> all ( select

from prueba1 where campo1

like 'P%' escape '$'

");

} catch (SQLException e) {} ASG_r23.close(); ASG_st23.close(); System.out.println("filas que cumplen la condicion matches P* escape $ : " + dos ); Statement ASG_st24 = ASGcondb.retCon().createStatement(); ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not try {

ASG_r23.next(); dos = ASG_r23.getInt(1);

like 'P%' escape '\\'

'\\'

");

ASG_r24.next(); dos = ASG_r24.getInt(1); } catch (SQLException e) {} ASG_r24.close(); ASG_st24.close(); System.out.println("filas que cumplen la condicion not like P% : " + dos ); Statement ASG_st25 = ASGcondb.retCon().createStatement(); ResultSet ASG_r25 = ASG_st25.executeQuery("select count ( * ) from prueba1 where campo1 not try {

like '_rueba%' escape

'\\' ");

} catch (SQLException e) {} ASG_r25.close(); ASG_st25.close(); System.out.println("filas que cumplen la condicion not like _rueba : " + dos ); Statement ASG_st26 = ASGcondb.retCon().createStatement(); ResultSet ASG_r26 = ASG_st26.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') try {

ASG_r25.next(); dos = ASG_r25.getInt(1);

} catch (SQLException e) {} ASG_r26.close(); ASG_st26.close(); System.out.println("filas que cumplen la condicion matches ?[a-z]ueba : " + dos ); Statement ASG_st27 = ASGcondb.retCon().createStatement(); ResultSet ASG_r27 = ASG_st27.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) not in ('r','s') "); try { ASG_r27.next(); dos = ASG_r27.getInt(1); } catch (SQLException e) {} ASG_r27.close(); ASG_st27.close(); System.out.println("filas que cumplen la condicion matches ?[^r-s]ueba : " + dos ); Statement ASG_st28 = ASGcondb.retCon().createStatement(); ResultSet ASG_r28 = ASG_st28.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('r','s') "); try { ASG_r28.next(); dos = ASG_r28.getInt(1); } catch (SQLException e) {} ASG_r28.close(); ASG_st28.close(); System.out.println("filas que cumplen la condicion matches ?[rs]ueba : " + dos ); Statement ASG_st29 = ASGcondb.retCon().createStatement(); ResultSet ASG_r29 = ASG_st29.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) not in ('r','s') "); try { ASG_r29.next(); dos = ASG_r29.getInt(1); } catch (SQLException e) {} ASG_r29.close(); ASG_st29.close(); System.out.println("filas que cumplen la condicion matches ?[^rs]ueba : " + dos ); Statement ASG_st30 = ASGcondb.retCon().createStatement(); ResultSet ASG_r30 = ASG_st30.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8') ");

ASG_r26.next(); dos = ASG_r26.getInt(1);

try {

301
ASG_r30.next(); dos = ASG_r30.getInt(1);

} catch (SQLException e) {} ASG_r30.close(); ASG_st30.close(); System.out.println("filas que cumplen la condicion matches ?[a-z123456789A-Z]ueba : " + dos ); Statement ASG_st31 = ASGcondb.retCon().createStatement(); ResultSet ASG_r31 = ASG_st31.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9') "); try { ASG_r31.next(); dos = ASG_r31.getInt(1); } catch (SQLException e) {} ASG_r31.close(); ASG_st31.close(); System.out.println("filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : " + dos ); } }

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class opersql { static String hola ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; int dos ; double tres ; java.sql.Date fecha , fecha2 ; fecha2 = null; fecha = null; uno = ""; dos = 0; tres = 0.0; ASGcondb.activaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.exeUpdate("drop table prueba2 "); ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 char(20) , campo2 smallint , campo3 decimal(10,2) , campo4 date , campo5 date ) "); ASGcondb.exeUpdate("create table prueba2 ( campo5 char(20) , campo4 smallint , campo1 decimal(10,2) , campo2 date , campo3 date ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 1 , 8.2 , current date , date('31/12/2007') ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'otra Cosa' , 2 , 3 , current date , date('31/12/2007') ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 'Prueba' , 3 , 1 , current date , current date ) "); ASGcondb.exeUpdate("insert into prueba2 values ( 'prueba' , 2 , 10 , current date , current date ) "); ASGcondb.exeSelectSimple("select tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select informix.tabla99.campo2 from tabla99 "); ASGcondb.exeSelectSimple("select informix.prueba1.campo2 from prueba1 "); ASGcondb.exeSelectSimple("select e.campo1 , f.campo1 , g.campo1 from prueba1 e , prueba2 f , tabla99 g "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select campo3 + campo2 + 1 from prueba1 where campo2 = 1 "); try { ASG_r1.next(); tres = ASG_r1.getDouble(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println("resultado sumar dos nmeros: " + tres ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select campo4 + campo2 DAY + 1 DAY from prueba1 where campo2 = 1 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); dos = 2 ; Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select campo4 + "+ dos +" DAY from prueba1 where campo2 = 1 "); try { ASG_r3.next(); fecha = ASG_r3.getDate(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println("resultado sumar fecha y entero: " + ASGfaux.formato_fecha(fecha) ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select days(date('31/12/2007') ) - days(campo4 ) from prueba1 where campo2 = 1 "); try { ASG_r4.next();

campo2

= 1

");

} catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println("resultado restar dos fechas: " + dos ); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select days({d '"+ fecha +"'} ) - days(campo4 ) try {

dos = ASG_r4.getInt(1);

302

from prueba1 where

campo2

= 2

");

} catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println("resultado restar dos fechas: " + dos ); ASGcondb.exeUpdate("insert into prueba1 values ( 'prueba' , 3 , 5 , {d '"+ fecha +"'} , current date ) "); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select days({d '"+ fecha +"'} ) - days(campo4 ) from prueba1 where try {

ASG_r5.next(); dos = ASG_r5.getInt(1);

");

} catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select days(campo5 ) - days(campo4 ) try {

ASG_r6.next(); dos = ASG_r6.getInt(1);

from prueba1 where campo2

= 2

campo2

= 2

");

ASG_r7.next(); dos = ASG_r7.getInt(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select days({d '"+ fecha +"'} ) - days(current date ) try {

from prueba1 where

");

} catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println("resultado de restar dos fechas: " + dos ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select campo4 from prueba1 where campo2 = 1 "); try { ASG_r9.next(); fecha2 = ASG_r9.getDate(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println("fecha fila1: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select campo4 from prueba1 where campo2 = 2 "); try { ASG_r10.next(); fecha2 = ASG_r10.getDate(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println("fecha fila2: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select campo4 from prueba1 where campo2 = 3 "); try { ASG_r11.next(); fecha2 = ASG_r11.getDate(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println("fecha fila3: " + ASGfaux.formato_fecha(fecha2) ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo2 ) from prueba1 where campo4 < {d '"+ fecha +"'} try {

ASG_r8.next(); dos = ASG_r8.getInt(1);

ASG_r12.next(); dos = ASG_r12.getInt(1); } catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println("nmero de filas con fecha menor que: " + ASGfaux.formato_fecha(fecha) + " = " + dos ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( * ) from prueba1 where campo2 between 1 and 2 try { ASG_r13.next(); dos = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close();

");

ASG_st13.close(); System.out.println("nmero de filas con campo2 entre 1 y 2: " + dos ); Statement ASG_st14 = ASGcondb.retCon().createStatement(); ResultSet ASG_r14 = ASG_st14.executeQuery("select campo3 from prueba1 where exists ( select campo2 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r14.next(); tres = ASG_r14.getDouble(1); } catch (SQLException e) {} ASG_r14.close(); ASG_st14.close(); System.out.println("resultado exist: " + tres ); Statement ASG_st15 = ASGcondb.retCon().createStatement(); ResultSet ASG_r15 = ASG_st15.executeQuery("select campo3 from prueba1 where campo2 in ( select campo4 from prueba2 ) "); try { ASG_r15.next(); tres = ASG_r15.getDouble(1); } catch (SQLException e) {} ASG_r15.close(); ASG_st15.close(); System.out.println("resultado in: " + tres ); Statement ASG_st16 = ASGcondb.retCon().createStatement(); ResultSet ASG_r16 = ASG_st16.executeQuery("select sum ( campo3 ) from prueba1 where campo2 in ( 1 , 2 , 3 , 4 , 6 ) "); try { ASG_r16.next(); tres = ASG_r16.getDouble(1); } catch (SQLException e) {} ASG_r16.close(); ASG_st16.close(); System.out.println("resultado in: " + tres ); Statement ASG_st17 = ASGcondb.retCon().createStatement(); ResultSet ASG_r17 = ASG_st17.executeQuery("select sum ( campo3 ) from prueba1 where campo2 not in ( select campo4 from prueba2 ) "); try { ASG_r17.next(); tres = ASG_r17.getDouble(1); } catch (SQLException e) {} ASG_r17.close(); ASG_st17.close(); System.out.println("resultado not in: " + tres ); Statement ASG_st18 = ASGcondb.retCon().createStatement(); ResultSet ASG_r18 = ASG_st18.executeQuery("select count ( * ) from prueba1 where campo1 is null "); try { ASG_r18.next(); dos = ASG_r18.getInt(1); } catch (SQLException e) {} ASG_r18.close(); ASG_st18.close(); System.out.println("filas con valores nulos: " + dos ); Statement ASG_st19 = ASGcondb.retCon().createStatement(); ResultSet ASG_r19 = ASG_st19.executeQuery("select count ( * ) from prueba1 where campo1 is not null "); try { ASG_r19.next(); dos = ASG_r19.getInt(1); } catch (SQLException e) {} ASG_r19.close(); ASG_st19.close(); System.out.println("filas con valores no nulos: " + dos ); Statement ASG_st20 = ASGcondb.retCon().createStatement(); ResultSet ASG_r20 = ASG_st20.executeQuery("select sum ( campo3 ) from prueba1 where campo2 > any ( select campo4 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r20.next(); tres = ASG_r20.getDouble(1); } catch (SQLException e) {} ASG_r20.close(); ASG_st20.close(); System.out.println("resultado any: " + tres ); Statement ASG_st21 = ASGcondb.retCon().createStatement(); ResultSet ASG_r21 = ASG_st21.executeQuery("select sum ( campo3 ) from prueba1 where campo2 >= some ( select campo4 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r21.next(); tres = ASG_r21.getDouble(1); } catch (SQLException e) {} ASG_r21.close(); ASG_st21.close(); System.out.println("resultado some: " + tres ); Statement ASG_st22 = ASGcondb.retCon().createStatement(); ResultSet ASG_r22 = ASG_st22.executeQuery("select sum ( campo3 ) from prueba1 where campo2 > all ( select campo4 from prueba2 where campo4 = prueba1.campo2 ) "); try { ASG_r22.next(); tres = ASG_r22.getDouble(1); } catch (SQLException e) {} ASG_r22.close(); ASG_st22.close(); System.out.println("resultado all: " + tres ); Statement ASG_st23 = ASGcondb.retCon().createStatement();

303

escape '$'

");

ResultSet ASG_r23 = ASG_st23.executeQuery("select try {

count ( campo2 )

from prueba1 where campo1

like 'P%'

304

");

ASG_r23.next(); dos = ASG_r23.getInt(1); } catch (SQLException e) {} ASG_r23.close(); ASG_st23.close(); System.out.println("filas que cumplen la condicion matches P* escape $ : " + dos ); Statement ASG_st24 = ASGcondb.retCon().createStatement(); ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not try {

like 'P%' escape '\\'

'\\'

");

ASG_r24.next(); dos = ASG_r24.getInt(1); } catch (SQLException e) {} ASG_r24.close(); ASG_st24.close(); System.out.println("filas que cumplen la condicion not like P% : " + dos ); Statement ASG_st25 = ASGcondb.retCon().createStatement(); ResultSet ASG_r25 = ASG_st25.executeQuery("select count ( * ) from prueba1 where campo1 not try {

like '_rueba%' escape

'\\' ");

} catch (SQLException e) {} ASG_r25.close(); ASG_st25.close(); System.out.println("filas que cumplen la condicion not like _rueba : " + dos ); Statement ASG_st26 = ASGcondb.retCon().createStatement(); ResultSet ASG_r26 = ASG_st26.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z') try {

ASG_r25.next(); dos = ASG_r25.getInt(1);

} catch (SQLException e) {} ASG_r26.close(); ASG_st26.close(); System.out.println("filas que cumplen la condicion matches ?[a-z]ueba : " + dos ); Statement ASG_st27 = ASGcondb.retCon().createStatement(); ResultSet ASG_r27 = ASG_st27.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) not in ('r','s') "); try { ASG_r27.next(); dos = ASG_r27.getInt(1); } catch (SQLException e) {} ASG_r27.close(); ASG_st27.close(); System.out.println("filas que cumplen la condicion matches ?[^r-s]ueba : " + dos ); Statement ASG_st28 = ASGcondb.retCon().createStatement(); ResultSet ASG_r28 = ASG_st28.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('r','s') "); try { ASG_r28.next(); dos = ASG_r28.getInt(1); } catch (SQLException e) {} ASG_r28.close(); ASG_st28.close(); System.out.println("filas que cumplen la condicion matches ?[rs]ueba : " + dos ); Statement ASG_st29 = ASGcondb.retCon().createStatement(); ResultSet ASG_r29 = ASG_st29.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) not in ('r','s') "); try { ASG_r29.next(); dos = ASG_r29.getInt(1); } catch (SQLException e) {} ASG_r29.close(); ASG_st29.close(); System.out.println("filas que cumplen la condicion matches ?[^rs]ueba : " + dos ); Statement ASG_st30 = ASGcondb.retCon().createStatement(); ResultSet ASG_r30 = ASG_st30.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8') "); try { ASG_r30.next(); dos = ASG_r30.getInt(1); } catch (SQLException e) {} ASG_r30.close(); ASG_st30.close(); System.out.println("filas que cumplen la condicion matches ?[a-z123456789A-Z]ueba : " + dos ); Statement ASG_st31 = ASGcondb.retCon().createStatement(); ResultSet ASG_r31 = ASG_st31.executeQuery("select count ( * ) from prueba1 where campo1 like '__ueba%' escape '\\' and substr(campo1,2,1) in ('a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','1','2','3','4','5','6','7','8','9') "); try { ASG_r31.next(); dos = ASG_r31.getInt(1); } catch (SQLException e) {}

ASG_r26.next(); dos = ASG_r26.getInt(1);

ASG_r31.close(); ASG_st31.close(); System.out.println("filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : " + dos );

305

EJEMPLO DE MANEJO DE CONSTANTES TIPO FECHA


CDIGO FUENTE INFORMIX-4GL: CTESFECHA.4GL
#Expresiones SQL #expresion de manejo de constantes tipo fecha database datos define fecha date define fechahora datetime year to fraction main define uno char(20), dos date, tres datetime year to fraction, cuatro integer, cinco decimal(12,2)

whenever error stop drop table prueba1 whenever error continue create table prueba1 ( campo1 integer, campo2 decimal(20,0), campo3 date, campo4 datetime year to fraction ) #ctes fecha nmero let dos = 1; message dos insert into prueba1 values (1,1,today,current); insert into prueba1 values (2,1,dos,current); let dos = date (39378) message dos let cuatro = 39378 let dos = date (cuatro) message dos insert into prueba1 values (3,40000,dos,current); select date(campo1) into fecha from prueba1 where campo1 = 3 message fecha select date(39379) into fecha from prueba1 where campo1 = 3 message fecha select count(campo1) into cuatro from prueba1 where campo3 > message cuatro 39376

select count(campo1) into cuatro from prueba1 where 39376 > campo3 message cuatro #ctes fecha cadena let dos = "01/01/1900"; message dos insert into prueba1 values (1,1,today,current); insert into prueba1 values (2,1,dos,current); let dos = date ("24/10/2007") message dos let dos = "24/10/2007" let dos = date (dos) message dos insert into prueba1 values (3,40000,dos,current); select date(campo1) into fecha from prueba1 where campo1 = 3 message fecha select date("25/10/2007") into fecha from prueba1 where campo1 = 3 message fecha select date(today) into fecha from prueba1 where campo1 = 3 message fecha select count(campo1) into cuatro from prueba1 where campo3 > "22/10/2007" message cuatro select count(campo1) into cuatro from prueba1 where "22/10/2007" > campo3 message cuatro #ctes fecha/hora cadena let tres = "1900-01-01 00:00:00" message tres insert into prueba1 values (1,1,today,current); insert into prueba1 values (2,1,today,tres); let tres = date ("2007-10-24 00:00:00") message tres let tres = "2007-10-24 00:00:00" let tres = date (tres) message tres

306
insert into prueba1 values (3,40000,dos,tres); select date(campo3) into fechahora from prueba1 where campo1 = 3 message fechahora select date(current) into fechahora from prueba1 where campo1 = 3 message fechahora select count(campo1) into cuatro from prueba1 where campo4 > "2007-10-22 00:00:00.0" message cuatro select count(campo1) into cuatro from prueba1 where "2007-10-22 00:00:00.0" > campo4 message cuatro end main

CDIGO OBJETO: CTESFECHA.JAVA CDIGO OBJETO INFORMIX


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class ctesfecha { static java.sql.Date fecha ; static java.sql.Timestamp fechahora ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; uno = ""; dos = null; tres = null; ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 integer , campo2 decimal(20,0) , campo3 date , campo4 datetime year to fraction ) "); dos = ASGfaux.cteIntToFechaJ(1) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , today , current ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , current ) "); dos = ASGfaux.fecha( 39378 ) ; System.out.println(ASGfaux.formato_fecha(dos) ); cuatro = 39378 ; dos = ASGfaux.fecha( cuatro ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , current ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select date( campo1 ) from prueba1 where campo1 = 3 "); try { ASG_r1.next(); fecha = ASG_r1.getDate(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select date( 39379 ) from prueba1 where campo1 = 3 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( campo1 ) from prueba1 where campo3 > 39376 "); try { ASG_r3.next(); cuatro = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println(cuatro ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( campo1 ) from prueba1 where 39376 > campo3 "); try { ASG_r4.next(); cuatro = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println(cuatro ); dos = ASGfaux.fecha("01/01/1900") ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , today , current ) ");

00:00:00.0'

");

ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , current ) "); dos = ASGfaux.fecha( ASGfaux.fecha("24/10/2007") ) ; System.out.println(ASGfaux.formato_fecha(dos) ); dos = ASGfaux.fecha("24/10/2007") ; dos = ASGfaux.fecha( dos ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , current ) "); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select date( campo1 ) from prueba1 where campo1 = 3 "); try { ASG_r5.next(); fecha = ASG_r5.getDate(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select date( '25/10/2007' ) from prueba1 where campo1 = 3 "); try { ASG_r6.next(); fecha = ASG_r6.getDate(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select date( today ) from prueba1 where campo1 = 3 "); try { ASG_r7.next(); fecha = ASG_r7.getDate(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select count ( campo1 ) from prueba1 where campo3 > '22/10/2007' "); try { ASG_r8.next(); cuatro = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println(cuatro ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select count ( campo1 ) from prueba1 where '22/10/2007' > campo3 "); try { ASG_r9.next(); cuatro = ASG_r9.getInt(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println(cuatro ); tres = ASGfaux.fechahora("1900-01-01 00:00:00") ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , today , current ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , today , {ts '"+ tres +"'} ) "); tres = ASGfaux.fecha( ASGfaux.fechahora("2007-10-24 00:00:00") ) ; System.out.println(tres ); tres = ASGfaux.fechahora("2007-10-24 00:00:00") ; tres = ASGfaux.fecha( tres ) ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , {ts '"+ tres +"'} ) "); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select date( campo3 ) from prueba1 where campo1 = 3 "); try { ASG_r10.next(); fechahora = ASG_r10.getTimestamp(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println(fechahora ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select date( current ) from prueba1 where campo1 = 3 "); try { ASG_r11.next(); fechahora = ASG_r11.getTimestamp(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println(fechahora ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo1 ) from prueba1 where campo4 > '2007-10-22 try {

307

campo4

");

ASG_r12.next(); cuatro = ASG_r12.getInt(1); } catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println(cuatro ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( campo1 )

from prueba1 where '2007-10-22 00:00:00.0'

>

try {

308
ASG_r13.next(); cuatro = ASG_r13.getInt(1);

} catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println(cuatro );

CDIGO OBJETO SQLSERVER


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class ctesfecha { static java.sql.Date fecha ; static java.sql.Timestamp fechahora ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; uno = ""; dos = null; tres = null; ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 integer , campo2 decimal(20,0) , campo3 datetime , campo4 datetime ) "); dos = ASGfaux.cteIntToFechaJ(1) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , getdate() ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , getdate() ) "); dos = ASGfaux.fecha( 39378 ) ; System.out.println(ASGfaux.formato_fecha(dos) ); cuatro = 39378 ; dos = ASGfaux.fecha( cuatro ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , getdate() ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select convert(datetime, convert(datetime, ( campo1 - 1) ,103) ,103) from prueba1 where campo1 = 3 "); try { ASG_r1.next(); fecha = ASG_r1.getDate(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select convert(datetime, convert(datetime, ( 39379 - 1) ,103) ,103) from prueba1 where campo1 = 3 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( campo1 ) from prueba1 where campo3 > convert(datetime, 39376 - 1,103) "); try { ASG_r3.next(); cuatro = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println(cuatro ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( campo1 ) from prueba1 where 39376 > convert(int ,campo3 ) + 1 "); try { ASG_r4.next(); cuatro = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println(cuatro ); dos = ASGfaux.fecha("01/01/1900") ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , getdate() ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , getdate() ) "); dos = ASGfaux.fecha( ASGfaux.fecha("24/10/2007") ) ; System.out.println(ASGfaux.formato_fecha(dos) ); dos = ASGfaux.fecha("24/10/2007") ; dos = ASGfaux.fecha( dos ) ;

System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , getdate() ) "); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select convert(datetime, convert(datetime, ( campo1 - 1) ,103) ,103) from prueba1 where campo1 = 3 "); try { ASG_r5.next(); fecha = ASG_r5.getDate(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select convert(datetime, convert(datetime,'25/10/2007',103) ,103) from prueba1 where campo1 = 3 "); try { ASG_r6.next(); fecha = ASG_r6.getDate(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select convert(datetime, dateadd(dd,0, datediff(dd,0,getdate())) ,103) from prueba1 where campo1 = 3 "); try { ASG_r7.next(); fecha = ASG_r7.getDate(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select count ( campo1 ) from prueba1 where campo3 > convert(datetime,'22/10/2007',103) "); try { ASG_r8.next(); cuatro = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println(cuatro ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select count ( campo1 ) from prueba1 where convert(datetime,'22/10/2007',103) > campo3 "); try { ASG_r9.next(); cuatro = ASG_r9.getInt(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println(cuatro ); tres = ASGfaux.fechahora("1900-01-01 00:00:00") ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , getdate() ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , dateadd(dd,0, datediff(dd,0,getdate())) , {ts '"+ tres +"'} ) "); tres = ASGfaux.fecha( ASGfaux.fechahora("2007-10-24 00:00:00") ) ; System.out.println(tres ); tres = ASGfaux.fechahora("2007-10-24 00:00:00") ; tres = ASGfaux.fecha( tres ) ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , {ts '"+ tres +"'} ) "); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select convert(datetime, campo3 ,103) from prueba1 where campo1 = 3 "); try { ASG_r10.next(); fechahora = ASG_r10.getTimestamp(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println(fechahora ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select dateadd(dd,0, datediff(dd,0, getdate() )) from prueba1 where campo1 = 3 "); try { ASG_r11.next(); fechahora = ASG_r11.getTimestamp(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println(fechahora ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo1 ) from prueba1 where campo4 > convert(datetime,'2007-10-22 00:00:00.0',121) "); try { ASG_r12.next(); cuatro = ASG_r12.getInt(1); } catch (SQLException e) {} ASG_r12.close(); ASG_st12.close(); System.out.println(cuatro );

309

00:00:00.0',121)

Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( campo1 ) > campo4 "); try { ASG_r13.next(); cuatro = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println(cuatro );

310
from prueba1 where convert(datetime,'2007-10-22

CDIGO OBJETO ORACLE


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class ctesfecha { static java.sql.Date fecha ; static java.sql.Timestamp fechahora ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; uno = ""; dos = null; tres = null; ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("drop table prueba1 cascade constraints"); ASGcondb.activaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 integer , campo2 decimal(20,0) , campo3 date , campo4 timestamp ) "); dos = ASGfaux.cteIntToFechaJ(1) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , sysdate ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , sysdate ) "); dos = ASGfaux.fecha( 39378 ) ; System.out.println(ASGfaux.formato_fecha(dos) ); cuatro = 39378 ; dos = ASGfaux.fecha( cuatro ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , sysdate ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select to_date( to_date( (campo1 + 2415020 ),'J') ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r1.next(); fecha = ASG_r1.getDate(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select to_date( to_date( (39379 + 2415020 ),'J') ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( campo1 ) from prueba1 where campo3 > to_date(39376 + 2415020 ,'J') "); try { ASG_r3.next(); cuatro = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println(cuatro ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( campo1 ) from prueba1 where 39376 > to_number(to_char(campo3 ,'J')) - 2415020 "); try { ASG_r4.next(); cuatro = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println(cuatro ); dos = ASGfaux.fecha("01/01/1900") ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , sysdate ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , sysdate ) "); dos = ASGfaux.fecha( ASGfaux.fecha("24/10/2007") ) ;

System.out.println(ASGfaux.formato_fecha(dos) ); dos = ASGfaux.fecha("24/10/2007") ; dos = ASGfaux.fecha( dos ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , sysdate ) "); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select to_date( to_date( (campo1 + 2415020 ),'J') ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r5.next(); fecha = ASG_r5.getDate(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select to_date( to_date('25/10/2007','dd/mm/yyyy') ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r6.next(); fecha = ASG_r6.getDate(1); } catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select to_date( to_date(to_char(sysdate,'dd/mm/yyyy')) ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r7.next(); fecha = ASG_r7.getDate(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select count ( campo1 ) from prueba1 where campo3 > to_date('22/10/2007','dd/mm/yyyy') "); try { ASG_r8.next(); cuatro = ASG_r8.getInt(1); } catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println(cuatro ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select count ( campo1 ) from prueba1 where to_date('22/10/2007','dd/mm/yyyy') > campo3 "); try { ASG_r9.next(); cuatro = ASG_r9.getInt(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println(cuatro ); tres = ASGfaux.fechahora("1900-01-01 00:00:00") ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , sysdate ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , to_date(to_char(sysdate,'dd/mm/yyyy')) , {ts '"+ tres +"'} ) "); tres = ASGfaux.fecha( ASGfaux.fechahora("2007-10-24 00:00:00") ) ; System.out.println(tres ); tres = ASGfaux.fechahora("2007-10-24 00:00:00") ; tres = ASGfaux.fecha( tres ) ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , {ts '"+ tres +"'} ) "); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select to_date( campo3 ,'dd/mm/yyyy') from prueba1 where campo1 = 3 "); try { ASG_r10.next(); fechahora = ASG_r10.getTimestamp(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println(fechahora ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select to_date(to_char( sysdate ,'dd/mm/yyyy')) from prueba1 where campo1 = 3 "); try { ASG_r11.next(); fechahora = ASG_r11.getTimestamp(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println(fechahora ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo1 ) from prueba1 where campo4 > timestamp '200710-22 00:00:00.0' "); try { ASG_r12.next(); cuatro = ASG_r12.getInt(1); } catch (SQLException e) {}

311

00:00:00.0'

ASG_r12.close(); ASG_st12.close(); System.out.println(cuatro ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( campo1 ) > campo4 "); try { ASG_r13.next(); cuatro = ASG_r13.getInt(1); } catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println(cuatro );

312

from prueba1 where timestamp '2007-10-22

CDIGO OBJETO DB2


import import import import java.sql.*; ASGdb.*; ASGdbutil.*; ASGutil.*;

public class ctesfecha { static java.sql.Date fecha ; static java.sql.Timestamp fechahora ; private static AccesDB ASGcondb = null; public static void main(String argv[]) throws Exception { ASGcon.cargaparamcon(); ASGcondb = new AccesDB("datos"); ASGcondb.HayTransac(); String uno ; java.sql.Date dos ; java.sql.Timestamp tres ; int cuatro ; double cinco ; cuatro = 0; cinco = 0.0; uno = ""; dos = null; tres = null; ASGcondb.desactivaControlError(); ASGcondb.exeUpdate("drop table prueba1 "); ASGcondb.activaControlError(); ASGcondb.exeUpdate("create table prueba1 ( campo1 integer , campo2 decimal(20,0) , campo3 date , campo4 timestamp ) "); dos = ASGfaux.cteIntToFechaJ(1) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , current date , current timestamp ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , current timestamp ) "); dos = ASGfaux.fecha( 39378 ) ; System.out.println(ASGfaux.formato_fecha(dos) ); cuatro = 39378 ; dos = ASGfaux.fecha( cuatro ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , current timestamp ) "); Statement ASG_st1 = ASGcondb.retCon().createStatement(); ResultSet ASG_r1 = ASG_st1.executeQuery("select date( date( (campo1 + 693595) ) ) from prueba1 where campo1 = 3 "); try { ASG_r1.next(); fecha = ASG_r1.getDate(1); } catch (SQLException e) {} ASG_r1.close(); ASG_st1.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st2 = ASGcondb.retCon().createStatement(); ResultSet ASG_r2 = ASG_st2.executeQuery("select date( date( (39379 + 693595) ) ) from prueba1 where campo1 = 3 "); try { ASG_r2.next(); fecha = ASG_r2.getDate(1); } catch (SQLException e) {} ASG_r2.close(); ASG_st2.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st3 = ASGcondb.retCon().createStatement(); ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( campo1 ) from prueba1 where campo3 > date(39376 + 693595) "); try { ASG_r3.next(); cuatro = ASG_r3.getInt(1); } catch (SQLException e) {} ASG_r3.close(); ASG_st3.close(); System.out.println(cuatro ); Statement ASG_st4 = ASGcondb.retCon().createStatement(); ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( campo1 ) from prueba1 where 39376 > days(campo3 ) 693595 "); try { ASG_r4.next(); cuatro = ASG_r4.getInt(1); } catch (SQLException e) {} ASG_r4.close(); ASG_st4.close(); System.out.println(cuatro ); dos = ASGfaux.fecha("01/01/1900") ; System.out.println(ASGfaux.formato_fecha(dos) );

");

ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , current date , current timestamp ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , {d '"+ dos +"'} , current timestamp ) "); dos = ASGfaux.fecha( ASGfaux.fecha("24/10/2007") ) ; System.out.println(ASGfaux.formato_fecha(dos) ); dos = ASGfaux.fecha("24/10/2007") ; dos = ASGfaux.fecha( dos ) ; System.out.println(ASGfaux.formato_fecha(dos) ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , current timestamp ) "); Statement ASG_st5 = ASGcondb.retCon().createStatement(); ResultSet ASG_r5 = ASG_st5.executeQuery("select date( date( (campo1 + 693595) ) ) from prueba1 where campo1 try {

313

");

ASG_r5.next(); fecha = ASG_r5.getDate(1); } catch (SQLException e) {} ASG_r5.close(); ASG_st5.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st6 = ASGcondb.retCon().createStatement(); ResultSet ASG_r6 = ASG_st6.executeQuery("select date( date('25/10/2007') try {

from prueba1 where campo1

= 3

");

} catch (SQLException e) {} ASG_r6.close(); ASG_st6.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st7 = ASGcondb.retCon().createStatement(); ResultSet ASG_r7 = ASG_st7.executeQuery("select date( current date try { ASG_r7.next(); fecha = ASG_r7.getDate(1); } catch (SQLException e) {} ASG_r7.close(); ASG_st7.close(); System.out.println(ASGfaux.formato_fecha(fecha) ); Statement ASG_st8 = ASGcondb.retCon().createStatement(); ResultSet ASG_r8 = ASG_st8.executeQuery("select count ( campo1 ) try {

ASG_r6.next(); fecha = ASG_r6.getDate(1);

from prueba1 where campo1

= 3

");

from prueba1 where campo3

> date('22/10/2007')

");

} catch (SQLException e) {} ASG_r8.close(); ASG_st8.close(); System.out.println(cuatro ); Statement ASG_st9 = ASGcondb.retCon().createStatement(); ResultSet ASG_r9 = ASG_st9.executeQuery("select count ( campo1 ) try {

ASG_r8.next(); cuatro = ASG_r8.getInt(1);

from prueba1 where date('22/10/2007')

> campo3

");

ASG_r9.next(); cuatro = ASG_r9.getInt(1); } catch (SQLException e) {} ASG_r9.close(); ASG_st9.close(); System.out.println(cuatro ); tres = ASGfaux.fechahora("1900-01-01 00:00:00") ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 1 , 1 , current date , current timestamp ) "); ASGcondb.exeUpdate("insert into prueba1 values ( 2 , 1 , current date , {ts '"+ tres +"'} ) "); tres = ASGfaux.fecha( ASGfaux.fechahora("2007-10-24 00:00:00") ) ; System.out.println(tres ); tres = ASGfaux.fechahora("2007-10-24 00:00:00") ; tres = ASGfaux.fecha( tres ) ; System.out.println(tres ); ASGcondb.exeUpdate("insert into prueba1 values ( 3 , 40000 , {d '"+ dos +"'} , {ts '"+ tres +"'} ) "); Statement ASG_st10 = ASGcondb.retCon().createStatement(); ResultSet ASG_r10 = ASG_st10.executeQuery("select date( campo3 ) from prueba1 where campo1 = 3 "); try { ASG_r10.next(); fechahora = ASG_r10.getTimestamp(1); } catch (SQLException e) {} ASG_r10.close(); ASG_st10.close(); System.out.println(fechahora ); Statement ASG_st11 = ASGcondb.retCon().createStatement(); ResultSet ASG_r11 = ASG_st11.executeQuery("select date( current timestamp ) from prueba1 where campo1 try {

= 3

00:00:00.0'

");

ASG_r11.next(); fechahora = ASG_r11.getTimestamp(1); } catch (SQLException e) {} ASG_r11.close(); ASG_st11.close(); System.out.println(fechahora ); Statement ASG_st12 = ASGcondb.retCon().createStatement(); ResultSet ASG_r12 = ASG_st12.executeQuery("select count ( campo1 ) try {

from prueba1 where campo4

> '2007-10-22

ASG_r12.next(); cuatro = ASG_r12.getInt(1); } catch (SQLException e) {}

campo4

");

ASG_r12.close(); ASG_st12.close(); System.out.println(cuatro ); Statement ASG_st13 = ASGcondb.retCon().createStatement(); ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( campo1 ) try {

314

from prueba1 where '2007-10-22 00:00:00.0'

>

} }

} catch (SQLException e) {} ASG_r13.close(); ASG_st13.close(); System.out.println(cuatro );

ASG_r13.next(); cuatro = ASG_r13.getInt(1);

NDICE DE FIGURAS

Figura 1: Interfaces proporcionados por Informix-4GL .......................................................... 9 Figura 2: Ficheros de los que consta una aplicacin en Informix .............................................11 Figura 3: Tipos de bloques en un programa.........................................................................14 Figura 4: Componentes del traductor .................................................................................25 Figura 5: Palabras reservadas de Informix ..........................................................................26 Figura 6: Estructura bsica de un mdulo de programa ........................................................58 Figura 7: Ejecucin de la aplicacin hola.4gl sobre Informix .................................................61 Figura 8: Resultado de la ejecucin del programa hola.java como aplicacin modo texto ...........61 Figura 9: Ejecucin del programa hola.java como aplicacin grfica .......................................62 Figura 10: Ejecucin del programa hola.java como aplicacin Web ........................................62 Figura 11: Resultado de ejecucin de un programa con men en Informix................................83 Figura 12: Resultado de ejecucin de un programa con men en Java .....................................83 Figura 13: Propiedades de la base de datos SQL Server ...................................................... 202 Figura 14: Lista te tareas del proyecto ............................................................................. 227 Figura 15: Diagrama Gantt de tareas del proyecto ............................................................. 227

316

NDICE DE TABLAS

Tabla 1: Sentencias compuestas de Informix-4GL ................................................................14 Tabla 2. mbito de referencia de los identificadores 4GL .......................................................16 Tabla 3: Tipos de datos 4GL .............................................................................................18 Tabla 4: Operadores de las expresiones 4GL .......................................................................21 Tabla 5. Operadores sobre expresiones enteras ...................................................................22 Tabla 6: Operadores reconocidos por el analizador lxico ......................................................27 Tabla 7: Constantes reconocidas por el analizador lxico .......................................................27 Tabla 9: Mapeo entre tipos de datos Informix-4GL y JAVA .....................................................84 Tabla 10: Valor de inicializacin de variables .......................................................................85 Tabla 11: Asigacin de expresiones tipo fecha .....................................................................85 Tabla 12: Asignacin de expresiones tipo fecha/hora ............................................................86 Tabla 13: Asignacin de expresiones tipo fecha a entero .......................................................86 Tabla 14: Estndar SQL ...................................................................................................92 Tabla 15: Sentencias de definicin de datos ........................................................................93 Tabla 16: Sentencias de manipulacin de datos ...................................................................93 Tabla 17: Sentencias de manipulacin de cursores ...............................................................93 Tabla 18: Sentencias de optimizacin-Informacin ...............................................................93 Tabla 19: Sentencias de control de acceso a los datos ..........................................................94 Tabla 20: Sentencias de integridad de los datos...................................................................94 Tabla 21: Sentencias de manipulacin dinmica de datos ......................................................94 Tabla 22: Tipos de datos primarios .................................................................................. 155 Tabla 23: Sinnimos de tipos de datos primarios................................................................ 156 Tabla 24: Tipos de datos JDBC........................................................................................ 157 Tabla 25: Mapeos de datos Informix-SQL a SQL JDBC......................................................... 160 Tabla 26: Mapeo de tipos de datos SqlServer a SQL JDBC ................................................... 164 Tabla 27: Tipos de datos numricos de Oracle ................................................................... 165 Tabla 28: Mapeo de tipos de datos Oracle a SQL JDBC ........................................................ 167 Tabla 29: Mapeo de tipos de datos DB2 a SQL JDBC ........................................................... 169 Tabla 30: Mapeo entre tipos de datos Informix-SQL y el resto de gestores ............................. 170 Tabla 31: Mapeos de datos Informix-SQL a implementaciones JDBC de los gestores ................ 171 Tabla 32: Mapeo entre tipos de datos SQL JDBC y Java....................................................... 173 Tabla 33: Mapeo entre tipos de datos Java y SQL JDBC....................................................... 174 Tabla 34: Funciones para recuperacin de datos del gestor de bases de datos ........................ 175 Tabla 35: Conversiones implcitas soportadas por Informix .................................................. 176 Tabla 36: Conversiones soportadas por SqlServer .............................................................. 177 Tabla 37: Conversiones implcitas soportadas por Oracle ..................................................... 178 Tabla 38: Conversiones implcitas soportadas por DB2 ........................................................ 178 Tabla 39: Conversiones implcitas necesarias para SqlServer................................................ 179 Tabla 40: Conversiones implcitas necesarias para Oracle .................................................... 180 Tabla 41: Conversiones implcitas necesarias para DB2 ....................................................... 182 Tabla 42: Precedencia de operadores en Informix-SQL........................................................ 199 Tabla 43: Precedencia de operadores en SqlServer............................................................. 203 Tabla 44: Precedencia de operadores Oracle ..................................................................... 206 Tabla 45: Precedencia de operadores Db2......................................................................... 208 Tabla 46: Formatos por defecto de Informix-SQL ............................................................... 210 Tabla 47: Formatos por defecto de SqlServer .................................................................... 211 Tabla 48: Formatos por defecto de Oracle......................................................................... 212

317 Tabla 49: Formatos por defecto de Db2............................................................................ 213 Tabla 50: Formatos del lenguaje de programacin Java....................................................... 214 Tabla 51: Ejemplo de configuracin de entornos ................................................................ 215 Tabla 52: Uso de constantes tipo fecha en sentencias SQL................................................... 220 Tabla 53: Valores numricos asociados a una fecha en cada gestor ....................................... 220 Tabla 54: Coste del proyecto .......................................................................................... 228 Tabla 55: Formato de fecha en funcin del idioma establecido.............................................. 232

318

INDICE DE CUADROS

Cuadro 1: Cdigo fuente mnimo de un programa Informix-4GL .............................................59 Cuadro 2: Relacin entre cdigo objeto modo texto y modo grfico.........................................60 Cuadro 3: Makefile y ASGmakefile .....................................................................................63 Cuadro 4: Ejemplo mdulo principal de programa multimdulo...............................................65 Cuadro 5: Ejemplo de mdulo de programa multimdulo......................................................65 Cuadro 6: Ejemplo de mdulo de programa multimdulo......................................................66 Cuadro 7: Ejemplo de bloque de programa globals ..............................................................67 Cuadro 8: Ejemplo mdulo de programa globals ..................................................................68 Cuadro 9: Programa multimdulo completo con seccin globals.............................................70 Cuadro 10: Ejemplo de definicin de funciones ....................................................................72 Cuadro 11: Ejemplo de funcin con valores de retorno..........................................................73 Cuadro 12: Sentencias de control de flujo...........................................................................79 Cuadro 13: Ejemplo sentencias men ................................................................................82

319

REFERENCIAS BIBLIOGRAFICAS

[INFOR89] Informix 4GL: User Guide (Informix-4GL V4.0), Informix Software Inc., Informix Press, 1989. [INFOR91] Informix Guide to SQL: Tutorial (Informix-SQL V4.1), Informix Software Inc., Informix Press, 1991. [INFOR91] Informix Guide to SQL: Reference (Informix-SQL V4.1), Informix Software Inc., Informix Press, 1991. [INFOR91] SQL Quick Syntax Guide (Informix-SQL V4.1), Informix Software Inc., Informix Press, 1991. [INFOR94] Informix 4GL: Quick Syntax (Version 6.0), Informix Software Inc., Informix Press, 1994. [INFOR94] Informix SQL: User Guide (Version 6.0), Informix Software Inc., Informix Press, 1994. [INFOR94] Informix SQL: Reference (Version 6.0), Informix Software Inc., Informix Press, 1994. [INFOR97] Informix Guide to SQL: Syntax (Version 9.1), Informix Software Inc., Informix Press, 1997. [INFOR98] Informix Guide to SQL: Reference (Version 7.3), Informix Software Inc., Informix Press, 1998. [INFOR99] Informix 4GL: Referencia Manual (Version 7.3), Informix Software Inc., Informix Press, 1999. [INFOR00] Informix JDBC Drive: Programmers Guide, Informix Software Inc., Informix Press, 2000. [INTER03] IBM Informix Guide to SQL: Reference (Version 9.4), International Business Machines Corporation, International Business Machines Corporation, 2003. [INTER04] IBM Informix JDBC Driver Programmers Guide, International Business Machines Corporation, International Business Machines Corporation, 2004. [INTER04] IBM Informix JDBC Driver Programmers Guide, International Business Machines Corporation, International Business Machines Corporation, 2004. [ADVA98] La Biblia de Oracle8, Advanced Informatcion Systems Inc., Ediciones Anaya Multimedia S.A., 1998. [DIAN01] Oracle 9i: SQL Reference (Release 9.0.1), Diana Lorentz, Oracle Corporation, 2001. [DIAN02] Oracle 9i: SQL Reference (Release 9.2), Diana Lorentz, Oracle Corporation, 2002. [KEVI03] Oracle 9i: Manual del administrador, Kevin Loney, Marlene Theriault, McGrawHill/Osborne, 2003. [DIAN06] Oracle Database SQL Reference 10g (Release 10.2), Diana Lorentz, Oracle Corporation, 2006. [KEVI01] Oracle Database 10g: Complete Reference, Kevin Loney, McGraw-Hill/Osborne, 2004. [MICR02] SQL Server 2000 Driver for JDBC Users Guide and Reference, Microsoft, Microsoft, 2002. [MICR02] Libros de pantalla SQL Server 2000, Microsoft, Microsoft, 2002. [MICR07] Libros de pantalla SQL Server 2005, Microsoft, Microsoft, 2007.

320 [INTE03] SQL Reference for Cross-Platform Development, International Business Machines Corporation, International Business Machines Corporation, 2003. [INTE02] SQL Reference Volume 1 (Version 8), International Business Machines Corporation, International Business Machines Corporation, 2002. [INTE02] SQL Reference Volume 2 (Version 8), International Business Machines Corporation, International Business Machines Corporation, 2002. [INTE04] SQL Reference Volume 1 (Version 8.2), International Business Machines Corporation, International Business Machines Corporation, 2004. [INTE04] SQL Reference Volume 2 (Version 8.2), International Business Machines Corporation, International Business Machines Corporation, 2004. [WHEI05] Microsoft SQL Server to IBM DB2 UDB Conversion Guide, Whei-Jen Chen, Alain Fisher, Stefan Hummel, Shailendra Kishore, Bin TeahTed Wasserman, International Business Machines Corporation, 2005. [MICR02] Migrating Informix Databases to Microsoft SQL Server 2000, Microsoft Corporation, Microsoft TechNet, 2002. [MICR99] Migrar bases de datos de Oracle a MS SQL Server 7.0, Microsoft Corporation, Microsoft TechNet, 1999. [EXAL03] Migrating Informix 4GL Applications to J2EE1.3 with the b+ J2EE Application Generator, Exaltec Software, Exaltec Software Limited, 2003. [SANJ95] INFORMIX 6.X to Oracle7: Comparison of Tables and Features, Sanjoy Mondal, Dan Mohler, Oracle Corporation, 1995. [SANJ94] Migrating from INFORMIX 5.X to Oracle7: Design Considerations, Sanjoy Mondal, Dan Mohler, Oracle Corporation, 1994. [DONA96] Converting Applications: INFORMIX 4GL to Oracle7, Donal Daly, Geeta Deodhar, Lakshmana Pillai, Lynne Chaddon, Nik Pollak, Robert Froeber, Sanjoy Mondal, Subhash Jawahrani, Breda McColgan, Oracle Corporation, 1996. [ORAC96] Database Conversion Guide: DB2/MVS Corporation, 1996. to Oracle7, Oracle Corporation, Oracle

[ORAC03] Migrating Applications from Microsoft SQL Server to Oracle9i Database, Oracle Corporation, Oracle Corporation, 2003. [BRUE00] Thinking in Java 2 Ed., Bruce Eckel, Prentice Hall, 2000. [BRUE03] Thinking in Java 3 Ed., Bruce Eckel, Prentice Hall, 2003. [JOSE07] Dominie JavaScript, Jos Lpez Quijano, Ra-Ma Editorial, 2007.

Você também pode gostar