You are on page 1of 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 1

MEMORIA







NGEL SUREZ GARCA
JULIO DE 2008

TUTOR: RAL IZQUIERDO
CASTANEDO
2
NDICE:
PREAMBULO ........................................................................................................... 6
PLANTEAMIENTO 4GL............................................................................................... 8
INTRODUCCION 4GL................................................................................................ 8
ESTUDIO DEL LENGUAJE INFORMIX-4GL ..................................................................... 9
INTERFACES DE UNA APLICACIN EN INFORMIX 9
PARTES DE UNA APLICACIN 10
CARACTERSTICAS BSICAS DEL LENGUAJE 12
TIPOS DE DATOS 17
EXPRESIONES 4GL 19
TRADUCTOR DEL LENGUAJE.................................................................................... 24
PRERREQUISITOS 24
ALCANCE Y LIMITACIONES 24
ANALIZADOR LEXICO 25
ANALISIS DE LA SINTAXIS 27
SEMANTICA, TABLA DE SIMBOLOS, Y MANEJO DE ERRORES 53
GENERACIN DE CDIGO 55
TRATAMIENTO DE SENTENCIAS DE INFORMIX-4GL ..................................................... 57
SENTENCIAS DE DEFINICIN DEL MDULO PRINCIPAL DE PROGRAMA 57
SENTENCIAS DE MANEJO DE FUNCIONES 70
SENTENCIAS DE CONTROL DEL FLUJO 74
SENTENCIA DE DEFINICIN DE MENS 79
SENTENCIAS DE DECLARACIN Y UTILIZACIN DE VARIABLES 83
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 93
SENTENCIAS SQL DE MANIPULACIN DE DATOS 93
SENTENCIAS SQL DE MANIPULACIN DE CURSORES 93
SENTENCIAS SQL DE OPTIMIZACIN-INFORMACIN 93
SENTENCIAS SQL DE CONTROL DE ACCESO A LOS DATOS 93
SENTENCIAS SQL QUE GARANTIZAN LA INTEGRIDAD DE LOS DATOS 94
SENTENCIAS SQL DE MANIPULACIN DINMICA DE DATOS 94
ESTUDIO DE LAS SENTENCIAS SQL......................................................................... 94
SENTENCIA ALTER INDEX 94
SENTENCIA ALTER TABLE 95
SENTENCIA BEGIN WORK 102
SENTENCIA CLOSE 104
SENTENCIA CLOSE DATABASE 105
SENTENCIA COMMIT WORK 106
SENTENCIA CREATE AUDIT 106
SENTENCIA CREATE DATABASE 107
SENTENCIA CREATE INDEX 109
SENTENCIA CREATE SYNONYM 110
SENTENCIA CREATE TABLE 111
SENTENCIA CREATE VIEW 117
3
SENTENCIA DATABASE 118
SENTENCIA DECLARE CURSOR 119
SENTENCIA DELETE FROM 120
SENTENCIA DROP AUDIT FOR 121
SENTENCIA DROP DATABASE 122
SENTENCIA DROP INDEX 122
SENTENCIA DROP SYNONYM 123
SENTENCIA DROP TABLE 124
SENTENCIA DROP VIEW 125
SENTENCIA EXECUTE 125
SENTENCIA FETCH 126
SETENCIA FLUSH 127
SENTENCIA FREE 128
SENTENCIA GRANT 128
SENTENCIA INSERT INTO 134
SENTENCIA LOAD FROM 135
SENTENCIA LOCK TABLE 136
SENTENCIA OPEN 138
SENTENCIA PREPAPRE 139
SENTENCIA PUT 140
SENTENCIA RENAME COLUMN 140
SENTENCIA RENAME TABLE 141
SENTENCIA REVOKE 141
SENTENCIA ROLLBACK WORK 143
SENTENCIA SELECT 143
SENTENCIA START 147
SENTENCIA UNLOAD 147
UNLOCK TABLE 148
SENTENCIA UPDATE 148
UPDATE STATISTICS 150
SENTENCIAS DE MANIPULACIN DINMICA DE DATOS Y CURSORES........................... 150
SENTENCIAS DE CONTROL DE FLUJO...................................................................... 153
ESTUDIO DE TIPOS DE DATOS .............................................................................. 154
TIPOS DATOS BASICOS 154
TIPOS DE DATOS JDBC 156
TIPOS DE DATOS INFORMIX-SQL 157
TIPO DE DATOS SQLSERVER 161
TIPOS DE DATOS DE ORACLE 164
TIPOS DE DATOS DE DB2 167
TABLA DE MAPEOS 169
MAPEO DE TIPOS DE DATOS ENTRE JDBC Y JAVA ..................................................... 172
FUNCIONES DE RECUPERACION DE DATOS SQL ....................................................... 174
CONVERSIONES DE TIPOS DE DATOS..................................................................... 175
TRATAMIENTO DE LAS CONVERSIONES NO IMPLICITAS 178
EXPRESIONES SQL .............................................................................................. 183
EXPRESIONES DE MANEJO DE COLUMNAS 184
EXPRESIONES DE CONSTANTES 188
FUNCIONES SQL 191
EXPRESIONES AGREGADAS 195
NOMBRES DE VARIABLES 196
4
NOMBRES DE ELEMENTOS DE LA BASE DE DATOS.................................................... 196
OPERACIONES SOBRE EXPRESIONES SQL ............................................................... 197
TRATAMIENTO POR SQLSERVER 199
TRATAMIENTO PO ORACLE 203
TRATAMIENTO POR DB2 206
TRADUCCIN DE OPERADORES SOBRE EXPRESIONES 208
CONFIGURACIN LOCAL....................................................................................... 209
ELEMENTOS DE INFORMIX 210
ELEMENTOS DE SQLSERVER 211
ELEMENTOS DE ORACLE 212
ELEMENTOS DE DB2 213
ELEMENTOS DE JAVA 213
CONCLUSIONES Y EJEMPLO DE CONFIGURACIN 214
TRATAMIENTO DE LAS FECHAS.............................................................................. 216
RECONOCIMIENTO DE LAS FECHAS 217
MOSTRAR VALORES 217
INTERCAMBIO DE DATOS ENTRE JAVA Y EL GESTOR 218
CREACIN DE OBJETOS: PROPIETARIO Y ACCESO.................................................... 222
OBJETOS CREADOS EN INFORMIX 222
OBJETOS CREADOS EN SQLSERVER 222
OBJETOS CREADOS EN DB2 223
OBJETOS CREADOS EN ORACLE 223
CONCLUSIONES 224
CONFIGURACIN DE LA CONEXIN........................................................................ 225
PLANIFICACIN Y PRESUPUESTO........................................................................... 226
MANUAL DE USUARIO .......................................................................................... 229
REQUISITOS HARDWARE 229
REQUISITOS SOFTWARE 229
CONFIGURACIN 230
EJECUCIN DEL TRADUCTOR 233
VERIFICACIN DE FUNCIONAMIENTO 234
ANEXO I: FUENTES.............................................................................................. 235
EJEMPLO SENTENCIA ALTER TABLE 235
EJEMPLO SENTENCIAS CONEXIN/DESCONEXIN 237
EJEMPLO SENTENCIAS DE TRATAMIENTO DE TRANSACCIONES 237
EJEMPLO SENTENCIA CREACION INDICE 238
EJEMPLO SENTENCIA CREACION DE SINONIMOS 239
EJEMPLO SENTENCIA CREACION DE TABLA 242
EJEMPLO SENTENCIAS CREACION TABLA TEMPORAL 243
EJEMPLO SENTENCIA CREACION VISTA 245
EJEMPLO SENTENCIA DELETE 247
EJEMPLO SENTENCIA DROP INDEX 248
EJEMPLO SENTENCIA DROP OBJETO 249
EJEMPLO SENTENCIA GRANT 251
EJEMPLO SENTENCIA INSERT 251
EJEMPLO SENTENCIA LOAD/UNLOAD 252
EJEMPLO SENTENCIA LOCK/UNLOCK 253
EJEMPLO SENTENCIA RENAME COLUMN 254
EJEMPLO SENTENCIA RENAME TABLA 255
EJEMPLO SENTENCIA PREPARE/EXECUTE PREPARE/DECLARE 256
5
EJEMPLO SENTENCIA DECLAREFORUPDATE 258
EJEMPLO SENTENCIA FOREACH-FORUPDATE 262
EJEMPLO SENTENCIA TIPOS DE DATOS 267
EJEMPLO DE MANEJO DE COLUMNAS Y CONSTANTES PREDEFINIDAS 269
EJEMPLO DE MANEJO DE LITERALES, CONSTANTES Y VARIABLES 272
EJEMPLO FUNCIONES DE MANEJO DE FECHAS 275
EJEMPLO DE FUNCIONES MATEMTICAS 280
EJEMPLO DE FUNCIONES AGREGADAS 283
EJEMPLO DE FUNCION WEEKDAY 284
EJEMPLO DE MANEJO DE OPERACIONES SOBRE EXPRESIONES 288
EJEMPLO DE MANEJO DE CONSTANTES TIPO FECHA 305
NDICE DE FIGURAS ............................................................................................ 315
NDICE DE TABLAS.............................................................................................. 316
INDICE DE CUADROS........................................................................................... 318
REFERENCIAS BIBLIOGRAFICAS............................................................................. 319

6
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.



7








ESTUDIO DEL LENGUAJE DE
PROGRAMACIN INFORMIX-4GL

8
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.
9
ESTUDIO DEL LENGUAJE INFORMIX-4GL
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.
INTERFACES DE UNA APLICACIN EN INFORMIX

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:
Ficheros de datos
Informes
Base de datos
Ventanas 4gl
Usuarios de la base de datos
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

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
Codio fuen te 4gl
. 4gl
Fi ch er os de men sajes Especificacion
de for mat os
For matos
compilados
Fich er os de mesajes
compilados
Codi go fuen te compi lado
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 fcil de leer el
cdigo fuente 4GL.
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 FOREACH INPUT PROMPT
CONSTRUCT FUNCION INPUT ARRAY REPORT
DISPLAY ARRAY GLOBLAS MAIN SQL
FOR IF MENU 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 mbito de referencia
Constantes Global
Argumentos Local a su funcin o report.
Variable 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 Mientras el formato de pantalla permanezca
abierto
Identificadores de Pantalla o ventanas Globales (a partir de que son declarados)
Sentencias label 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) no puede volver
a utilizarse el mismo nombre para referenciar otra.
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 Tipo de valor que almacena
ARRAY OF type Arrays de valores de cualquier otro tipo de dato
4GL simple
BYTE Un tipo de dato binario cuya longitud es 231 bytes
CHAR(tamao) Cadena de caracteres de cmo mximo 32767
bytes de longitud
CHARACTER Esta palabra reservada es sinnimo de CHAR
DATE Especifica una fecha
DATETIME Especifica una fecha y la hora del da
DECIMAL(p, s) Nmero en formato punto fijo, con una parte
entera de longitud (p) y una parte decimal de
longitud (s)
DECIMAL(p) Nmero en formato punto fijo, con una parte
entera de longitud (p)
DEC Esta palabra reservada es sinnimo de DECIMAL
FLOAT Nmero en formato punto fijo de cmo mximo 32
dgitos de longitud
DOUBLE PRECISION Esta palabra reservada es sinnimo de FLOAT
INTEGER Nmero entero cuyo valor puede oscilar entre el
rango: -2.147.483.647 a + 2.147.483.647
INT Esta palabra reservada es sinnimo de INTEGER
INTERVAL Extensin de tiempo en aos y meses o una unidad
de tiempo mas pequea
18
MONEY Cantidad de moneda con una escala y precisin
NUMERIC Esta palabra reservada es sinnimo de DECIMAL
REAL Esta palabra reservada es sinnimo de
SMALLFLOAT
RECORD Conjunto de valores, de distintos tipos de datos,
ordenados
SMALLFLOAT Nmero en formato punto fijo, de cmo mximo
16 dgitos de precisin
SMALLINT Nmero entero con un rango de 32767 a 32767
TEXT Cadena de caracteres de longitud mxima 232
bytes
VARCHAR(tamao) Cadena de caracteres de longitud variable, su
tamao a de ser menor de 255 bytes
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.
Los tipos de datos de Informix-4GL se pueden clasificar en varias categoras, que son:
! 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.
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 Retorna TRUE o FALSE (o NULL en algunos contextos).
! Integer Retorna un nmero entero de tipo INT o SMALLINT.
! Number Retorna un valor de que puede ser de cualquier tipo de dato tipo Nmero.
! Carcter Retorna un valor tipo: CHAR o VARCHAR.
! Time 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.
De igual modo tampoco se pueden incluir los siguientes operadores 4GL en expresiones SQL:
! 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().
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 Descripcin Asociatividad Precedencia
.
[ ]
( )
Elementos de un registro
ndice de arrays o subcadenas
Llamada a funciones
De izquierda
De izquierda
Ninguna
16


UNITS Cualificador simple de intervalos De izquierda 15
+
-
Mas unario
Menos unario
De derecha 14

**
MOD
Exponenciacin
Mdulo
De izquierda 13
*
/
Multiplicacin
Divisin
De izquierda 12

+
-
Suma
Resta
De izquierda

11

|| Concatenacin De izquierda 10
LIKE
MATCHES
Comparacin de Cadenas De derecha 9
<
<=
= ==
>=
>
!= <>
Menor que
Menor igual que
Igual que
Mayor igual que
Mayor que
Distinto
De izquierda 8
IN() Pertenencia a un conjunto De derecha 7
BETWEEN . AND Rango De Izquierda 6
IS NULL Si es nulo De izquierda 5
NOT Negacin lgica De izquierda 4
AND Interseccin lgica De izquierda 3
OR Unin lgica De izquierda 2
ASCII
CLIPPED
COLUMN
ORD
SPACES
USING
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 1

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 Nombre Nombre del Resultado Precedencia
** Exponenciacin Potencia 12
Mod Mdulo Resto entero 12
* Multiplicacin Producto 11
/ Divisin Cociente 11
+ Adicin Suma 10
- Sustraccin Diferencia 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 unarios que se aplican para enteros tambin son
aplicables a expresiones tipo nmero.
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 considera los siguientes caracteres como imprimibles:
! TAB (= CONTROL-I)
! NEWLINE (= CONTROL-J)
! FORMFEED (= CONTROL-L)
! Y desde ASCII 32 (= blanco) hasta 128 (= ~)
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 la adicin y la
sustraccin, y los operadores de relacin.
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

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:

Cdigo fuente
Analizador Lxico
Analizador Sintctico
Analizador Semntico
T
a
b
l
a

d
e

S

m
b
o
l
o
s
M
a
n
e
j
o

d
e

e
r
r
o
r
e
s
Generacin de Cdigo
GI GD GO GS
CoI CoD CoO CoS
Cdigo objeto dependiente
26

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
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
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 Descripcin Ejemplos
entero nmero entero negativo o
positivo
1, +54, -46
decimal nmero decimal
1.0, 1.3e+34, .32E-34, 43e+34
carcter carcter simple 'a'
cadena cadena de caracteres
cadena
fecha fecha corta
dd/mm/yyyy
fecha/hora fecha larga
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> ::= arg_val <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= arr_count <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= arg_curr <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= cursor_name <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= downshift <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= upshift <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= err_get <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_drawbox <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_getenv <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_getkey <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_keyval <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_lastkey <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= fgl_scr_size <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= length <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= nuv_args <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= ord <PAR1> <EXPR> <PAR2>
<AGREGATEFUNCTIONS> ::= scr_line <PAR1> <PAR2>
<AGREGATEFUNCTIONS> ::= 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> ::= rowid <OPCASCDESC>
<UNAORDERBYCLAUSE> ::= <ELTOSEL> <OPCASCDESC>
<OPCINTOTEMPCLAUSE> ::= <VACIO>
<OPCINTOTEMPCLAUSE> ::= 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 y
estas situaciones son resueltas durante la codificacin. Los casos que no cumplen LL1 son:
! 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>
" Dentro de la sentencia INITIALIZE en:
# <PROPIETARIO> <IDENTIFICADOR> <PTO> <ULTUNARESTOLIKEINITIALIZE>
" Dentro de la sentencia VALIDATE en:
# <PROPIETARIO> <IDENTIFICADOR> <PTO> <RESTOUNAVALIDATE>
" 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, en la seccin OUTPUT al tratar las dimensiones de las
paginas:
<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 Informix-
4GL 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: let fecha = today
Cdigo objeto JAVA: 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: select fecha - campo4 into dos from prueba1
Cdigo objeto JAVA para SqlServer: executeQuery("select datediff(dd,campo4 ,{d
'"+fecha+" '} ) from prueba1 ");
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 INFORMIX-
4GL
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

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>
}
}
SECCION GLOBALS
DEFINICION VARIABLES
BLOQUE MAIN

FUNCIONES y REPORTS

SECCION DATABASE
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. Informix-
4GL 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.

Cuadro 1: Cdigo fuente mnimo de un programa Informix-4GL
main
display "hola mundo"
end main
hola.4gl
60

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:
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;



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");
}
}

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

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");
}
}
hola.java
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, de un programa
multimdulo con respecto a los monomdulo, son:
! 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. ASGcondb.<mtodo>
Multimdulo: 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.

Cuadro 3: Makefile y ASGmakefile
.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

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

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


multi21=
multi11.4gl
multi12.4gl
multi13.4gl
multi14.4gl
exe:multi21
makefile 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 puede contener informacin relativa a mltiples programas
multimdulo.
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

Cuadro 4: Ejemplo mdulo principal de programa multimdulo

Cuadro 5: Ejemplo de mdulo de programa multimdulo
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
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 );

}
}
multi2.4gl multi2.java
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
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 );
}
}
multi1.4gl multi1.java
66

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 char(1),
impre char(50),
nimp decimal(2,0)
end globals
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.
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 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 ;
}
}
multi3.4gl multi3.java
67

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.




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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}
}
modglobal.4gl modglobal.java
class ASGglobals_modglobal{
static int uno , dos , tres;
static double cuatro;
static String cinco;
}

ASGglobals_modglobal.java
68

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 la definicin, utilizacin y
traduccin de este tipo de variables.
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).
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}
}
modglobal2.4gl modglobal2.java
class globals{
static double cuatro;
static String cinco;
static int dos;
static int uno;
static int tres;
}
globals.java
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>

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: " , uno
message "En main: " , dos
message "En main: " , tres
call fx(uno)
call fx2(uno)
message "En main tras vuelta funcion: " ,
uno
message "En main tras vuelta funcion: " ,
dos
message "En main tras vuelta funcion: " ,
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
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}
}
multi12.4gl multi12.java
70



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.
multi1=
multi2.4gl
multi3.4gl
exe:multi1

multi12=
multi22.4gl
multi32.4gl
exe:multi12
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;
}
ASGmakefile ASGglobal_multi12.java
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ;
}
}
multi32.4gl multi32.java
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
multi22.4gl
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}
}
multi22.java
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.
Este cdigo se transformar en una sentencia JAVA como la que sigue:
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:
72

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 y el tipo de
retorno:
private static <tipo_retorno> <nombre_funcion> (<argumentos_con_tipo>) {
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.4gl
funcion1.java
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.

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:
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.4gl
funcion2.java
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> ] $ System.exit (<codigo_salida>);
exit main $ System.exit (0);
exit menu $ 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

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

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

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

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
sentencia while" );
ejemplowhile ( ) ;
break;
default :
System.out.println("Fin de
programa" );
System.exit(0);
break;
}
}
}

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

sentctrlflujo.4gl
sentctrlflujo.java
79

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]

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;
}
}
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:

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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;
import javax.swing.*;
import java.awt.*;
import ASGgrafico.*;
import 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" );

sentmenu.4gl
sentmenu.java
82

Cuadro 13: Ejemplo sentencias men
ASGmenu.getItem("Ejemplo1").addActionListener(
new ActionListener ()
{
public void actionPerformed(ActionEvent e)
{

ASGarea.setText("");
ASGarea.append("Ejemplo de sentencia for" +"\n");
ejemplofor ( ) ;
}
}
);
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
EXIT" +"\n")
;
ejemploforc ( ) ;
}
}
);
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());
}

sentmenu.java (2)
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 Informix-
4GL del cdigo fuente. Para ello se utiliza la siguiente tabla:
Tipo de dato Informix-4GL Tipo de dato Java
CHAR, CHARACTER String
VARCHAR String
TEXT String
NUMERIC | DECIMAL | DEC java.math.BigDecimal | double
SMALLINT short
INTEGER | INT int
REAL | SMALLFLOAT float
FLOAT | DOUBLE double
BYTE byte[]
DATE java.sql.Date
TIMESTAMP java.sql.Timestamp
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 Valor inicial
String (espacio en blanco)
Short, int 0
Flota, double 0,0
Date, Timestamp null
Byte null
Bigdecimal 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 Conversin a JAVA
today new Date(new java.util.Date().getTime()) ;
22/07/2007 ASGfaux.fecha("22/07/2007") ;
4000 ASGfaux.cteIntToFechaJ(40000) ;
date (<fecha> ) ASGfaux.fecha ( <fecha> ) ;
mdy (<mes>, <dia>, <ao> ) ASGfaux.mdy (<mes>, <dia>, <ao> ) ;
Tabla 10: Asigacin de expresiones tipo fecha

Informix-4GL Conversin a JAVA
current new Timestamp(new java.util.Date().getTime()) ;
2007-07-22 12:33:20.444 ASGfaux.fechahora("2007-07-22 12:33:20.444") ;
86
datetime (2007-07-22 12:33:20.444) year
to fraction
ASGfaux.fechahora("2007-07-22 12:33:20.444") ;
Tabla 11: Asignacin de expresiones tipo fecha/hora

Informix-4GL Conversin a JAVA
day( <fecha> ) ASGfaux.day( <fecha> ) ;
moth ( <fecha> ) ASGfaux.month ( <fecha> ) ;
year ( <fecha> ) ASGfaux.year ( <fecha> ) ;
weekday ( <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 6 1 ASGglobals_modglobal
cuatro$1 2 1 ASGglobals_modglobal
uno$2 3 2 modglobal
dos$3 3 3 modglobal
uno$1 3 1 ASGglobals_modglobal
tres$1 3 1 ASGglobals_modglobal
dos$1 3 1 ASGglobals_modglobal
fx$2 15 2 modglobal
fx2$2 15 2 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, Informix OL,
SqlServer, Oracle y Db2.
Dentro de esta seccin no solo se estudian con total detalle todas las sentencias SQL de Informix-
SQL 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 Nivel Caractersticas
ANSI SQL/89 Nivel 1 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)
SQL/92 Nivel de acceso Mensajes de errores estndar:
SQLSTATE
Lenguajes anfitriones adicionales: C,
Ada.
Nivel intermedio Tipos de datos: DATE, TIME
Operadores: OUTER JOIN, OUTER
UNION, INSERT SELECT
Dominios
Estructuras de manipulacin: ALTER
TABLE
Dynamic SQL
Acciones referenciales: ON DELTE
Intervalos de tiempo: YEAR, MONTH,
DAY, HOUR
Aritmtica sobre unidades de tiempo.
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 mismos
1
.
! 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.

1
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 CREATE TABLE DROP TABLE
ALTER TABLE CREATE VIEW DROP VIEW
CLOSE DATABASE DATABASE RENAME COLUMN
CREATE DATABASE DROP DATABASE RENAME TABLE
CREATE INDEX DROP INDEX
CREATE SYNONYM DROP SYNONYM
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 LOAD UNLOAD
DELETE SELECT 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 FETCH OPEN
DECLARE FLUSH 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 REVOKE SET LOCK MODE
LOCK TABLE UNLOCK TABLE
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 COMMIT WORK CREATE AUDIT
DROP AUDIT ROLLBACK WORK 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 tabla
2
.
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 Informix-
SQL 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.

2
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 Informix-
SQL 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 Informix-
SQL, 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 Informix-
SQL 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: CREATE TEMP TABLE tablatemporal
Sintaxis de SqlServer: CRETE TABLE #tablatemporal
117
Sintaxis de Oracle: CREATE GLOBAL TEMPORARY TABLE tablatemporal
Sintaxis de DB2: 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 Informix-
SQL 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 ("insert into tabla values(?)");
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.
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.
! DBA. Tiene todas las capacidades del privilegio Resource y adems la posibilidad de:
" 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.
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 a un usuario emitir instrucciones EXECUTE en un procedimiento
almacenado.
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 son
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.
Para conceder permisos de ejecucin de sentencias sobre tablas o vistas se ha de tener sobre
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.
! CONTROL. Concede todos los privilegios necesarios para:
" 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
! 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 la hora de procesar el cdigo, se indicar por
pantalla con el siguiente mensaje:
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: HOLDLOCK, NOLOCK, READCOMMITTED, REPEATABLEREAD,
SERIALIZABLE.
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 sistema que el servidor utiliza para
optimizar las bsquedas.
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 ( * ) from tabla1");
Try {
ASG_rsp_c5.next();
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
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.
Sintaxis:
<SENTENCIA FOREACH> ::=
FOREACH cursor [INTO variable_de_programa]
<sentencias>
END FOREACH
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 Longitud Descripcin
BINARY 1 byte
Para consultas sobre tabla adjunta de productos de bases de
datos que definen un tipo de datos Binario.
155
BIT 1 byte Valores Si/No True/False
BYTE 1 byte Un valor entero entre 0 y 255.
COUNTER 4 bytes Un nmero incrementado automticamente (de tipo Long)
CURRENCY 8 bytes
Un entero escalable entre 922.337.203.685.477,5808 y
922.337.203.685.477,5807.
DATETIME 8 bytes Un valor de fecha u hora entre los aos 100 y 9999.
SINGLE 4 bytes
Un valor en punto flotante de precisin simple con un rango
de -3.402823*10
38
a 1.401298*10
-45
para valores
negativos, 1.401298*10
-45
a 3.402823*10
38
para valores
positivos, y 0.
DOUBLE 8 bytes
Un valor en punto flotante de doble precisin con un rango de
-1.79769313486232*10
308
a -4.94065645841247*10
-324
para
valores negativos, 4.94065645841247*10
-324
a
1.79769313486232*10
308
para valores positivos, y 0.
SHORT 2 bytes Un entero corto entre -32,768 y 32,767.
LONG 4 bytes Un entero largo entre -2,147,483,648 y 2,147,483,647.
LONGTEXT
1 byte por
carcter
De cero a un mximo de 1.2 gigabytes.
LONGBINARY Segn se necesite De cero 1 gigabyte. Utilizado para objetos OLE.
CHARACTER
1 byte por
carcter
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 Sinnimos
BINARY VARBINARY
BIT
BOOLEAN
LOGICAL
LOGICAL1
YESNO
BYTE INTEGER1
COUNTER AUTOINCREMENT
CURRENCY MONEY
DATETIME
DATE
TIME
TIMESTAMP
SINGLE
FLOAT4
IEEESINGLE
REAL
DOUBLE
FLOAT
FLOAT8
IEEEDOUBLE
NUMBER
NUMERIC
156
SHORT
INTEGER2
SMALLINT
LONG
INT
INTEGER
INTEGER4
LONGBINARY
GENERAL
OLEOBJECT
LONGTEXT
LONGCHAR
MEMO
NOTE
TEXT
ALPHANUMERIC
CHAR
CHARACTER
STRING
VARCHAR
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
TM
JDBC 2.0 API) son:
JDBC SQL Type Descripcin
CHAR Cadena de tamao fijo de 0 a 254 caracteres de longitud
VARCHAR Cadena de longitud variable de 0 a 254 caracteres de longitud
LONGVARCHAR Cadena de longitud variable de al menos 1 Gb
NUMERIC
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.
DECIMAL Dato equivalente al NUMERIC
BIT Representa un solo bit que puede tomar los valores uno o cero
TINYINT Tipo entero de 8 bits, representa valores entre 0 y 255 con o sin signo
SMALLINT Entero con signo de 16 bits, toma valores entre -32768 and 32767
INTEGER
Entero con signo de 32 bits, toma valores entre -2147483648 and
2147483647
BIGINT
Entero con signo de 64-bit, admite valores desde -9223372036854775808
157
hasta 9223372036854775807
REAL
Nmero en punto flotante de simple precisin y al menos 7 dgitos de
mantisa
FLOAT Tipo de dato equivalente al DOUBLE
DOUBLE
Nmero en punto flotante de doble precisin que soporta 15 dgitos de
mantisa
BINARY Dato de tipo binario de longitud fija de 0 a 254 bytes
VARBINARY Dato de tipo binario de longitud variable de 0 a 254 bytes
LONGVARBINARY Dato de tipo binario que admite al menos 1 Gb de datos
DATE Representa una fecha formada por da, mes, y ao
TIME Representa una unidad de tiempo en formato horas, minutos, y segundos.
TIMESTAMP
Tipo de dato donde almacenamos fecha y hora hasta una precisin de
microsegundos (6 dgitos de precisin).
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 un nmero de punto flotante con aproximadamente 7 dgitos
significativos.
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 (0001-
9999).
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 Tipo de valor Almacenado Tipo Dato SQL JDBC
BYTE Cadena binaria de longitud mxima 1 Gb LONGVARBINARY
CHAR | CHARACTER
Si cadena de caracteres de hasta 254 caracteres
ASCII
CHAR
CHAR | CHARACTER
Cadena de caracteres de ms de 254 caracteres
ASCII
LONGVARCHAR
DATE Fechas desde 31 de diciembre de 1899 DATE
DATETIME year to day Momentos en el tiempo que representan fechas DATE
DATETIME hour to second Momentos en el tiempo que representas horas TIME
160
DATETIME
Punto en el tiempo, especifica fechas combinadas
con la hora del da hasta precisin de
microsegundos
TIMESTAMP
DEC | DECIMAL |
NUMERIC
Nmero en punto fijo con una precisin mxima
de 16 dgitos
DECIMAL
DOUBLE PRECISION |
FLOAT
Nmero en punto flotante de hasta 14 dgitos de
precisin.
DOUBLE
INTEGER | INT
Entero, desde -2,147,483,647 hasta
+2,147,483,647
INTEGER
INTERVAL Intervalos de tiempo no soportado
MONEY
Cantidad monetaria definida con escala y
precisin
DECIMAL(16,2)
SMALLFLOAT | REAL
Nmero en punto flotante de hasta 7 dgitos de
precisin
REAL
SMALLINT Nmero entero desde -32,767 hasta +32,767 SMALLINT
SERIAL Tipo de dato incremental INTEGER
TEXT Cadena de caracteres de longitud mxima 1 Gb LONGVARCHAR
VARCHAR
Cadena de longitud variable y no mas de 255
caracteres
VARCHAR
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 -2
31
(-2.147.483.648) y 2
31
- 1
(2.147.483.647).
INTEGER es un sinnimo para INT.
SMALLINT datos enteros comprendidos entre 2
15
(-32.768) y 2
15
- 1 (32.767).
TINYINT Datos enteros comprendidos 0 y 255.
BIGINT Datos enteros (nmeros enteros) comprendidos entre -2
63
(-9.223.372.036.854.775.808)
y 2
63
-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 - 10
38
+1 y 10
38
- 1.
NUMERIC y DEC Son sinnimo de DECIMAL.
MONEY Y SMALLMONEY
MONEY Valores de moneda comprendidos entre -2
63
(-922.337.203.685.477,5808) y 2
63
- 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 2
31
- 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 2
30
- 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 2
31
- 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 Tipo Dato SQL JDBC
BINARY BINARY
BIT BIT
CHAR CHAR
DATETIME TIMESTAMP
DECIMAL DECIMAL
DECIMAL() IDENTITY DECIMAL
FLOAT FLOAT
IMAGE LONGVARBINARY
INT INTEGER
INT IDENTITY INTEGER
MONEY DECIMAL
NCHAR CHAR
NTEXT LONGVARCHAR
NUMERIC NUMERIC
NUMERIC() IDENTITY NUMERIC
NVARCHAR VARCHAR
REAL REAL
SMALLDATETIME TIMESTAMP
SMALLINT SMALLINT
SMALLINT IDENTITY SMALLINT
SMALLMONEY DECIMAL
SYSNAME VARCHAR
TEXT LONGVARCHAR
TIMESTAMP BINARY
164
TINYINT TINYINT
TINYINT IDENTITY TINYINT
UNIQUEIDENTIFIER CHAR
VARBINARY VARBINARY
VARCHAR VARCHAR
BIGINT BIGINT
BIGINT IDENTITY BIGINT
SQL_VARIANT 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 Representacin
DECIMAL, DEC NUMBER
NUMERIC NUMBER
INTEGER NUMBER
INT NUMBER
TINYINT NUMBER
SMALLINT NUMBER(38)
BIGINT NUMBER
FLOAT NUMBER
DOUBLE PRECISION NUMBER
REAL NUMBER
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 Tipo Dato SQL JDBC
CHAR CHAR
VARCHAR VARCHAR
LONG | CLOB LONGVARCHAR
NUMBER NUMERIC
NUMBER DECIMAL
NUMBER BIT
NUMBER TINYINT
NUMBER SMALLINT
NUMBER INTEGER
NUMBER BIGINT
NUMBER REAL
NUMBER FLOAT
NUMBER DOUBLE
NUMBER BINARY
167
RAW VARBINARY
LONGRAW | BLOB LONGVARBINARY
DATE DATE
DATE TIME
TIMESTAMP 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 double-
bytes 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 n va desde 1 hasta 16336
double-byte.
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 Tipo dato SQL JDBC
SMALLINT BIT, TINYINT, SMALLINT
169
INTEGER INTEGER
REAL FLOAT, REAL
DOUBLE DOUBLE
DECIMAL NUMERIC, DECIMAL
CHAR CHAR
GRAPHIC CHAR
VARCHAR VARCHAR, LONGVARCHAR
VARGRAPHIC VARCHAR
CLOB(n) VARCHAR, LOGVARHAR, CLOB
BINARY BINARY
VARBINARY VARBINARY
BLOB(n) VARBINARY, LONGVARBINARY
DATE DATE
TIME TIME
TIMESTAMP TIMESTAMP
BLOB BLOB
CLOB CLOB
DBCLOB 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
Tipo Dato
JDBC Informix
Tipo Dato
SQLSERVER
Tipo Dato
Oracle
Tipo Dato DB2
BYTE LONGVARBINARY IMAGE LONGRAW |BLOB BLOB
CHAR | CHARACTER ("254) CHAR ("254) CHAR ("8000) CHAR("2000) CHAR ("254)
CHAR | CHARACTER ("35767) LONGVARCHAR TEXT ("2 Gb) LONG (" 2 Gb) VARCHAR ("35767)
DATE DATE DATETIME DATE DATE
DATETIME year to day DATE DATETIME DATE DATE
DATETIME hour to second TIME DATETIME DATE TIME
DATETIME TIMESTAMP DATETIME TIMESTAMP TIMESTAMP
DEC | DECIMAL | NUMERIC DECIMAL DECIMAL DECIMAL DECIMAL
DOUBLE PRECISION | FLOAT FLOAT FLOAT FLOAT FLOAT
INTEGER | INT INTEGER INTEGER INTEGER INTEGER
INTERVAL no soportado ---------- ---------- ----------
MONEY DECIMAL DECIMAL DECIMAL DECIMAL
SMALLFLOAT | REAL REAL REAL REAL REAL
SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT
SERIAL INTEGER INTEGER INTEGER INTEGER
TEXT ("2 Gb) LONGVARCHAR TEXT ("2 Gb) CLOB ("4 Gb) CLOB ("2 Gb)
VARCHAR ("254) VARCHAR VARCHAR("8000) VARCHAR("4000) VARCHAR ("4000)
Tabla 29: Mapeo entre tipos de datos Informix-SQL y el resto de gestores

Tipo Dato Informix
Tipo Dato
JDBC Informix
Tipo Dato JDBC
SQLSERVER
Tipo Dato
JDBC Oracle
Tipo Dato JDBC
DB2
BYTE LONGVARBINARY LONGVARBINARY LONGVARBINARY LONGVARBINARY
CHAR | CHARACTER CHAR CHAR CHAR CHAR
CHAR | CHARACTER LONGVARCHAR LONGVARCHAR LONGVARCHAR LONGVARCHAR
DATE DATE TIMESTAMP DATE DATE
DATETIME year to day DATE TIMESTAMP DATE DATE
DATETIME hour to second TIME TIMESTAMP TIME TIME
DATETIME TIMESTAMP TIMESTAMP TIMESTAMP TIMESTAMP
DEC | DECIMAL | NUMERIC DECIMAL DECIMAL DECIMAL DECIMAL
DOUBLE PRECISION | FLOAT FLOAT FLOAT FLOAT FLOAT
INTEGER | INT INTEGER INTEGER INTEGER INTEGER
INTERVAL no soportado ---------- ---------- ----------
MONEY DECIMAL DECIMAL DECIMAL DECIMAL
SMALLFLOAT | REAL REAL REAL REAL REAL
171
SMALLINT SMALLINT SMALLINT SMALLINT SMALLINT
SERIAL INTEGER
INTEGER IDENTITY INTEGER INTEGER
GENERATED AS
IDENTITY
TEXT LONGVARCHAR LONGVARCHAR LONGVARCHAR LONGVARCHAR
VARCHAR VARCHAR VARCHAR VARCHAR 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 Tipo de dato Java
CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC | DECIMAL java.math.BigDecimal
SMALLINT short
INTEGER int
REAL float
FLOAT double
DOUBLE double
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP 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 Tipo de dato SQL JDBC
String VARCHAR o LONGVARCHAR
java.math.BigDecimal NUMERIC | DECIMAL
short SMALLINT
int INTEGER
float REAL
Double DOUBLE
byte[] VARBINARY o LONGVARBINARY
java.sql.Date DATE
174
java.sql.Time TIME
java.sql.Timestamp 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 Funcin Java para recuperarlo
CHAR GetString
VARCHAR GetString
LONGVARCHAR GetAsciiStream, getCharacterStream, getString
NUMERIC | DECIMAL GetBigDecimal, getDouble
SMALLINT GetShort
INTEGER GetInt
REAL GetFloat
FLOAT GetDouble
DOUBLE GetDouble
LONGVARBINARY GetBinaryStream
DATE GetDate
TIME GetTime
175
TIMESTAMP GetTimestamp
Tabla 33: Funciones para recuperacin de datos del gestor de bases de datos
CONVERSIONES DE TIPOS DE DATOS
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.
En este punto se trata:
! 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 &






Tipo de dato origen #

C
H
A
R


V
A
R
C
H
A
R


I
N
T
E
G
E
R

S
M
A
L
L
I
N
T


F
L
O
A
T

S
M
A
L
L
F
L
O
A
T

D
E
C
I
M
A
L

M
O
N
E
Y

D
A
T
E


D
A
T
E
T
I
M
E


I
N
T
E
R
V
A
L


CHAR Y Y Y Y Y Y Y Y Y Y
VARCHAR Y Y Y Y Y Y Y Y Y Y
INTEGER Y Y Y Y Y Y Y
SMALLINT Y Y Y Y Y Y Y Y
FLOAT Y Y Y Y Y Y Y
SMALLFLOAT Y Y Y Y Y Y Y Y
DECIMAL Y Y Y Y Y Y Y Y
MONEY Y Y Y Y Y Y Y Y
DATE Y Y Y Y Y Y Y Y Y
DATETIME Y Y Y
INTERVAL Y Y
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 &




Tipo de dato origen #

B
I
N
A
R
Y

V
A
R
B
I
N
A
R
Y

C
H
A
R

V
A
R
C
H
A
R

N
C
H
A
R

N
V
A
R
C
H
A
R

D
A
T
E
T
I
M
E

S
M
A
L
L
D
A
T
E
T
I
M
E

D
E
C
I
M
A
L

N
U
M
E
R
I
C

F
L
O
A
T

R
E
A
L

B
I
G
I
N
T

I
N
T

S
M
A
L
L
I
N
T

T
I
N
Y
I
N
T

M
O
N
E
Y

S
M
A
L
L
M
O
N
E
Y

B
I
T

T
I
M
E
S
T
A
M
P

U
N
I
Q
U
E
I
D
E
N
T
I
F
I
E
R

I
M
A
G
E

N
T
E
X
T

T
E
X
T

S
Q
L
_
V
A
R
I
A
N
T

BINARY Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VARBINARY Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
177
CHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VARCHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
NCHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
NVARCHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
DATETIME Y Y Y Y Y Y
SMALLDATETIME Y Y Y Y Y Y
DECIMAL Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
NUMERIC Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
FLOAT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
REAL Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
BIGINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
INT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
SMALLINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
TINYINT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
MONEY Y Y Y Y Y Y Y Y Y Y Y Y Y Y
SMALLMONEY Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
BIT Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
TIMESTAMP Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
UNIQUEIDENTIFIER Y Y Y Y Y Y Y
IMAGE Y Y Y
NTEST Y Y Y
TEXT 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:


Tipo de dato destino &




Tipo de dato origen #

C
H
A
R

V
A
R
C
H
A
R

D
A
T
E

T
I
M
E
S
T
A
M
P

L
O
N
G

N
U
M
B
E
R

R
O
W

R
O
W
I
D

C
L
O
B

B
L
O
B

N
C
H
A
R

N
V
A
R
C
H
A
R
2

N
C
L
O
B

B
I
N
A
R
Y
_
F
L
O
A
T

N

B
I
N
A
R
Y
_
D
O
U
B
L
E

CHAR Y Y Y Y Y Y Y Y Y Y Y
VARCHAR Y Y Y Y Y Y Y Y Y Y Y Y
DATE Y Y Y Y
TIMESTAMP Y Y Y Y Y
LONG Y Y Y Y Y Y Y Y
NUMBER Y Y Y Y Y Y
ROW Y Y Y Y Y Y
ROWID Y Y Y Y
CLOB Y Y Y Y Y Y
BLOB Y
NCHAR Y Y Y Y Y Y Y Y Y Y Y Y
178
NVARCHAR2 Y Y Y Y Y Y Y Y Y Y Y Y
NCLOB Y Y Y Y Y Y
BINARY_FLOAT Y Y Y Y Y Y
BINARY_DOUBLE Y Y Y Y Y Y
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 &





Tipo de dato origen #

S
M
A
L
L
I
N
T

I
N
T
E
G
E
R


D
E
C
I
M
A
L


R
E
A
L


D
O
U
B
L
E


C
H
A
R


V
A
R
C
H
A
R


C
L
O
B


G
R
A
P
H
I
C


V
A
R
G
R
A
P
H
I
C


D
B
C
L
O
B


B
L
O
B

D
A
T
E


T
I
M
E


T
I
M
E
S
T
A
M
P


R
O
W
I
D


SMALLINT Y Y Y Y Y Y
INTEGER Y Y Y Y Y Y
DECIMAL Y Y Y Y Y Y
REAL Y Y Y Y Y Y
DOUBLE Y Y Y Y Y Y
CHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VARCHAR Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y
CLOB Y Y Y Y Y Y
GRAPHIC Y Y Y Y Y Y Y Y Y Y Y Y Y Y
VARGRAPHIC Y Y Y Y Y Y Y Y Y Y Y Y Y Y
DBCLOB Y Y Y Y Y Y
BLOB
DATE Y Y
TIME Y Y
TIMESTAMP Y Y Y Y
ROWID Y Y Y
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
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 Informix-
SQL 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 &



Tipo de dato origen #

C
H
A
R
/
t
e
x
t

V
A
R
C
H
A
R

D
A
T
E
T
I
M
E

D
E
C
I
M
A
L

N
U
M
E
R
I
C

F
L
O
A
T

R
E
A
L

I
N
T

S
M
A
L
L
I
N
T

CHAR/text Y Y/N Y/N Y/N Y/N Y/N Y/N Y/N
VARCHAR Y Y Y Y Y Y Y Y
DATETIME Y Y
DECIMAL Y Y Y Y Y Y Y Y
NUMERIC Y Y Y Y Y Y Y Y
FLOAT Y Y Y Y Y Y Y Y
REAL Y Y Y Y Y Y Y Y
INT Y Y Y Y Y Y Y Y
SMALLINT Y Y Y Y Y Y Y Y
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 nmero
3
.

3
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()) = 39149 = 09/03/2007
CONVERT(int, CONVERT(datetime,'12/31/1899')) = -1 = 31/12/1899
CONVERT(int, CONVERT(datetime,'01/01/1900')) = 0 = 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 &



Tipo de dato origen #


C
H
A
R

/
l
o
n
g


V
A
R
C
H
A
R



D
A
T
E



T
I
M
E
S
T
A
M
P



N
U
M
B
E
R


CHAR /long Y Y/N Y Y/N
VARCHAR Y Y Y Y
DATE Y Y
TIMESTAMP Y Y
NUMBER Y Y
Tabla 39: Conversiones implcitas necesarias para Oracle
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 &





Tipo de dato origen #

S
M
A
L
L
I
N
T

I
N
T
E
G
E
R


D
E
C
I
M
A
L


R
E
A
L


D
O
U
B
L
E


C
H
A
R

/
V
A
R
C
H
A
R

V
A
R
C
H
A
R


D
A
T
E


T
I
M
E
S
T
A
M
P


SMALLINT Y Y Y Y Y Y
INTEGER Y Y Y Y Y Y
DECIMAL Y Y Y Y Y Y
REAL Y Y Y Y Y Y
DOUBLE Y Y Y Y Y Y
CHAR/VARCHAR Y Y Y Y Y Y Y Y
VARCHAR Y Y Y Y Y Y Y Y
DATE Y Y
TIMESTAMP Y Y Y
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.
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
Ejemplos:
Cdigo fuente Informix-SQL: select campo1[2,4] from tabla
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 campo1
257 25/07/2006
258 25/07/2006
259 25/07/2006
260 25/07/2006
261 25/07/2006
262 25/07/2006
263 31/12/1900
264 25/07/2006
Ejemplo de consulta del ROWID sobre Oracle:
SQL> select rowid, tabla.* from tabla
ROWID UNO DOS
------------------ ------ ---------
AAADJiAABAAADhNAAA 1 1
AAADJiAABAAADhNAAB 2 1
AAADJiAABAAADhNAAC 3 1
AAADJiAABAAADhNAAD 4 1
AAADJiAABAAADhNAAE 5 1
AAADJiAABAAADhNAAF 6 1
AAADJiAABAAADhNAAG 7 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 campo1 campo2
F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA 1
A8908CB3-7230-43C4-BE39-0E0194D3380E A8908CB3-7230-43C4-BE39-0E0194D3380E 1
38679D43-0EF3-40BD-A132-D651BF98F909 38679D43-0EF3-40BD-A132-D651BF98F909 1
B7334E8B-5D61-429B-B339-F7E2A22440C1 B7334E8B-5D61-429B-B339-F7E2A22440C1 1
095BA7DA-5A43-4B00-8BA5-F513221E1624 095BA7DA-5A43-4B00-8BA5-F513221E1624 1
CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 1
4DDA3709-380E-4B90-BBB1-1648414E9A5A 4DDA3709-380E-4B90-BBB1-1648414E9A5A 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.)
Otra forma que se puede plantear es mediante la siguiente definicin:
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 campo1 campo2
F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA F1AC0A33-BBB6-4C47-8E40-179DD83C8EAA 1
A8908CB3-7230-43C4-BE39-0E0194D3380E A8908CB3-7230-43C4-BE39-0E0194D3380E 1
38679D43-0EF3-40BD-A132-D651BF98F909 38679D43-0EF3-40BD-A132-D651BF98F909 1
187
B7334E8B-5D61-429B-B339-F7E2A22440C1 B7334E8B-5D61-429B-B339-F7E2A22440C1 1
095BA7DA-5A43-4B00-8BA5-F513221E1624 095BA7DA-5A43-4B00-8BA5-F513221E1624 1
CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA CBCF8013-274A-4593-ADD7-AA0C0CBFE4FA 1
4DDA3709-380E-4B90-BBB1-1648414E9A5A 4DDA3709-380E-4B90-BBB1-1648414E9A5A 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 campo2
------ --------------------
!AYCQs 1
!By3 1
!BH4 1
!B&8 1
!BV 1
!B5C$ 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

4
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

188
camporowid campo2
------ --------------------
1 1
2 1
3 1
4 1
5 1
6 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
datetime (2006-08-25 22:10:12.453) year to fraction $
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')
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)
datetime ( 2006-08-25 22:10:12.453 ) year to fraction $
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.
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 Informix-
SQL. 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: yyyy-
mm-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

return @hex
end
go
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 han sido tratadas en el punto anterior:
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.
! 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 | literal_fechahora | cadena_caracteres |
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.
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 ( select * from prueba2 where campo2=
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:

Operador Propsito
+, - Operadores unarios: positivo, negativo.
*, / Operadores binarios: multiplicacin, divisin.
+, - Operadores binarios: suma, resta.
NOT Negacin.
<, <=, =, >, >=, !=, <> Operadores relacionales.
IN, BETWEEN, LIKE, MATCHES, SOME, ALL, ANY Operadores lgicos.
AND Conjuncin.
OR Disyuncin.
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 datos
5
.
! 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>

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

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 Propsito
+, - , ~ Operadores unarios: positivo, negativo, negacin
a nivel de bit.
* , / , % Operadores binarios: multiplicacin, divisin,
mdulo.
+ , - , + Operadores binarios: suma, resta, concatenacin
=, >, <, >=, <=, <>, !=, !>, !< Comparacin
^, &, | Comparacin a nivel de bit: or exclusivo, and y
or
NOT Negacin lgica
AND Conjuncin
ALL, ANY, BETWEEN, IN, LIKE, OR, SOME Operadores lgicos
= Asignacin
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; Da siguiente.
select sysdate 7 from dual; Semana pasada.
select sysdate + (10/1440) from dual; 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: suma y resta,
concatenacin.
=, !=, <, >, <=, >=, <> Comparacin.
IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT]
IN, EXISTS, IS OF type, SOME, ANY, ALL
Comparacin lgica.
NOT Negacin lgica
AND Conjuncin.
OR Disyuncin.
Tabla 43: Precedencia de operadores Oracle
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.
En DB2 se pueden combinar querys con diferentes conjunto de operadores para construir
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 Propsito
+, - Operadores unarios: positivo, negativo.
*, / Operadores binarios: multiplicacin, divisin.
+, - Operadores binarios: suma, resta.
SOME, ANY, ALL
NOT Negacin.
<, <=, =, >, >=, <> Operadores de comparacin.
EXISTS, IN, BETWEEN, LIKE, MATCHES Operadores lgicos.
AND Conjuncin.
OR Disyuncin.
Tabla 44: Precedencia de operadores Db2
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 sentencia ejecutado sobre el gestor de bases de datos Informix, suponiendo
que este interpreta la fecha como dd/mm/yyyy, ser 13, pero si ejecutamos esta misma
sentencia sobre un gestor de bases de datos que interprete la fecha como mm/dd/yyyy el
resultado ser 336 y por tanto la ejecucin del programa obtendr resultados diferentes a los
esperados.
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
Delimitador de cadenas o fechas Comilla doble comilla simple
Delimitador de decimal Punto
Formato de fecha mm/dd/yyyy
Formato fecha/hora yyyy-mm-dd hh:mm:ss.ffffff
Delimitador fecha Flash (/)
Das de la semana 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.
Ejemplos:
MDY4/ 07/01/1950
DMY2- 01-07-50
MDY4/ 07/01/1950
MDY20 070150
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
Delimitador de cadenas o fechas Comilla simple
Delimitador de decimal Punto
Formato de fecha mm/dd/yyyy (mdy)
Formato de fecha/hora yyyy-mm-dd hh:mm:ss.fff
Delimitador fecha slash (/)
Das de la semana 1 domingo, 2 lunes, ...., 7 sbado
Tabla 46: Formatos por defecto de SqlServer
Los formatos en los que se presentan las fechas pueden ser:
dma (da, mes ao) formato si el idioma es espaol.
mda (mes, da, ao) formato por defecto.
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 DATEFIRST
6
.

6
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
Delimitador de cadenas o fechas Comilla simple
Delimitador de decimal Punto
Formato de fecha dd/mm/yyyy
Formato de fecha/hora yyyy-mm-dd hh:mm:ss.fffffffff
Delimitador fecha slash , guin, punto, espacio en blanco, etc.
Das de la semana 1 lunes, ...., 7 domingo
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
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 en los diferentes
parmetros NLS referirse a la documentacin proporcionada por Oracle.
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
Delimitador de cadenas o fechas Comilla simple
Delimitador de decimal Punto
Formato de fecha dd/mm/yyyy
Formato de fecha/hora yyyy/mm/dd hh:mm:ss.fffff
Delimitador fecha slash (/)
Das de la semana 1 domingo, 2 lunes, ...., 7 sbado
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.
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
Delimitador de cadenas o fechas Comilla doble
214
Delimitador de decimal Punto
Formato de fecha yyyy-mm-dd
Formato de fecha/hora yyyy-mm-dd hh:mm:ss.fffffffff
Delimitador fecha guin (-)
Das de la semana 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 Informix SqlServer Oracle Db2
Delimitador de cadenas Comilla
simple/doble
Comilla simple Comilla simple Comilla simple
Delimitador de decimal

Punto Punto Punto Punto
215
Formato de fecha

dd/mm/yyyy dd/mm/yyyy dd/mm/yyyy dd/mm/yyyy
Formato fecha/hora yyyy-mm-dd hh:mm:ss.ffffff
Delimitador fecha

slash slash slash slash
Das de la semana 0 domingo, 1
lunes, ...., 6
sbado
1 lunes, 2
martes, ...., 7
domingo
1 lunes, 2
martes, ....., 7
domingo
1 domingo, 2
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 .....
Sentencia final:
select funciondiadelasemana ( campoX) 1 into vble from tablaY
#si es domingo
if vble = 0 then .....
" 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 .....
Sentencia final:
select funciondiadelasemana ( campoX) mod 7 into vble from tablaY
#si es domingo
if vble = 0 then .....
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:
select ( datepart(gw, campoX) % 7) from tablaY
#si es domingo
if vble = 0 then .....
Oracle:
select mod( campoX,'D') , 7) from tablaY;
#si es domingo
if vble = 0 then .....
Db2:
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 fecha/hora el tratamiento es similar.
Informix-SQL admite que en una cadena venga embebida un valor datetime siempre y cuando
tenga el siguiente formato: yyyy-MM-dd HH:mm:ss.ffffff. El tratamiento es similar al utilizado
para el reconocimiento de las constantes tipo fecha, vase el 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> se
reconoce el mismo en el anlisis sintctico.
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 ("insert into tabla values(?)");
x.setDate(1, fecha);
x.executeUpdate();

! 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:
define fecha date
insert into prueba1 values (esto es un prueba, fecha, 12)
Sentencia generada:
java.sql.date fecha;
x.executeUpdate("insert into prueba1 values ( 'esto es una prueba' , { d " + fecha + " }
, 12 ) ");
Sentencia original con tipo de datos fecha/hora:
define fechah datetime year to fraction
insert into prueba1 values (esto es un prueba, fechah, 12)
Sentencia generada:
java.sql.Timestamp fechah;
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.
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 Cte. SqlServer Cte. Oracle Cte. DB2
Fecha: 37256 convert(datetime,
37256 cte ,103);

to_date(
to_char(37256 cte,
99999999999),J)
date(37256 cte)
220
Fecha: 31/12/2006 31/12/2006
dateadd(dd,0,
datediff(dd,0,
31/12/2006))
31/12/2006
to_date(to_char(31/12
/2006,'dd/mm/yyyy'))
31/12/2006
date(31/12/2006)

FechaHora: datetime
(2007-12-10 12:32:40)
year to fraction
Convert
(datetime,'2007-12-10
11:21:30 ',121) )
timestamp '2007-12-10
11:21:30'
'2007-12-10 11:21:30'
Fecha-Hora: 2007-12-
10 12:32:40
Convert
(datetime,'2007-12-10
11:21:30 ',121) )
timestamp '2007-12-10
11:21:30'
'2007-12-10 11:21:30'
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 Informix SqlServer Oracle Db2
Da siguiente: 22/10/2007 39376 39375 2454396 732971
Da actual: 21/10/2007 39375 39374 2454395 732970
31/12/1899 0 -1 2415020 693595
01/01/1900 1 0 2415021 693596
02/01/1900 2 1 2415022 693597
03/01/1900 3 2 2415023 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
usuarios
7
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.

7
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 Costo total Coste Satisfecho Coste Restante
1 Definicin del Proyecto 1.272,00 1.272,00 0
2 Recopilacin de Informacin 3.840,00 3.840,00 0
4 Creacin del Analizador lxico 1.280,00 1.280,00 0
5 Creacin del Analizador sintctico 15.360,00 15.360,00 0
6 Aadir semntica, tabla de smbolos
y gestin de errores 3.840,00 3.840,00 0
7 Desarrollo mdulos generadores de
cdigo 7.680,00 7.680,00 0
9 Estudio sentencias SQL de distintos
gestores 7.680,00 7.680,00 0
10 Incorporacin de sentencias al
generador de cdigo 5.120,00 5.120,00 0
11 Pruebas 3.840,00 3.840,00 0
12 Customizacin 11.520,00 0 11.520,00
Total 61.432,00 49.912,00 11.520,00
Tabla 53: Coste del proyecto

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 = 0
BD_Oracle = 1
BD_Informix = 2
BD_InformixOL = 3
BD_InformixSE = 9
BD_Sybase = 4
BD_Sqlserver = 5
BD_Db2 = 6
BD_Ingres = 7
BD_Mysql = 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: jdbc:Informix-SQLi
" SqlServer: jdbc:sqlserver:
" Oracle: jdbc:oracle:thin:@
" Db2: 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 Formato Informix Formato Oracle y
Db2
Formato SqlServer
E DMY4/ ' dd/mm/yyyy dd/mm/yyyy 103
U MDY4/ ' mm/dd/yyyy mm/dd/yyyy 101
A Y4MD. ' yyyy.mm.dd yyyy.mm.dd 102
G DMY4. ' dd.mm.yyyy dd.mm.yyyy 104
I DMY4- ' dd-mm-yyyy dd-mm-yyyy 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| #Tipo conexion a la base de datos
oracle.jdbc.driver.OracleDriver| #DBdriver
jdbc:oracle:thin:@| #Driver
| #Origen ODBC (opcional)
| #path (opcional)
datos| #Base de datos
asg| #Host
1521| #Puerto
233
| #Informixserver (opcional)
informix| #Usuario
informix| #Passwd
1| #Generacin de codigo
E| #Idioma
| #Vbles entorno
0| #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| #Tipo conexion a la base de datos
sun.jdbc.odbc.JdbcOdbcDriver| #DBdriver
{INFORMIX 3.32 32 BIT}| #Driver
ifxdatos| #Origen ODBC (opcional)
| #path (opcional)
datos| #Base de datos
asg| #Host
1528| #Puerto
| #Informixserver (opcional)
informix| #Usuario
informix| #Passwd
2| #Generacin de codigo
E| #Idiosma
| #Entorno
1| #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 Indica que se genere archivo de traza para cada mdulo.
2 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.
3 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
! Ejecutar el resultado de la compilacin anterior
" java codigo_objeto
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
EJEMPLO SENTENCIA ALTER TABLE
CDIGO FUENTE INFORMIX-4GL: ALTERTABLE.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)
)

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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;

public class altertable
{
private static AccesDB ASGcondb = null;
public static void main(String argv[]) throws Exception
{
ASGcon.cargaparamcon();
ASGcondb = new AccesDB("datos");
236
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 ");
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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) ");
237
ASGcondb.exeUpdate("alter table tabla1 add unique (campo2)");
ASGcondb.exeUpdate("alter table tabla1 add unique ( campo11 ) ");
}

}
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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
238
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
CDIGO OBJETO: TRANSAC.JAVA
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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
239
CDIGO OBJETO: CREATEINDEX.JAVA
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;

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 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 ");
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();
240
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 SQLSERVER
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 ");
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.*;
241
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 );
}

}
CDIGO OBJETO DB2
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 ");
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);
242
}
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 );
}

}
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 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 , 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.*;
243
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();
}
}
CDIGO OBJETO ORACLE
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 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 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) 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,
244
unique (campo1,campo3),
campo4 decimal(2,0) not null,
distinct (campo4),
campo5 int,
campo6 date,
campo7 datetime hour to minute
)

close database

end main
CDIGO OBJETO: CREATETTABLE.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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) , campo3
decimal(4,2) , campo4 decimal(2,0) not null , campo5 integer , campo6 date , campo7 timestamp ) ");
ASGcondb.finConexionDB();
}

}
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," ", dos

end main
CDIGO OBJETO: CREATEVIEW.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
246
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 SQLSERVER/DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}

}
247
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 into tabla1 values (1,1)
insert into tabla1 values (2,2)
insert into tabla1 values (3,3)
insert into tabla1 values (4,4)

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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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);
}
248
catch (SQLException e) {}
ASG_r2.close();
ASG_st2.close();
System.out.println("Nmero de filas: " + uno );
ASGcondb.exeUpdate("delete from sinonimo1 where campo1 = 2 ");
Statement ASG_st3 = ASGcondb.retCon().createStatement();
ResultSet ASG_r3 = ASG_st3.executeQuery("select count ( * ) from tabla1 ");
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 = 3 ");
Statement ASG_st4 = ASGcondb.retCon().createStatement();
ResultSet ASG_r4 = ASG_st4.executeQuery("select count ( * ) from tabla1 ");
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 );
}

}
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;

public class dropindex
{
249
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();
}

}
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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.*;
251
import 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) 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
CDIGO FUENTE INFORMIX-4GL: GRANT.4GL
main
grant dba to public
grant insert on tabla1 to public
end main
CDIGO OBJETO: GRANT.JAVA
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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
CDIGO FUENTE INFORMIX-4GL: INSERT.4GL
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");

create view vista1 (campo1,campo2,campo3) as select r.campo1,r.campo2, 3 from tabla1 r

insert into tabla2 select campo3, campo2 from vista1
252

end main
CDIGO OBJETO: INSERT.JAVA
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 , 3
from tabla1 r ");
ASGcondb.exeUpdate("insert into tabla2 select campo3 , campo2 from vista1 ");
}
}
EJEMPLO SENTENCIA LOAD/UNLOAD
CDIGO FUENTE INFORMIX-4GL: LOADUNLOAD.4GL
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")

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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ");
}
}
253
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
CDIGO OBJETO: LOCK.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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("insert into tabla1 values ( 3 , 3 , 'tres' ) ");
ASGcondb.exeUpdate("update tabla1 set campo2 = 4 where campo1 = 1 ");
ASGcondb.finTransacOK();
}
}
CDIGO OBJETO ORACLE/DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
254
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();
}
}
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 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 ");
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 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 ");
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.*;
255
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");
}
}
EJEMPLO SENTENCIA RENAME TABLA
CDIGO FUENTE INFORMIX-4GL: RENAMETABLE.4GL
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 OBJETO: RENAMETABLE.JAVA
CDIGO OBJETO INFORMIX/ORACLE/DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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;
256
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'");
}
}
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 = 2
let vdos = 2.0
prepare s3 from "insert into tabla1 values (?,?,?)"
execute s3 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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);
257
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 );
}

}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
258
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 );
}
}
EJEMPLO SENTENCIA DECLAREFORUPDATE
CDIGO FUENTE INFORMIX-4GL: DECLAREFORUPDATE.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 = 2
let vdos = 2.0
prepare s3 from "insert into tabla1 values (?,?,?)"
execute s3 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" where current of c6
#delete from tabla1 where current of c6
close c6

update statistics
declare c7 cursor for select * from tabla1 where campo1 != 4 for update

open c7
fetch c7 into vuno
delete from tabla1 where current of c7
close c7

update statistics
end main
CDIGO OBJETO: DECLAREFORUPDATE.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import ASGutil.*;

public class declareforupdate
{
static int vcuatro ;
private static AccesDB ASGcondb = null;
public static void main(String argv[]) throws Exception
{
259
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();
}
}
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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;
260
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();
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
261
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();
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
262
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();
}
}
EJEMPLO SENTENCIA FOREACH-FORUPDATE
CDIGO FUENTE INFORMIX-4GL: FOREACHFORUPDATE.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
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 into tabla1 values (3,'tres',3)
insert into tabla1 values (4,'cuatro',4)
insert into tabla1 values (5,'cinco',5)
insert into tabla1 values (6,'seis',6)
insert into tabla1 values (7,'siete',7)


263
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 "Estado final"
prepare s8 from "select * from tabla1"
declare c8 cursor for s8
foreach c8 into vuno,vtres,vdos
message "campos: ", vuno," ",vtres,vdos
end foreach

end main
CDIGO OBJETO: FOREACHFOR.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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
{
264
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 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();
}
}
CDIGO OBJETO SQLSERVER
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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);
265
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();
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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" ;
266
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();
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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;
267
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();
}
}
EJEMPLO SENTENCIA TIPOS DE DATOS
CDIGO FUENTE INFORMIX-4GL: TIPOSDATOS.4GL
#tipos de datos admitidos
database datos

268
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
CDIGO OBJETO: TIPOSDATOS.JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
269
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 ");
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 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 ;
java.sql.Date dos ;
java.sql.Timestamp tres ;
uno = "";
dos = null;
tres = null;
ASGcondb.activaControlError();
ASGcondb.exeUpdate("drop table prueba1 ");
270
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 );
}
}
CDIGO OBJETO SQLSERVER
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 ;
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.*;
271
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 );
}
}
CDIGO OBJETO DB2
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 ;
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();
272
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 );
}
}
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 uno = "hola mundo"
let cuatro = 24
let dos = today;
let tres = current;
let cinco = cuatro;
let tres = "2007-07-22 12:33:20.444";
let dos = "22/07/2007";
let fecha = 40000

message "campo1: ", uno
message "campo2: ", dos
message "campo3: ", tres
message "campo4: ", cuatro
message "campo5: ", cinco
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 into prueba1 values ("esto es una prueba",today,current,12,12.3)
insert into prueba1 values (uno,dos,tres,cuatro,12.3)
insert into prueba1 values (uno,fecha,tres,cuatro,1.3)
insert into prueba1 values (uno,"15/08/2006","2007-07-21 13:44:30.23",cuatro,12.3)
insert into prueba1 values (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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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;
273
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 );
}
}
CDIGO OBJETO SQLSERVER
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ) ");
274
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 , 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 ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 '2007-
07-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-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 );
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
275
import 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 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 dia = day(today)
let mes = month(today);
let diaw = weekday(today)
let anio = year(today)
let fecha1 = date("31/12/2006")
let fecha1 = date(today)
let fecha2 = mdy(month(today),dia,year(today))
let fecha3 = datetime (2007-07-22 12:33:20.444) year to fraction

message "dia: ", dia
message "mes: ", mes
message "dia de la semana: ", diaw
message "ao: ", anio
message "fecha: ", fecha1
276
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 "dia: ", dia
message "mes: ", mes
message "dia de la semana: ", diaw
message "ao: ", anio
message "fecha: ", fecha1
message "fecha: ", fecha2

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 "dia: ", dia
message "mes: ", mes
message "dia de la semana: ", diaw
message "ao: ", anio
message "fecha: ", fecha1
message "fecha: ", fecha2

end main
CDIGO OBJETO: EXPRSQL4JAVA
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
277
ResultSet ASG_r1 = ASG_st1.executeQuery("select day ( today ) , month ( today ) , weekday ( 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 ) , diaw = weekday ( 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) );
}
}
CDIGO OBJETO SQLSERVER
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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
{
278
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 ( dateadd(dd,0, datediff(dd,0,getdate())) ) , mes = month (
dateadd(dd,0, datediff(dd,0,getdate())) ) , diaw = datepart ( dw, dateadd(dd,0, datediff(dd,0,getdate())) ) % 7 , anio = year
( dateadd(dd,0, datediff(dd,0,getdate())) ) , fecha1 = convert(datetime, convert(datetime,'31/12/2006',103) ,103) , fecha2 =
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) );
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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);
279
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 = 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) );
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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);
280
}
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) );
}
}
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
281
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 );
}
}
CDIGO OBJETO SQLSERVER
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
}
}
282
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
283
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 );
}
}
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 into prueba1 values ("esto es una prueba",10,"16")
insert into prueba1 values ("esto es una prueba",20,"16")
insert into prueba1 values ("esto es una prueba",20,"16")
insert into prueba1 values ("esto es una prueba",20,"16")
insert into prueba1 values ("esto es una prueba",10,"16")
insert into prueba1 values ("esto es una 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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) , campo2 decimal(10,2) , campo3 char(20) ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10 , '16' ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 20 , '16' ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 20 , '16' ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 20 , '16' ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10 , '16' ) ");
ASGcondb.exeUpdate("insert into prueba1 values ( 'esto es una prueba' , 10 , '16' ) ");
Statement ASG_st1 = ASGcondb.retCon().createStatement();
ResultSet ASG_r1 = ASG_st1.executeQuery("select count ( * ) from prueba1 ");
284
try
{
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 l = weekday("03/09/2007")
let m =weekday("04/09/2007")
let x =weekday("05/09/2007")
let j =weekday("06/09/2007")
let v =weekday("07/09/2007")
let s =weekday("08/09/2007")
let d =weekday("09/09/2007")
let h =weekday(today)

message "lunes: ",l
message "martes: ",m
message "miercoles: ",x
message "jueves: ",j
message "viernes: ",v
message "sabado: ",s
message "domingo: ",d
message "hoy: ",h
message "-----------------------"

whenever error continue
drop table prueba2
285
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)

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 "lunes: ",l
message "martes: ",m
message "miercoles: ",x
message "jueves: ",j
message "viernes: ",v
message "sabado: ",s
message "domingo: ",d
message "hoy: ",h

end main
CDIGO OBJETO: EXPRSQL7.JAVA
CDIGO OBJETO INFORMIX

import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 );
286
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 SQLSERVER
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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");
287
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
, fecha2 date ) ");
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ;
288
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 , 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 into prueba1 values ("prueba",1,8.2,today,"31/12/2007")
insert into prueba1 values ("otra Cosa",2,3,today,"31/12/2007")
insert into prueba1 values ("Prueba",3,1,today,today)
insert into prueba2 values ("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
289
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
CDIGO OBJETO: OPERSQL.4GL
CDIGO OBJETO INFORMIX
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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");
290
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 , 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
{
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 +"'} , today ) ");
Statement ASG_st6 = ASGcondb.retCon().createStatement();
ResultSet ASG_r6 = ASG_st6.executeQuery("select {d '"+ fecha +"'} - campo4 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 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();
291
ResultSet ASG_r8 = ASG_st8.executeQuery("select {d '"+ fecha +"'} - today 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
{
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();
292
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();
ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) from prueba1 where campo1 matches 'P*' ");
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 $ : " + dos );
Statement ASG_st24 = ASGcondb.retCon().createStatement();
ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not like 'P%' escape '\\'
");
try
{
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 like '_rueba' escape
'\\' ");
try
{
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 matches '?[a-z]ueba' ");
try
{
ASG_r26.next();
dos = ASG_r26.getInt(1);
}
catch (SQLException e) {}
ASG_r26.close();
ASG_st26.close();
293
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 matches '?[^r-s]ueba'
");
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 matches '?[rs]ueba' ");
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 matches '?[^rs]ueba' ");
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 matches '?[a-z123456789A-
Z]ueba' ");
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 matches '?[a-zA-
Z123456789]ueba' ");
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
294
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 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 ");
295
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();
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);
}
296
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();
ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) from prueba1 where campo1 like 'P%' escape '$'
");
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 $ : " + dos );
Statement ASG_st24 = ASGcondb.retCon().createStatement();
ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not like 'P%' escape '\\'
");
try
{
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 like '_rueba' escape
'\\' ");
try
{
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 like '_[a-z]ueba' escape
'\\' ");
try
{
ASG_r26.next();
dos = ASG_r26.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 '_[^r-s]ueba' escape
'\\' ");
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 '_[rs]ueba' escape
'\\' ");
try
{
ASG_r28.next();
dos = ASG_r28.getInt(1);
}
catch (SQLException e) {}
297
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 '_[^rs]ueba' escape
'\\' ");
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 '_[a-z123456789A-
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 ?[a-z123456789A-Z]ueba : " + dos );
Statement ASG_st31 = ASGcondb.retCon().createStatement();
ResultSet ASG_r31 = ASG_st31.executeQuery("select count ( * ) from prueba1 where campo1 like '_[a-zA-
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 ?[a-zA-Z123456789]ueba : " + dos );
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
298
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
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
{
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 = 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 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')) 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
{
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();
299
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();
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
{
300
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();
ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) from prueba1 where campo1 like 'P%' escape '$'
");
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 $ : " + dos );
Statement ASG_st24 = ASGcondb.retCon().createStatement();
ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not like 'P%' escape '\\'
");
try
{
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 like '_rueba%' escape
'\\' ");
try
{
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 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_r26.next();
dos = ASG_r26.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') ");
301
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_r31.close();
ASG_st31.close();
System.out.println("filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : " + dos );
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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();
302
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 days({d '"+ fecha +"'} ) - days(campo4 ) 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 +"'} , current date ) ");
Statement ASG_st6 = ASGcondb.retCon().createStatement();
ResultSet ASG_r6 = ASG_st6.executeQuery("select days({d '"+ fecha +"'} ) - days(campo4 ) 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 days(campo5 ) - days(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 days({d '"+ fecha +"'} ) - days(current date ) 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
{
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();
303
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();
304
ResultSet ASG_r23 = ASG_st23.executeQuery("select count ( campo2 ) from prueba1 where campo1 like 'P%'
escape '$' ");
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 $ : " + dos );
Statement ASG_st24 = ASGcondb.retCon().createStatement();
ResultSet ASG_r24 = ASG_st24.executeQuery("select count ( * ) from prueba1 where campo1 not like 'P%' escape '\\'
");
try
{
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 like '_rueba%' escape
'\\' ");
try
{
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 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_r26.next();
dos = ASG_r26.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) {}
305
ASG_r31.close();
ASG_st31.close();
System.out.println("filas que cumplen la condicion matches ?[a-zA-Z123456789]ueba : " + dos );
}
}
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 > 39376
message cuatro

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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ) ");
307
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
00:00:00.0' ");
try
{
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' >
campo4 ");
308
try
{
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 java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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 ) ;
309
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 );
310
Statement ASG_st13 = ASGcondb.retCon().createStatement();
ResultSet ASG_r13 = ASG_st13.executeQuery("select count ( campo1 ) from prueba1 where convert(datetime,'2007-10-22
00:00:00.0',121) > campo4 ");
try
{
ASG_r13.next();
cuatro = ASG_r13.getInt(1);
}
catch (SQLException e) {}
ASG_r13.close();
ASG_st13.close();
System.out.println(cuatro );
}
}
CDIGO OBJETO ORACLE
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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") ) ;
311
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 '2007-
10-22 00:00:00.0' ");
try
{
ASG_r12.next();
cuatro = ASG_r12.getInt(1);
}
catch (SQLException e) {}
312
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 timestamp '2007-10-22
00:00:00.0' > campo4 ");
try
{
ASG_r13.next();
cuatro = ASG_r13.getInt(1);
}
catch (SQLException e) {}
ASG_r13.close();
ASG_st13.close();
System.out.println(cuatro );
}
}
CDIGO OBJETO DB2
import java.sql.*;
import ASGdb.*;
import ASGdbutil.*;
import 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) );
313
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 =
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( 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( current date ) 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 > date('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 date('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 , 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 = 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
00:00:00.0' ");
try
{
ASG_r12.next();
cuatro = ASG_r12.getInt(1);
}
catch (SQLException e) {}
314
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' >
campo4 ");
try
{
ASG_r13.next();
cuatro = ASG_r13.getInt(1);
}
catch (SQLException e) {}
ASG_r13.close();
ASG_st13.close();
System.out.println(cuatro );
}

}




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, McGraw-
Hill/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 to Oracle7, Oracle Corporation, Oracle
Corporation, 1996.
[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.

You might also like