Está en la página 1de 58

Walter R.

Ojeda Valiente – Visual FoxPro y Firebird SQL

Visual FoxPro y Firebird SQL


Índice
Introducción............................................... 4

PARTE 1: Cliente/Servidor.................................. 5
Servidores de archivos compartidos y Cliente/Servidor... 5
Sistemas Cliente/Servidor............................... 5
Como funciona Cliente/Servidor.......................... 6
¿Cuales son las ventajas de usar Cliente/Servidor?...... 6
Como mostrar los datos al usuario....................... 7
Manera eficiente de enviar/recibir datos del Servidor... 7
Claves primarias........................................ 9
Relaciones.............................................. 9
Concurrencia............................................ 9
Transacciones........................................... 10
Diferencia de terminología.............................. 10

PARTE 2: Firebird.......................................... 11
¿Qué es Firebird?....................................... 11
Tipos de Servidor....................................... 11
Recursos utilizados..................................... 11
Plataformas y versiones para el Servidor................ 12
Plataformas y versiones para el Cliente................. 12
Características principales de Firebird................. 12
Conectividad............................................ 13
Herramientas............................................ 14
Instalando el Servidor.................................. 14
Instalando el Cliente................................... 14
Instalando el driver ODBC............................... 15
Verificando la instalación.............................. 15
El archivo HOST......................................... 16
El archivo ALIASES.CONF................................. 16
El archivo FIREBIRD.CONF................................ 17
El archivo SECURITY2.FDB................................ 17
Como evitar la corrupción de las Bases de Datos......... 17
Como corromper una Base de Datos........................ 17
Dialectos SQL (SQL dialect)............................. 18
Tamaño de la página (page size)......................... 18
Conjunto de caracteres (character set).................. 18
Scripts................................................. 19
El usuario SYSDBA....................................... 20
Agregando nuevos usuarios........................... 21
Borrando usuarios................................... 21
Listando todos los usuarios......................... 21
Cambiando la contraseña de un usuario............... 22
Nombres de los usuarios............................. 22
Contraseñas (passwords) de los usuarios............. 22
Como proteger las Bases de Datos........................ 22

-1-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Privilegios de acceso a una Base de Datos............... 22


Privilegios......................................... 23
Privilegios sobre columnas (campos)................. 23
Ejemplos............................................ 23
Roles................................................... 24
Creando un rol...................................... 24
Eliminando un rol................................... 24
Ejemplos............................................ 24
Comandos del Firebird más utilizados.................... 25
Crear una Base de Datos............................. 25
Conectarse a una Base de Datos...................... 25
Crear un dominio.................................... 25
Ver los dominios existentes......................... 25
Ver la estructura de un dominio..................... 25
Crear una tabla..................................... 26
Borrar una tabla de la Base de Datos................ 26
Ver todas las tablas de una Base de Datos........... 26
Ver la estructura de una tabla...................... 26
Agregarle una clave primaria a una tabla............ 26
Agregarle una columna a una tabla................... 26
Borrar una columna de una tabla..................... 26
Agregarle filas a una tabla......................... 26
Borrar algunas filas de una tabla................... 26
Borrar todas las filas de una tabla................. 26
Modificar columnas de una tabla..................... 26
Consultar las filas de una tabla.................... 27
Consultar las filas cuando se conoce una subcadena.. 27
Consultar solamente los que no están repetidos...... 27
Consultar los datos ordenadamente................... 27
Contar la cantidad de filas de una tabla............ 27
Sumar una columna numérica.......................... 27
Hallar el promedio de una columna numérica.......... 27
Hallar el valor mínimo de una columna numérica...... 27
Hallar el valor máximo de una columna numérica...... 27
Agrupar filas....................................... 27
Ponerles condiciones a las filas agrupadas.......... 27
Relacionar dos tablas............................... 28
Ordenar una tabla................................... 28
El programa ISQL.EXE.................................... 28
El programa GBAK.EXE.................................... 29
Ejemplo 1........................................... 30
Ejemplo 2........................................... 30
El programa NBACKUP.EXE................................. 30
Para hacer un backup completo....................... 31
Para hacer un backup incremental.................... 31
Para restaurar un backup completo................... 31
Para restaurar un backup incremental................ 31
Usando SQL Manager...................................... 32
¿Por qué usar un administrador gráfico?............. 32
La Base de Datos Employee........................... 32
Registrando una Base de Datos....................... 32
¿Qué son los dominios?.............................. 34
¿Cómo se crea un nuevo dominio?..................... 35
¿Qué son las tablas?................................ 36
¿Qué son las vistas?................................ 37
¿Qué son los procedimientos almacenados?............ 37

-2-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

¿Qué son las UDFs?.................................. 38


¿Qué son los desencadenantes?....................... 39
¿Qué son las excepciones?........................... 40
¿Qué son los generadores?........................... 40
¿Para qué se usa SET TERM?.......................... 41
¿Cuándo se usan los : delante del nombre de una
Variable?........................................... 41
Integridad Referencial.................................. 42
La restricción foreign key.......................... 42
Indices................................................. 44
Transacciones........................................... 45
¿Por qué se usan las transacciones?................. 45
Una transacción, muchos pedidos..................... 46
Transacciones y MGA................................. 46
Grabación de datos.................................. 46
Datos desechados.................................... 47
Problemas con transacciones......................... 48
Solución a los problemas............................ 48

PARTE 3: Visual FoxPro y Firebird.......................... 49


¿Qué es DSN?............................................ 49
Para crear un DSN................................... 50
Para conectarse sin DSN............................. 50
Una clase para usar con Bases de Datos SQL.............. 50
Función para conectarse a una BD usando DSN......... 51
Función para conectarse a una BD sin usar DSN....... 52
Función para desconectarse de una (o todas) BD SQL.. 52
Procedimiento para hallar el nombre del driver...... 52
Función para ejecutar comandos SQL.................. 53
Función para verificar si hay una conexión activa... 54
Descargar las clases................................ 54
Programas en Visual FoxPro que usan Firebird............ 54
Ejemplo Nº 1. Usando la instrucción SELECT.......... 54
Ejemplo Nº 2. Una pequeña aplicación administrativa. 56

Conclusión................................................. 58

-3-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Visual FoxPro y Firebird SQL

Introducción
¿Por qué usar Firebird con Visual FoxPro? ¿Por qué Firebird gusta tanto?

Responder a esas preguntas es el objetivo de este documento. Para conseguirlo se


debe empezar desde el principio, es decir desde lo que es Cliente/Servidor, las
características de Firebird y como integrarlo con Visual FoxPro. Para que todo sea más
fácil de entender, este documento se divide en tres partes:

1. Cliente/Servidor. Donde se explican algunos conceptos básicos


2. Firebird. Donde se explican sus principales características
3. Visual FoxPro y Firebird. Donde se explica como usarlos juntos

Visual FoxPro es un lenguaje fantástico, tiene muchísimas capacidades de las cuales


carecen otros lenguajes, se pueden realizar aplicaciones realmente muy buenas
usándolo, es más, resulta prácticamente imposible pensar en una aplicación del tipo
administrativo o comercial que no pueda ser realizada exitosamente y en poco tiempo
con él.

Firebird es un motor de bases de datos SQL muy liviano, muy poderoso, muy fácil
de usar y totalmente gratis tanto para uso privado como comercial. Y se lo puede
integrar perfectamente con Visual Foxpro.

Por lo tanto, es muy lógico que estos dos colosos trabajen juntos. Sin embargo, hasta
este momento no había literatura al respecto, quienes usaron Visual Foxpro con Firebird
están más que conformes con el rendimiento obtenido pero todo lo tuvieron que
aprender desde cero. Cuando finalices de leer este documento te habrás ahorrado un
montón de tiempo.

En este documento se supone que ya has programado en Visual FoxPro y lo conoces


más o menos bien. Está orientado a enseñarte las diferencias que tiene con el Firebird,
las características de este último y como hacerlos trabajar conjuntamente.

-4-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Parte 1. Cliente/Servidor

Servidores de archivos compartidos y Cliente/Servidor


Mediante el uso de servidores de archivos compartidos es como Visual FoxPro,
Clipper, DBase, Paradox, Access y otros lenguajes manejan los datos. En este caso el
servidor de archivos es una característica del Sistema Operativo, no del lenguaje. Es el
Windows quien te da acceso a los archivos que están en una carpeta compartida. Un
programa que se encuentra en otra computadora de la red lee esos archivos en la
memoria de su propia computadora y graba datos en ellos como si estuvieran en su
disco local. El gran problema con este aprovechamiento es la fragilidad de los datos,
que pueden dañarse o corromperse. Es bastante frecuente encontrarse con tablas o
índices dañados. Un corte de la energía eléctrica o un “reset” en cualquiera de las
computadoras de la red puede corromper las tablas o los índices. Además, como las
carpetas son compartidas algunos humanos (por intención o por ignorancia) pueden
borrar o modificar los archivos que en ellas se encuentran.

En cambio en un sistema Cliente/Servidor los clientes (aunque estén localizados


en la misma computadora que el Servidor) nunca tocan los datos directamente, sino que
envían mensajes al Servidor diciéndole lo que quieren hacer. El Servidor procesa esos
mensajes y ejecuta los pedidos usando su propio código y administrando el espacio en
el disco duro, en forma independiente del Sistema Operativo. Un humano que esté
sentado frente a otra computadora de la red y que tuviera la (mala) intención de
modificar una Base de Datos necesitará conocer:
• el nombre de la computadora donde se encuentra la Base de Datos
• el motor utilizado (Firebird, Postgre, MySQL, etc.)
• la carpeta donde se encuentra la Base de Datos
• el nombre de la Base de Datos
• el nombre de un usuario de esa Base de Datos
• la contraseña de ese usuario
• algunos conocimientos de programación para poder conectarse a ella

En un sistema de archivos compartidos, es muy fácil que cualquiera consiga acceso


a la carpeta compartida y a partir de allí ya puede borrar o modificar todas las tablas y
eso es ¡¡¡un peligro potencial muy grave!!!

Sistemas Cliente/Servidor
Un sistema Cliente/Servidor (tal como Firebird) está compuesto por dos
módulos de software diseñados para comunicarse entre sí usando el mismo protocolo de
comunicación. El Cliente envía mensajes al Servidor pidiéndole algo y éste responde al
pedido. Inclusive pueden estar en distintos Sistemas Operativos, por ejemplo el Servidor
en una computadora con Linux y el Cliente en una computadora con Windows. El
protocolo recomendado para usar con Firebird es TCP/IP.

-5-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Como funciona Cliente/Servidor


- Un programa llamado Servidor se instala en una computadora. Su misión es
“escuchar” los mensajes que llegan a un puerto de esa computadora (el puerto
por defecto para Firebird es el 3050) y luego insertar / borrar / modificar / enviar
/ procesar los datos pedidos y enviar la respuesta correspondiente.
- Otro programa, llamado Cliente, se instala en otra computadora (o en la misma).
Su misión es recibir pedidos de la aplicación (Contabilidad, Ventas, Sueldos,
etc.) y enviar esos pedidos al Servidor y recibir los datos que éste le provee para
devolverlos a la aplicación. Pero esos datos son una imagen, una copia, de los
datos que se encuentran en el Servidor.

Este es un concepto que se debe entender muy bien: los datos que recibe el
Cliente (y que luego envía a la aplicación) son una copia de los datos del Servidor.
En cambio en un sistema de archivos compartidos (el utilizado por las tablas .DBF)
son los datos originales, no una copia, los que utilizan las aplicaciones.

En Firebird:

La APLICACIÓN envía un pedido al CLIENTE quien lo envía al SERVIDOR

El SERVIDOR envía la respuesta al CLIENTE quien la envía a la APLICACIÓN

La aplicación puede ser un sistema de Contabilidad, de Facturación, de Sueldos, etc.

APLICACIÓN Pedido Pedido


(Contabilidad,
Facturación, CLIENTE SERVIDOR
Sueldos, Respuesta Respuesta
Tesorería, etc.)

¿Cuales son las ventajas de usar Cliente/Servidor?


- Mayor seguridad. La Base de Datos se encuentra en una computadora a la cual
los usuarios de otras computadoras de la red no pueden acceder. Recuerda que
no hay carpetas compartidas. Además, cada Base de Datos tiene sus propios
mecanismos de seguridad, para usarla hay que especificar el nombre del usuario
y la contraseña. Inclusive a los usuarios se los puede agrupar en “roles” con lo
cual se determina qué pueden hacer y que no.
- Mayor rapidez. Los datos que viajan por la red son pocos, eso incrementa la
velocidad. Aunque los usuarios sean muchos, el tráfico por la red siempre es
mucho menor que usando un sistema de archivos compartidos (tablas .DBF) que
tenga la misma cantidad de usuarios.

-6-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

- Consistencia de los datos. O se graban todos los datos o no se graba ninguno.


En un sistema de archivos compartidos (tablas .DBF) podría darse el siguiente
caso: se graba una fila (registro) en la tabla cabecera, mientras se están grabando
las filas (registros) de la tabla de detalles se interrumpe la energía eléctrica.
¿Cuál es la consecuencia? Que el movimiento (o transacción) está incompleto.
Algo así no puede suceder en Firebird porque los datos: o se graban todos o no
se graba ninguno. Jamás pueden estar incompletos.
- Acceso a través de Internet o redes WAN. Como los datos que viajan son
pocos, hacer aplicaciones que envíen/reciban datos a través de Internet o de una
red WAN es eficiente.
- Independencia del lenguaje. Si ya no quieres programar en Visual FoxPro y
prefieres hacerlo en Java, Visual Basic, Delphi o cualquier otro lenguaje, no hay
problema. Dentro de la Base de Datos nada cambiará.

Como mostrar los datos al usuario


Cuando se utilizan tablas .DBF es común que el programa de ABM tenga los
botones “Primero”, “Anterior”, “Siguiente”, “Ultimo”. Inclusive es común mostrar
muchos datos en una grilla para que el usuario pueda “navegar” a través de ella. En una
aplicación Cliente/Servidor eso es considerado mala práctica. ¿Por qué? porque se
satura la red. En el caso de las grillas se considera que mostrar hasta 200 filas (registros)
en ellas está dentro de lo aceptable, nunca más. Nunca. Si el usuario necesita ver más
filas (registros) entonces debe hacer click en un botón para que se le muestren las
siguientes (o anteriores) 200 filas (registros). Lo normal en las buenas aplicaciones
Cliente/Servidor es que la interfaz sea de búsqueda (el usuario escribe lo que necesita y
sólo eso se le muestra).

Manera eficiente de enviar/recibir datos del Servidor


La filosofía detrás de Cliente/Servidor es que el tráfico en la red sea el mínimo
posible. Ni un byte más de lo estrictamente necesario. Tanto en un sentido (del Cliente
al Servidor) como en el otro (del Servidor al Cliente). Por lo tanto:
• Todo lo que puede procesarse en la aplicación se debe procesar en la
aplicación
• Los procesos que requieren acceso a las tablas deben realizarse en el
Servidor, nunca en la aplicación

Un ejemplo: una aplicación envía una petición de consulta al Servidor para que
devuelva un cursor (un cursor es una tabla temporal) con las ventas realizadas entre dos
fechas. En el Servidor se descubre que una de las fechas estaba vacía. Eso es un error de
concepto. ¿Por qué? porque esa verificación pudo haberse realizado en la aplicación, la
petición de consulta viajó por la red y el mensaje de error también. O sea, hubo un
tráfico innecesario en la red, lo cual la hace más lenta. Cuando de devolver datos se
trata, al Servidor deben llegar siempre los datos totalmente validados, allí no debe
validarse nada, todas las validaciones deben realizarse antes.

-7-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Otro ejemplo: se le muestra al usuario en una grilla la lista de todos los


proveedores de la empresa para que elija a uno de ellos. ¿Cómo se obtuvieron esos
datos? ¿Se los trajo del Servidor? Ese es otro error de concepto, porque si la empresa
tiene 2.000 proveedores, viajaron por la red los datos de los 2.000 proveedores. Lo
correcto es tener en el disco local una tabla con los datos de los proveedores (solamente
códigos y nombres, nada más), cuando el usuario quiere verlos para elegir a uno de ellos
se verifica que la tabla local coincida con la tabla del Servidor ¿cómo? si por ejemplo el
último código de la tabla local es el 1997 entonces se sabe que faltan los tres últimos
proveedores. Se copian los códigos y nombres de esos tres proveedores en la tabla local
y se le muestra al usuario esa tabla. Cuando el usuario elige a uno de esos proveedores
entonces se envía su código al Servidor, para recuperar los demás datos de ese
proveedor (dirección, teléfono, localidad, e-mail, etc.). O sea, por la red viajaron los
datos de los 3 proveedores faltantes (códigos y nombres) más los datos del proveedor
elegido. Y no los datos de los 2.000 que estaban en el Servidor.

Otro ejemplo: se le quiere mostrar al usuario los datos de los proveedores a


quienes se les debe más de 10.000 dólares. ¿Cómo se hace eso? ¿Trayendo todos los
proveedores del Servidor y luego filtrando para que solamente queden a quienes se les
debe más de 10.000 dólares? ese es otro error de concepto. Porque si hay 2.000
proveedores y solamente 50 cumplen con la condición, viajaron por la red los 2.000. Lo
correcto es que en la petición de consulta se especifique la condición, para que el
Servidor envíe los datos de 50 proveedores, no de 2.000.

Por supuesto que si hay que imprimir un informe con los datos de todos los
proveedores entonces los datos de todos los proveedores viajarán por la red. Pero si
solamente se necesitan los datos de algunos proveedores, solamente los datos de ellos
deben viajar por la red.

Siempre hay que tener presente lo siguiente: el tráfico en la red debe ser el
mínimo posible. Por lo tanto traer todos los datos es, en general, un error de concepto.

Estarás empezando a entender la idea detrás de Cliente/Servidor cuando tengas


muy en claro que: por la red debe viajar la menor cantidad de datos posibles.

En el lenguaje SQL la instrucción utilizada para traer datos desde el Servidor


hacia el Cliente se llama SELECT. Por ejemplo, la siguiente instrucción:

SELECT * FROM Paises

Mostrará todos los datos de todos los países. Si realmente se desea ver todos los
datos de todos los países (códigos, nombres, capitales, población, forma de gobierno,
idioma oficial, moneda, etc.) entonce es correcta. Pero si solamente se desean ver
algunos datos (códigos y nombres, por ejemplo) es errónea porque se está haciendo
viajar por la red datos que no se utilizarán.

En síntesis: en general, usar SELECT * es un error. ¿Por qué? porque en general


no se necesitan todas las columnas (campos) de cada fila (registro).

-8-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Para quienes están acostumbrados a usar tablas .DBF esto puede resultar difícil
al principio, ya que allí lo normal es que los registros se lean completamente. Cuando se
accede a un registro se tiene acceso a todos sus campos. Por ejemplo:

USE Paises
SET ORDER TO TAG Codigo
SEEK “595” && Busca el país que tiene código “595”
? Codigo, Nombre, Capital, Poblacion, FormaGob, Idioma, Moneda

No es el mismo caso en SQL, en SQL se pueden especificar cuales son las


columnas (campos) requeridos. Por ejemplo:

SELECT Codigo, Nombre FROM Paises WHERE Codigo = “595”

solamente traerá el Código y el Nombre del país cuyo código es “595”.

O sea, que por la red solamente viajaron el Código y el Nombre de ese país,
nada más. Al no viajar la Capital, Población, etc., todo es más rápido.

Claves primarias
Cada tabla debe tener sí o sí una clave que identifique a cada fila (registro) de
manera inequívoca (o sea que no puede faltar ni estar duplicada). A esa clave se la llama
Clave Primaria (PK = Primary Key). Lo mejor para estos casos es que esa clave la
genere el propio Firebird ¿Por qué preocuparte en generar una clave única si el Firebird
puede realizar ese trabajo por ti? No es lógico.

Para que una columna (campo) pueda ser utilizada como clave primaria, no debe
aceptar valores nulos.

Relaciones
Para relacionar una tabla con otra se utilizan las claves foráneas o extranjeras
(FK = Foreign Key). Ese relacionamiento es persistente, o sea que estará en vigencia
sea cual sea la aplicación que utilice a esa Base de datos.

Concurrencia
En una aplicación multi-usuario puede ocurrir que dos o más de ellos quieran
leer o modificar la misma fila (registro) al mismo tiempo. Eso puede causar problemas a
veces graves. Pero no es el caso con Firebird ya que éste provee un mecanismo por el
cual “los lectores no molestan a los escritores y los escritores no molestan a los
lectores”.

-9-
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Transacciones
Esto puede ser un poco difícil de entender al principio ya que cuando se usan
tablas .DBF los datos quedan grabados después que el usuario hizo click sobre el botón
“Grabar” y la luz del disco duro se apagó. En cambio en Firebird todas las
comunicaciones entre el Cliente y el Servidor ocurren durante transacciones. Inclusive
leer una fila (registro) de una tabla no se puede realizar si antes no se inició una
transacción. Una transacción empieza cuando el Cliente la inicia (a pedido de la
aplicación), a partir de ese momento y hasta que finaliza (también por pedido de la
aplicación al Cliente) puede realizar pedidos al Servidor.

Durante este período se pueden grabar/borrar/modificar filas (registros) y estas


operaciones son grabadas en el disco duro pero no cambian el estado de la Base de
Datos, o sea que aunque ya se grabaron en el disco duro todavía son reversibles.

La transacción finaliza cuando la aplicación le pide al Cliente que las


operaciones sean permanentes (commit) o que sean desechadas si ocurrió algún error
(roll back).

En este último caso se aplica la regla de la atomicidad: si aunque sea un cambio


a la Base de Datos falló entonces todos los cambios son desechados. Por lo tanto: o se
graban todos o ninguno. Esto incluye cualquier cambio realizado por desencadenantes
(triggers) o procedimientos almacenados (stored procedures).

Diferencia de terminología
En las bases de datos relacionales (como Firebird) se le llama “fila” a lo que en
Visual FoxPro estamos acostumbrados a llamar “registro”. Y se le llama “columna” a lo
que le solemos llamar “campo”. Recuerda eso.

fila ----------> registro


columna ----------> campo

Como seguramente estás más acostumbrado a llamar registro y campo a lo que


en SQL se llaman fila y columna es que muchas veces verás esas palabras rodeadas de
paréntesis. Pero trata de acostumbrarte a los nombres “fila” y “columna” porque serán
los que leerás en toda la literatura SQL.

- 10 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Parte 2. Firebird

¿Qué es Firebird?
Es un motor de bases de datos relacionales SQL. Es Open Source (código
abierto) y es totalmente gratis, tanto para uso privado como para uso comercial. Tiene
todas las características y la potencia de un RDBMS (Relational DataBase Management
System o Sistema Administrador de Bases de Datos Relacionales). Puede manejar bases
de datos desde unos pocos Kilobytes hasta muchos Terabytes con muy buen
rendimiento y casi sin mantenimiento.

Tipos de Servidor
Firebird tiene cuatro tipos de Servidor (Classic, SuperServer, SuperClassic,
Embedded), cualquiera de ellos se puede utilizar y sea cual sea el utilizado las Bases de
Datos no cambian. Por lo tanto se puede pasar muy fácilmente de uno a otro. El
recomendado para usar en Windows es el llamado SuperServer y por lo tanto las
siguientes referencias serán a ese. Sin embargo, si la computadora tiene varios
procesadores entonces Classic o SuperClassic serían los preferibles. Para aplicaciones
monousuario o para catálogos en CD o programas similares se puede usar Embedded,
ya que no necesita instalación, incluye el Servidor y el Cliente en un solo archivo .DLL

Recursos utilizados
Una de las ventajas de Firebird es que utiliza muy pocos recursos. Inclusive
puede instalarse en las obsoletas computadoras 486 DX con Windows 95 o con Linux.
Desde luego que no es realista usar esas computadoras en esta época, pero sí es posible.
Por supuesto que cuanto más poderosa sea la computadora será mucho mejor para
todos. El Servidor de Firebird utiliza 2 Mb de memoria y a eso hay que agregarle unos
115 Kb por cada conexión a la Base de Datos. Una regla mnemónica fácil es la
siguiente: 2 Mb + 1 Mb cada 8 conexiones.

En esta época casi cualquier computadora tiene por lo menos 1024 Mb, así que
pueden realizarse muchísimas conexiones sin ningún problema.

El espacio requerido en el disco duro es de alrededor de 14 Mb, aunque un poco


más puede ser necesario para realizar almacenamiento temporario.

- 11 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Plataformas y versiones para el Servidor


• Windows Seven
• Windows Vista
• Windows XP Profesional
• Windows 2008 Server
• Windows 2003 Server
• Windows 2000 Server
• Windows NT 4
• Windows ME
• Windows 98
• Windows 95
• Linux
• FreeBSD
• varios UNIX
• Mac OS X (Darwin)
• Sun Solaris SPARC e Intel
• HP-UX

Pasar de una plataforma a otra no puede ser más fácil. Se hace un backup de la
Base de Datos en una plataforma y se lo restaura en la otra plataforma.

Plataformas y versiones para el Cliente


Las mismas que para el Servidor.

Características principales de Firebird


Firebird es un motor de bases de datos SQL muy completo. Es poderoso, liviano,
y las necesidades de configuración y de administración son mínimas. Fácilmente se lo
puede escalar desde monousuario hasta organizaciones con sucursales por todo el
mundo y miles de computadoras conectadas al mismo tiempo. Un único servidor
Firebird puede manejar múltiples bases de datos independientes, cada una de ellas
conectada a muchos clientes. Además, es verdaderamente Open Source, lo cual significa
que es totalmente gratis tanto para uso privado como para uso comercial.

• A.C.I.D. A=Atomicity (atomicidad), C=Consistency (consistencia), I=Isolation


(aislamiento), D=Durability (durabilidad) es algo que deben tener todos los
motores de bases de datos bien hechos. Firebird cumple perfectamente con ello.
Atomicidad: la operación se realizó o no, jamás puede quedar incompleta.
Consistencia: solamente se ejecutan las operaciones que no van a romper las
reglas y las directrices de la base de datos. Aislamiento: una operación no puede
afectar a otras. Esto asegura que la realización de dos transacciones sobre la
misma información sean independientes y no generen ningún tipo de error.
Durabilidad: una vez realizada la operación ésta persistirá y no se podrá
deshacer aunque falle el sistema.

- 12 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

• MGA. Multi Generational Architecture. (en castellano: Arquitectura de


múltiples generaciones). El Firebird maneja varias versiones de la misma fila
(registro) al mismo tiempo para que cada transacción tenga su propia versión,
por lo tanto: “los lectores no molestan a los escritores y los escritores no
molestan a los lectores”.
• Procedimientos almacenados. Estas son rutinas que pertenecen a la Base de
Datos y que se procesan en el Servidor. Un caso especial son los procedimientos
almacenados seleccionables los cuales pueden realizar sus tareas para cada fila
(registro) de una tabla y luego ser usados como una vista o una tabla virtual en el
lado del cliente. Muy útiles para informes.
• Desencadenantes. Cada tabla puede tener todos los desencadenantes (triggers)
que se desee, los cuales son lanzados automáticamente antes o después de
insertar, borrar o modificar una fila (registro). Pueden ser usados para poner
valores por defecto, asegurar la integridad de los datos, etc.
• Generadores. Usándolos fácilmente se pueden tener columnas (campos) que se
auto incrementan y claves únicas para ser usadas como PK (Primary Key).
• Bases de Datos de sólo lectura. Se las puede usar para programas demo o
catálogos, presentaciones, etc.
• Control completo de las transacciones. Una aplicación puede tener múltiples
transacciones manteniendo el total control sobre cada una de ellas.
• Backups en línea. Los backups de una Base de Datos pueden realizarse en
cualquier momento, aunque haya muchos usuarios usando sus tablas, vistas,
procedimientos almacenados, desencadenantes, etc. Esto permite que las
aplicaciones funcionen 24/7 (durante 24 horas, los 7 días de la semana).
• Backups incrementales. El backup se puede hacer solamente sobre los últimos
cambios, ahorrando así mucho tiempo y espacio en disco.
• Shadows. Todo lo que se escribe en una Base de Datos puede al mismo tiempo
escribirse en otra Base de Datos, de tal manera que si la primera tiene algún
problema (disco duro dañado, por ejemplo) pueden recuperarse el 100% de los
datos.
• Replicación. No es una característica nativa pero hay muchas herramientas de
terceros que permiten hacerla (algunas son gratis).
• Funciones externas. Bibliotecas de funciones externas (UDFs) pueden ser
escritas en cualquier lenguaje que genere DLLs y luego ser usadas por el
Firebird como si fueran funciones internas.
• Integridad referencial en cascada. Permite que al modificar un código de una
tabla padre se modifiquen automáticamente los códigos de todas las tablas hijas.
• Conjuntos de caracteres. Firebird implementa casi todos los lenguajes
humanos (español, inglés, portugués, italiano, alemán, polaco, ruso, etc.)

Conectividad
Firebird acepta los siguientes métodos: ODBC, JDBC (JayBird), PHP driver,
Perl, Python, OLEDB driver, dbExpress, proveedores de datos .Net, paquetes de
componentes nativos para C/C++/Delphi, llamadas directas a la API.

Para usarlo desde Visual FoxPro el primero de ellos (ODBC) da excelentes resultados.

- 13 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Herramientas
Hay muchos programas que pueden usarse con Firebird, incluyendo
administradores gráficos, replicadores, auditorías, generadores de datos, analizadores de
estadísticas del Servidor, etc.

Es más que aconsejable utilizarlos, porque se ahorra muchísimo tiempo al


hacerlo.

Entre los administradores gráficos más conocidos se cuentan los siguientes:


• FlameRobin (gratis)
• SQL Manager for InterBase and Firebird (la versión Lite es gratis)
• IBExpert (tiene una versión personal gratis)
• DB Workbench (la versión Lite es gratis)
• Firebird Development Studio (30 días gratis)

Instalando el Servidor
Hay que elegir cual tipo de Servidor se desea. Lo aconsejable es instalarlo como
un servicio del Windows, para que se inicie junto con el Windows. El mismo programa
que se utiliza para instalar el Servidor se usará para instalar al Cliente. Siempre es
aconsejable instalar la última versión estable. Se lo puede descargar de:

http://www.firebirdsql.org/index.php?op=files&id=engine

El Servidor se debe instalar en una sola computadora de la red, en aquella donde


se encontrarán todas las Bases de Datos.

Instalando el Cliente
Aunque se lo puede instalar manualmente, lo mejor es hacerlo mediante el
programa de instalación.

El Cliente se debe instalar en cada computadora de la red. Se lo puede instalar


CON las herramientas administrativas o SIN las herramientas administrativas. Lo mejor
es instalarlo SIN esas herramientas porque los usuarios comunes no deben tener acceso
a ellas.

Pero en la computadora que se usará para desarrollar aplicaciones hay que


instalar el Cliente CON las herramientas administrativas.

También es posible instalar en la misma computadora el Servidor y el Cliente.

- 14 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Instalando el driver ODBC


Para poder conectarse a una Base de Datos Firebird desde Visual FoxPro se
necesita escribir un “string de conexión” el cual necesitará de un driver ODBC (más
sobre esto en el siguiente capítulo).

Puedes descargar el driver ODBC que corresponde a tu computadora desde:

http://www.firebirdsql.org/index.php?op=files&id=odbc

Verificando la instalación
Verificando la conexión a la computadora donde se encuentra el Servidor

Para verificar que la red funciona correctamente y que la computadora donde se


encuentra el Cliente puede comunicarse con la computadora donde se encuentra el
Servidor se debe abrir una ventana de comandos en la computadora del Cliente y luego
escribir lo siguiente:

ping 192.21.7.15 -1 65500 - t

sustituyendo esa dirección IP por la que corresponda a la computadora donde se


encuentra el Servidor. Esto se llama “ping con carga máxima” y asegura que la
comunicación puede realizarse exitosamente.

Verificando que el Servidor se esté ejecutando

En la computadora donde se instaló el Servidor:


Inicio | Panel de Control | Herramientas administrativas | Servicios

Si se está ejecutando, se verá una pantalla similar a la siguiente:

- 15 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

El archivo HOST
Una manera de ocultar la dirección IP del Servidor es mediante el uso del
archivo HOST. Este es un archivo que se encuentra en la carpeta C:\WINDOWS\ y que
sirve para darle un nombre a las direcciones IP. Luego, cuando sea necesario, se puede
usar el nombre y no la dirección IP.

Si en la carpeta C:\WINDOWS\ no encuentras un archivo llamado HOST, debe


haber un archivo llamado HOSTS.SAM, renómbralo como HOST.

Ejemplos:

192.168.0.11 MiServidor # Servidor de Firebird en la LAN


65.215.221.149 apress.com # Servidor en una red WAN
127.0.0.1 localhost # Servidor local

El archivo HOST puede ser modificado con el NOTEPAD (Bloc de notas) o


cualquier otro editor de texto plano.

El archivo ALIASES.CONF
Este es un archivo que se encuentra en la carpeta raíz del Firebird y no debe ser
movido de allí.

Permite darle un nombre abreviado a las bases de datos y usar ese nombre
abreviado en las conexiones. Eso aumenta la seguridad, ya que los curiosos no pueden
saber en que carpeta se encuentra la Base de Datos ni cual es el nombre de ella.

Ejemplo:

Conta = C:\SISTEMAS\SQL_CONTA\CONTA.FDB

Conexión:

Para conectarse a la Base de Datos se podría escribir:

10.12.13.2:C:\SISTEMAS\SQL_CONTA\CONTA.FDB

o:

10.12.13.2:Conta

o:

MiServidor:Conta

Esta última es la preferible porque los curiosos no podrán saber ni la IP del


Servidor ni la carpeta ni el nombre real de la Base de Datos.

- 16 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

El archivo FIREBIRD.CONF
Este es un archivo que permite configurar al Firebird, se encuentra en su carpeta
raíz y sus valores pueden ser cambiados, de acuerdo a la necesidad.

En general, los valores que tiene son los más adecuados para la mayoría de las
situaciones, pero si no es así, cambiarlos es muy fácil. Se lo abre con cualquier editor de
texto plano (el NOTEPAD, por ejemplo) se cambia lo que se desea y se lo graba.

El archivo SECURITY2.FDB
Este es el archivo donde el Firebird guarda los datos de cada usuario (nombres y
contraseñas), está localizado en la misma carpeta del Firebird y no debe ser movido de
allí.

Como evitar la corrupción de las Bases de Datos


Aunque las Bases de Datos Firebird muy raramente tienen problemas, hay
algunas medidas que pueden tomarse para disminuir aún más la probabilidad de que
algo malo les pase:

• Chequear que la computadora tenga UPS (energía ininterrumpida)


• Chequear que la memoria de la computadora esté OK, (para ello puede usarse el
programa MTINST.EXE)
• Chequear que la Base de Datos tenga Forced Writes en ON
• Chequear que haya suficiente espacio libre en el disco, tanto para la Base de
Datos como para los archivos temporales

Las Bases de Datos Firebird no se corrompen si se interrumpe la energía eléctrica.

Como corromper una Base de Datos


Esta es una lista de las cosas que no debes hacer si quieres mantener a tu Base de
Datos en buen estado.

• Modificar las tablas de los metadatos. Estas son las tablas internas que el
Firebird crea dentro de cada Base de Datos. No las toques. Te lo repito: no las
toques.
• Deshabilitar “Forced Writes”. Por defecto, el Firebird graba los datos en el
disco apenas se hace el commit de ellos. No cambies esa configuración.
• Restaurando un backup en una Base de Datos que se está ejecutando. Si los
usuarios están usando una Base de Datos, no debes restaurar sobre ella.
• Permitir a los usuarios que se conecten durante una restauración. Mientras
se está restaurando una Base de Datos, nadie debe estar conectado.

- 17 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Dialectos SQL (SQL dialect)


Firebird soporta tres dialectos SQL, nombrados respectivamente 1, 2 y 3. El
último es el que debe usarse en todas las aplicaciones nuevas, los anteriores existen para
compatibilidad con versiones antiguas. El dialecto 3 es el que se usa por defecto pero si
quieres puedes escribir:

SET SQL DIALECT 3;

Hay programadores a quienes les gusta especificar el dialecto que emplean,


aunque no es necesario ya que si no lo especificas se usará el 3 (que es el más nuevo).

Tamaño de la página (page size)


Este es también un atributo opcional, se expresa en bytes. Su valor por defecto
es 4096. Los valores que puede tomar son: 1024, 2048, 4096, 8192, 16384 (habrás
notado que son todas potencias de 2, empezando con 2 ^ 10).

Si escribes cualquier otro número, el Firebird tomará el anterior en estos rangos.


Por ejemplo, si escribes:
2000 toma 1024
3000 toma 2048
3500 toma 2048
8000 toma 4096

Puedes usar cualquier tamaño de página (PAGE_SIZE) que desees, si no eliges


uno entonces se usará 4096. ¿Para qué sirve el tamaño de página? Para decirle al
Firebird cuantos bytes debe grabar en cada bloque. Si eliges un tamaño que no es el más
adecuado para tu aplicación, la única consecuencia será que los accesos a tu Base de
Datos no serán tan rápidos como podrían serlo. Si te parece que los accesos están lentos
entonces puedes hacer un backup de tu Base de Datos y luego restaurarla con un nuevo
tamaño de página, hasta encontrar el que resulte mejor.

Conjunto de caracteres (character set)


Los caracteres que puede reconocer el Firebird se encuentran en los así llamados
“character set”. Hay varios de ellos, debes usarlos para decirle el idioma que emplearás:
ASCII Inglés
BIG_5 Chino, Coreano, Vietnamita
CYRL Ruso
ISO8859_1 Castellano, Francés, Inglés, Italiano, Portugués, etc.
...

Hay muchos más, pero con estos ya tienes la idea. Lo importante a recordar es
que para los idiomas latinos (el castellano entre ellos) debes elegir: ISO8859_1

- 18 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Scripts
Además de crear las Bases de Datos, Dominios, Tablas, Índices, etc.
manualmente, también se tiene la posibilidad de hacer esas tareas automáticamente a
través de un script.

Un script es un archivo de texto plano usualmente con la extensión .SQL en el


cual se colocan los comandos que se desean ejecutar. Son muy útiles para reconstruir la
estructura de una Base de Datos o de una Tabla en la misma o en otra computadora.

Ejemplo:
CREATE TABLE Paises (
Codigo SmallInt NOT NULL,
Nombre VarChar(25) NOT NULL,
Capital VarChar(25),
Poblacion BigInt,

PRIMARY KEY (Codigo)


);

INSERT INTO Paises VALUES(595, ‘Paraguay’, ‘Asunción’, 6500000);


INSERT INTO Paises VALUES(1, ‘Estados Unidos’, ‘Washington’, 310000000);
INSERT INTO Paises VALUES(86, ‘China’, ‘Beijing’, 1250000000);

Como se ve en este ejemplo, se ha creado una tabla y también se le han agregado


datos. También se podrían haber creado una Base de Datos, dominios, otras tablas,
índices, etc.

Los scripts a menudo se utilizan cuando se instala una nueva aplicación (Ventas,
Facturación, Contabilidad, Sueldos, etc.) en lo de un cliente. No hace falta copiar una
Base de Datos vacía en su computadora, con copiar y ejecutar los scripts es más que
suficiente, se ahorra mucho espacio en disco, pero además los scripts cumplen con otra
tarea que es muy importante: documentación.

Mirando los scripts se puede conocer las características y las estructuras de una
Base de Datos y de cada uno de sus componentes (Dominios, Tablas, Índices, etc.)

Si se debe modificar algo, se modifica el script y ese cambio puede quedar


comentado.

Para comentar algo hay dos formas:


• Usando el par /* mi comentario va aquí */
• Usando -- este es mi comentario

Por ejemplo:
CREATE TABLE Usuarios (
Nombre VarChar(20), /* este es el nombre del usuario, si es necesario este
comentario puede ocupar varias líneas */
Contrasena VarChar(12) -- esta es la contraseña del usuario, sólo en una línea
);

- 19 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

El usuario SYSDBA
En Firebird hay un usuario que tiene todos los derechos, puede hacer todo lo que
quiera con cualquier Base de Datos. El nombre de ese usuario es SYSDBA. Cuando se
instala el Firebird la contraseña de ese usuario es masterkey (en realidad, masterke,
solamente se consideran los primeros ocho caracteres).

Lo primero que debes hacer apenas has instalado el módulo Servidor del
Firebird es cambiar esa contraseña ¿por qué? porque la contraseña masterkey la conocen
todos en todo el mundo y si tu computadora está conectada a Internet y llega a ser
hackeada o si dentro de tu organización hay un enemigo interno, será la primera
contraseña que probarán.

Para cambiar la contraseña del usuario SYSDBA debes abrir una ventana de
comandos, ingresar a la carpeta \BIN del Firebird y ejecutar el programa GSEC.EXE,
como se ve en la siguiente pantalla:

¿Qué se hizo? primero, ejecutar el programa gsec.exe con el usuario SYSDBA y


con la contraseña masterkey. Luego, se cambió la contraseña de SYSDBA, la nueva
contraseña es ahora secreto. Por supuesto que tú debes elegir otra contraseña, este es
sólo un ejemplo.

Para salir del programa GSEC.EXE y regresar a la ventana de comandos se debe


escribir el comando quit.

A partir de este momento la contraseña del usuario SYSDBA es secreto, la


contraseña anterior (masterkey) ya no funciona. Eso significa que no debes olvidar tu
nueva contraseña porque si la olvidas perderás tus derechos como usuario principal.

IMPORTANTE: Como el usuario SYSDBA es muy poderoso y tiene un poder


destructivo muy grande, no debería ser usado para crear bases de datos ni para llenar las
tablas con datos. En lugar de eso, debes crear usuarios comunes para que realicen esas
tareas.

Debes ingresar como usuario SYSDBA solamente para agregar, cambiar o


borrar usuarios, realizar backups, restauraciones y otras tareas que solamente él puede
hacer. Las tareas de todos los días, deben hacerlas los demás usuarios.

Recuérdalo muy bien porque este es un concepto muy importante: las tareas
diarias no debe hacerlas el usuario SYSDBA.

- 20 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Agregando nuevos usuarios


El usuario SYSDBA puede agregar nuevos usuarios, como se ve en la siguiente
pantalla:

Aquí se agregaron tres nuevos usuarios. Walter, con contraseña 123456, Silvia,
con contraseña hermosa y Erika con contraseña japonesa.

Borrando usuarios
El usuario SYSDBA también puede borrar usuarios, como se ve en la siguiente
pantalla:

Donde se ha borrado al usuario Erika utilizando para ello el comando del.

Listando todos los usuarios

Para ver los nombres de todos los usuarios se utiliza el comando display.

- 21 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Cambiando la contraseña de un usuario

Aquí se cambió la contraseña de Silvia, su nueva contraseña es muylinda, la


anterior ya no funciona.

Nombres de los usuarios


Los nombres de los usuarios pueden escribirse en minúsculas, mayúsculas o
cualquier combinación. Por ejemplo las palabras: Silvia, silvia y SILVIA se refieren
todas al mismo usuario.

Contraseñas (passwords) de los usuarios


A diferencia de los nombres, las contraseñas (passwords) de los usuarios deben
ser escritos siempre exactamente igual. Por ejemplo: MuyLinda, Muylinda, muylinda,
MUYLINDA son todas contraseñas diferentes y si escribes la que no corresponde, no
podrás acceder a la Base de Datos.

Como proteger las Bases de Datos


Si alguien tiene acceso a la computadora donde se encuentra una Base de Datos
puede copiarla, instalarla en otra computadora donde tenga acceso como usuario
SYSDBA y ver o robar todos los datos que quiera. No solamente puede copiarla,
también puede dañarla físicamente o destruirla completamente.

La regla a seguir es la siguiente: Solamente los procesos del Servidor deben


tener acceso a las Bases de Datos, los usuarios no necesitan y no deben tener acceso a
ellas, ni siquiera read-only (sólo lectura).

Privilegios de acceso a una Base de Datos


El creador de una Base de Datos y el usuario SYSDBA tienen acceso total y
completo sobre ella desde el mismo momento en que fue creada, los demás usuarios
nada pueden hacer con ella ... hasta que se les otorgan privilegios (o derechos). Recién a
partir de ese momento podrán usar la Base de Datos. Mientras no se les hayan otorgado
privilegios (o derechos) nada podrán hacer, ni siquiera consultarla.

- 22 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

IMPORTANTE: El usuario SYSDBA puede otorgar o quitar derechos a todos


los usuarios de la Base de Datos excepto a su creador. El creador siempre tiene todos los
derechos, ni siquiera SYSDBA puede quitárselos. De la misma manera, el creador
tampoco puede quitarle derechos a SYSDBA.

El comando que se usa para otorgar privilegios a los usuarios se llama GRANT.
Su sintaxis es la siguiente:

GRANT <privilegio> ON <objeto> TO <usuario>;

Para quitarles derechos a los usuarios se usa REVOKE. Su sintaxis es la


siguiente:

REVOKE <privilegio> ON <objeto> FROM <usuario>;

Privilegios

Los privilegios que pueden ser otorgados a los usuarios (y revocados) son los
siguientes:

Nombre del privilegio Lo que puede hacer .


SELECT Leer filas (registros)
INSERT Insertar filas (registros)
UPDATE Modificar el contenido de las filas (registros)
DELETE Borrar filas (registros)
REFERENCES Relacionar una clave primaria con una clave secundaria
ALL Select, Insert, Update, Delete, References
EXECUTE Ejecutar un Procedimiento Almacenado o llamarlo
ROLE Adquirir todos los privilegios del rol

Privilegios sobre columnas (campos)

El privilegio UPDATE permite modificar el contenido de todas las columnas


(campos) de una fila (registro). Pero a veces se necesita que el usuario solamente pueda
modificar algunas columnas, no todas. Para ello, a continuación de UPDATE se debe
escribir entre paréntesis los nombres de las columnas que podrá modificar.

Ejemplos:
GRANT SELECT, UPDATE, INSERT, DELETE ON PRODUCTOS TO SILVIA;

GRANT SELECT ON PRODUCTOS TO MIRTHA;

REVOKE DELETE ON PRODUCTOS TO SILVIA;

GRANT UPDATE (PRECIO_VENTA1, PRECIO_VENTA2) ON PRODUCTOS TO SILVIA;

- 23 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Roles
Los roles permiten agrupar a los usuarios para que todos quienes compartan un
rol tengan los mismos privilegios. Todos los usuarios que tienen el mismo rol disponen
de exactamente los mismos derechos. Un usuario puede tener varios roles pero
solamente uno de ellos estará activo en cada momento.

Por ejemplo, se puede tener un rol para Ventas, otro para Contabilidad, otro para
Recursos Humanos, etc. Si se crea un rol llamado “Ventas” que solamente permite ver
cantidades en stock, precios de venta y realizar ventas, los usuarios que usen ese rol no
podrán ver los Balances ni los datos de los empleados.

Los roles son específicos de cada Base de Datos, un rol creado para una Base de
Datos no funcionará en otra.

La implementación de roles tiene los siguientes pasos:


1. Crear un rol (usando CREATE ROLE)
2. Asignar privilegios al rol (usando GRANT privilegios TO NombreRol)
3. Asignar el rol a los usuarios (usando GRANT NombreRol TO Usuario)
4. Especificar el rol, además del nombre del usuario, al conectarse a una BD

Creando un rol

La sintaxis para crear un rol es muy simple:


CREATE ROLE <NombreRol>

El creador de la Base de Datos y el usuario SYSDBA pueden crear los roles y


otorgar los privilegios y asignarlos a los usuarios.

Eliminando un rol

Si ya no se necesita un rol entonces se lo puede eliminar, la sintaxis es:


DROP ROLE <NombreRol>

Ejemplos:
/* Se crea el rol R_PRODUCTOS, que tiene todos los privilegios sobre la tabla PRODUCTOS y se le asigna a Silvia */

CREATE ROLE R_PRODUCTOS;

GRANT ALL ON PRODUCTOS TO R_PRODUCTOS;

GRANT R_PRODUCTOS TO SILVIA;

/* Se crea el rol R_VENDEDORES, que solamente puede consultar la tabla VENDEDORES (o sea que no puede insertar
ni borrar ni modificar datos) y se le asigna a Silvia */

CREATE ROLE R_VENDEDORES;

GRANT SELECT ON VENDEDORES TO R_VENDEDORES;

GRANT R_VENDEDORES TO SILVIA;

- 24 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Como puede verse en la siguiente imagen, se creó el rol R_VENDEDORES, el


cual solamente permite consultar a la tabla VENDEDORES pero no permite que se
inserten, borren o modifiquen datos de ella.

El rol R_VENDEDORES se le otorgó a SILVIA, por lo tanto ella puede


consultar pero nada más, solamente puede hacer eso.

Cuando intentó agregar una fila a la tabla VENDEDORES el Firebird se lo


impidió, mostrando un código de error (-551), el cual significa: “no tienes permiso para
insertar/escribir en la tabla”.

Comandos del Firebird más utilizados


El Firebird tiene muchos comandos, la mayoría de ellos con varias cláusulas y
en cada versión se van agregando nuevos. Sin embargo hay algunos que son mucho más
utilizados que los demás, esos son los que se listan a continuación.

Crear una Base de Datos


CREATE DATABASE "C:\EJEMPLO.FDB" USER "WALTER" PASSWORD "123456";

Conectarse a una Base de Datos


CONNECT "C:\EJEMPLO.FDB" USER "SILVIA" PASSWORD "muylinda";

Crear un dominio
CREATE DOMAIN NumeroEntero INTEGER;
CREATE DOMAIN NombrePersona VARCHAR(30);

Ver los dominios existentes


SHOW DOMAINS;

Ver la estructura de un dominio


SHOW DOMAIN NumeroEntero;
SHOW DOMAIN NombrePersona;

- 25 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Crear una tabla


CREATE TABLE Personas(Codigo NumeroEntero,
Nombres NombrePersona,
Apellidos NombrePersona,
Sueldo Integer);

CREATE TABLE Amigos (Codigo Integer NOT NULL,


Nombres VarChar(15),
Apellidos VarChar(15));

Borrar una tabla de la Base de Datos


DROP TABLE Personas;

Ver todas las tablas de una Base de Datos


SHOW TABLES;

Ver la estructura de una tabla


SHOW TABLE Personas;
SHOW TABLE Amigos;

Agregarle una clave primaria a una tabla


ALTER TABLE Amigos ADD PRIMARY KEY (Codigo); la columna clave debe estar entre paréntesis

Agregarle una columna a una tabla


ALTER TABLE Personas ADD Telefono VarChar(15);
ALTER TABLE Personas ADD Clave Integer NOT NULL;

Borrar una columna de una tabla


ALTER TABLE Personas DROP Codigo;

Agregarle filas a una tabla


INSERT INTO Personas (1, "JUAN", "PEREZ");
INSERT INTO Personas (Codigo, Nombres, Apellidos) VALUES (2, "MARIA", "BENITEZ");
INSERT INTO Personas (Codigo, Nombres) VALUES (3, "CLAUDIA");

Borrar algunas filas de una tabla


DELETE FROM Personas WHERE Codigo = 25;
DELETE FROM Personas WHERE Codigo >= 12 AND Codigo <= 18;
DELETE FROM Personas WHERE Nombres = ‘MARIA’;

Borrar todas las filas de una tabla


DELETE FROM Personas;

Modificar columnas de una tabla


UPDATE PERSONAS SET Apellidos = 'ARRUA' WHERE Nombres = 'CLAUDIA';

- 26 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Consultar las filas de una tabla


SELECT * FROM Personas;
SELECT Nombres, Apellidos FROM Personas;
SELECT Nombres FROM Personas WHERE Apellidos = "BENITEZ";
SELECT * FROM Personas WHERE Nombres = "JUAN" OR Apellidos = "BENITEZ";
SELECT * FROM Personas WHERE Sueldo BETWEEN '2000' AND '5000';

Consultar las filas cuando se conoce una subcadena


SELECT * FROM Personas WHERE Nombres LIKE '%ANA%'; mostrará todos los nombres que tengan a ANA
en alguna parte (ANA, ANALIA, SUSANA, LUCIANA, etc.)
A_Z todas las filas que empiezan con A, tienen cualquier caracter en el medio y finalizan con Z
ABC% todas las filas que empiezan con ABC y continúan con cualquier caracter
%XYZ todas las filas que finalizan con XYZ
%AN% todas las filas que tienen AN en cualquier lugar
_AN% todas las filas que empiezan con cualquier carácter, continúan con AN y finalizan con cualquier carácter

Consultar solamente los que no están repetidos


SELECT DISTINCT Nombres FROM Personas;
SELECT DISTINCT Nombres, Apellidos FROM Personas;

Consultar los datos ordenadamente


SELECT * FROM Personas ORDER BY Nombres;
SELECT * FROM Personas ORDER BY Apellidos, Nombres;

Contar la cantidad de filas de una tabla


SELECT COUNT (*) FROM Personas;

Sumar una columna numérica


SELECT SUM(Sueldo) FROM Personas;

Hallar el promedio de una columna numérica


SELECT AVG(Sueldo) FROM Personas;
SELECT AVG(Sueldo) FROM Personas WHERE Apellidos = "BENITEZ";

Hallar el valor mínimo de una columna numérica


SELECT MIN(Sueldo) FROM Personas;

Hallar el valor máximo de una columna numérica


SELECT MAX(Sueldo) FROM Personas;

Agrupar filas
SELECT Codigo, Apellidos, Nombres FROM Personas GROUP BY Apellidos, Nombres, Codigo;
todas las columnas que están antes del GROUP BY deben estar también después, aunque pueden estar en distinto orden

Ponerles condiciones a las filas agrupadas


SELECT Codigo, Apellidos, Nombres FROM Personas GROUP BY Apellidos, Nombres, Codigo HAVING Nombres =
"JUAN";

- 27 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Relacionar dos tablas


SELECT Personas.Codigo, Personas.Apellidos, Paises.Nombres FROM Personas, Paises WHERE Personas.CodigoPais
= Paises.Codigo;

Ordenar una tabla


SELECT Personas.Codigo, Personas.Apellidos, Paises.Nombres FROM Personas, Paises ORDER BY Paises.Nombres;

El programa ISQL.EXE
Interactive SQL es un programa de línea de comandos que incorpora
herramientas y técnicas para mantener objetos de las bases de datos, administrar
transacciones, procesar scripts.

La ventaja que tiene es que existe en todas las instalaciones del Servidor de
Firebird, la desventaja es que hay que escribir los comandos. Como hay muchos
programas que permiten realizar esas tareas gráficamente, en general no se lo usa, pero
siempre es bueno conocerlo, alguna vez puede ser de utilidad. Por eso es recomendable
que practiques un poco con él, para saber usarlo cuando lo necesites.

Con ISQL se pueden crear bases de datos, dominios, tablas, índices, y en general
realizar todas las operaciones usuales.

Se encuentra en la carpeta \BIN del Firebird.

En la imagen de arriba se muestra como conectarse a una base de datos ya


existente. El comando a utilizar es CONNECT.

En la imagen de arriba se muestran todas las tablas que pertenecen a la base de


datos llamada EMPLOYEE.FDB.

- 28 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

En la imagen de arriba se ve la estructura de la tabla llamada COUNTRY.

En la imagen de arriba se ven todas las filas y las columnas country y currency
de la tabla COUNTRY.

El programa GBAK.EXE
Es un programa utilitario que se encuentra en la carpeta \BIN del Firebird, su
misión es realizar copias de seguridad (backups) de las bases de datos y restaurarlas
cuando sea necesario. También detecta corrupción de datos, libera el espacio en disco
ocupado por las filas borradas (un equivalente al comando PACK del VFP), resuelve las
transacciones que no estaban completas, permite partir una Base de Datos en varios
archivos (muy útil cuando ya es demasiado grande), también se lo usa para restaurar el
backup en otra plataforma (de Windows a Linux, por ejemplo).

IMPORTANTE: Nunca debes usar programas como WinZip o WinRar para


comprimir tu base de datos si el Firebird está en ejecución.

IMPORTANTE: El archivo de backup generado por el programa GBAK no


puede ser usado directamente porque el Servidor no lo reconocerá, antes de ser usado
debe ser restaurado con una versión de GBAK igual o posterior a la usada para crearlo.

IMPORTANTE: Los usuarios pueden continuar trabajando normalmente


mientras se realiza el backup, pero los datos que se graban son los que se encontraban
en la base de datos en el momento que GBAK se inició. Todos los cambios que los
usuarios hagan después no serán grabados en el archivo de backup.

- 29 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

PRECAUCIÓN: El hecho de que un backup se haya realizado exitosamente no


implica que se podrá recuperar sin problemas cuando se lo necesite. Siempre debes
probar a restaurar tu backup inmediatamente después de realizarlo, para asegurarte que
todo está bien.

El uso del programa GBAK está restringido al usuario SYSDBA y al usuario


quien creó la base de datos.

PRECAUCIÓN: Cualquiera puede robar una base de datos Firebird restaurando


un archivo de backup en una computadora donde conoce la contraseña del usuario
SYSDBA. Por eso es importantísimo asegurar que los archivos de backup se encuentren
en un lugar seguro.

Ejemplo 1:

Aquí el usuario SYSDBA cuya contraseña es secreto hizo un backup del archivo
AGENDA.FDB. El nombre del archivo generado es AGENDA27112010.

Ejemplo 2:

Aquí el usuario SYSDBA cuya contraseña es secreto restauró el archivo de


backup llamado AGENDA27112010 en una base de datos llamada AGENDA.FDB. Es
importante recordar que AGENDA27112010 no es reconocida como una Base de Datos
por el Firebird, debe ser restaurada para poder ser utilizada como tal.

El programa NBACKUP.EXE
Este programa ofrece posibilidades que no tiene GBAK.EXE pero no lo
reemplaza, sino que lo complementa.

Puede hacer el backup y la restauración completos o incrementales. Este último


sólo tiene los cambios ocurridos desde el último backup.

Puede bloquear la base de datos para que el backup se haga con otro programa.
En este caso no realiza el backup sino que establece las condiciones para que pueda ser
realizado.

- 30 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Ambos modos pueden hacerse sobre una Base de Datos activa, sin molestar a los
usuarios. El backup realizado siempre reflejará el estado al principio de la operación.

Para hacer un backup completo

La sintaxis de este comando es:


nbackup [-U <usuario> -P <contraseña>] -B 0 <Base de Datos> [<Nuevo Nombre>]

Como se ve en la imagen de arriba, el programa nbackup.exe creó un archivo de


backup con la extensión .nbk

Para hacer un backup incremental

Para ahorrar tiempo y espacio en disco se puede hacer un backup incremental, es


decir agregarle al backup anterior solamente los cambios realizados desde ese momento.
Para ello, a continuación del parámetro –B se escribe un número mayor que cero (el
número cero significa backup completo), como se ve en la siguiente imagen:

Si en el siguiente backup se utiliza:


- B 0, el backup será completo
- B 1, el backup será incremental desde el último backup de nivel 0
- B 2, el backup será incremental desde el último backup de nivel 1

Para restaurar un backup completo

Se debe usar el parámetro –R, como en la siguiente imagen:

Para restaurar un backup incremental

Se debe especificar toda la cadena de los archivos de backup, desde el nivel 0


hasta el nivel que se desea restaurar. Esta es la sintaxis:
nbackup [-U <usuario> -P <contraseña>]
-R <Base de Datos> [<backup0> [<backup1> [...] ] ]

- 31 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Usando SQL Manager


Hay varios administradores gráficos muy buenos, FlameRobin, SQL Manager,
IB Expert, DB Workbench, etc. cualquiera de ellos puede ser utilizado. Por una cuestión
de costumbre del autor de este documento, SQL Manager será el que se usará en las
siguientes páginas.

Se lo puede descargar desde:

http://www.sqlmanager.net/en/products/ibfb/manager/download

Hay varias opciones, si se desea descargar una que es gratis elegir la que dice
“freeware”.

¿Por qué usar un administrador gráfico?


Porque facilita muchísimo el trabajo, se ahorra muchísimo tiempo y se tienen las
ideas más claras.

La Base de Datos Employee


Cuando se instala el Firebird, dentro de su misma carpeta se copia una Base de
Datos con el nombre Employee (empleado), para que los nuevos usuarios de Firebird
puedan hacer pruebas con ella. Como está disponible en todas las instalaciones, será la
utilizada en los siguientes ejemplos:

Registrando una Base de Datos


Después de ingresar al SQL Manager lo primero que se debe hacer es registrar
la Base de Datos con la cual se desea trabajar. Eso es equivalente a abrirla, se necesita
hacerlo para poder usarla.

- 32 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Una vez que la Base de Datos esté registrada, se verá una pantalla, similar a la
siguiente:

Haciendo doble click sobre EMPLOYEE se verán todos sus componentes, como
a continuación se muestra:

- 33 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

en el panel de la izquierda pueden verse los componentes de las Bases de Datos


(dominios, tablas, vistas, procedimientos almacenados, funciones externas del usuario,
desencadenantes, etc.)

Haciendo click sobre el signo + que se encuentra a la izquierda de cada categoría


se pueden ver todos sus elementos, como se muestra a continuación:

¿Qué son los dominios?


Los dominios son definiciones, globales a la Base de Datos, que son utilizados
en las definiciones de las columnas (pero no en las definiciones de variables ni en los
parámetros de entrada o de salida de los procedimientos almacenados o de los
desencadenantes). Es decir, en la práctica son un nuevo tipo de datos. Eso significa que
además de los tipos de datos estándares como carácter, numérico, fecha, etc., se puede
usar un dominio. Son opcionales, se los puede usar o no, pero usarlos mejora la
legibilidad del código. Por ejemplo el dominio “Salary” tiene la siguiente definición:

- 34 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

CREATE DOMAIN SALARY AS


NUMERIC(10, 2)
DEFAULT 0
CHECK (VALUE > 0);

si una columna (por ejemplo: salario) tiene ese dominio, el Firebird no permitirá
que se grabe una fila si el valor de la columna salario es cero o menor que cero ¿Por qué
no? porque antes de realizar la grabación verifica que el valor sea mayor que cero
(CHECK (VALUE > 0))

Aquí hay otro ejemplo, el dominio “EmpNo” (número del empleado):

CREATE DOMAIN EMPNO AS


SMALLINT;

Aquí hay otro ejemplo, “CustNo” (número del consumidor):

CREATE DOMAIN CUSTNO AS


INTEGER
CHECK (VALUE > 1000);

Aquí hay otro ejemplo, “DeptNo” (número del departamento)

CREATE DOMAIN DEPTNO AS


CHAR(3) CHARACTER SET NONE
CHECK (VALUE = '000' OR (VALUE > '0' AND VALUE <= '999') OR VALUE IS NULL)
COLLATE NONE;

Si te parece complicado no te preocupes, dentro de poco lo entenderás. Recuerda


que usarlos o no es opcional, pero usarlos tiene sus ventajas. Por ejemplo, si sabes que
las fechas de las compras, de las ventas, de las cobranzas, de los pagos, no pueden ser
anteriores al 1 de enero de 2011, podrías crear un dominio basado en el tipo de datos
“date” que no permita fechas anteriores. Ese dominio luego lo usarás como tipo de datos
de todas las tablas que lo necesiten. Por lo tanto, no necesitarás validar que las fechas
sean posteriores al 1 de enero de 2011, el Firebird se encargará de esa tarea, te facilitará
tu trabajo. En ningún caso un usuario de tu aplicación podría grabar una fecha anterior.

¿Cómo se crea un nuevo dominio?


Haciendo click con el botón derecho sobre la palabra “Domains” y luego
eligiendo la opción “New domain...”, como se ve a continuación:

- 35 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

¿Qué son las tablas?


Los lugares donde se guardan los datos. Son muy similares a las utilizadas por
Visual FoxPro así que no merecen mayor comentario.

- 36 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

¿Qué son las vistas?


Consultas predeterminadas, cuyas columnas pueden provenir de una tabla o de
varias tablas. Si los usuarios necesitan ver ciertos datos frecuentemente es mejor hacer
una vista y no una consulta, ¿por qué? porque al ya estar dentro de la Base de Datos las
vistas se ejecutan más rápidamente.

Este es un ejemplo de una vista:


CREATE VIEW PHONE_LIST(
EMP_NO,
FIRST_NAME,
LAST_NAME,
PHONE_EXT,
LOCATION,
PHONE_NO)
AS
SELECT
emp_no, first_name, last_name, phone_ext, location, phone_no
FROM employee, department
WHERE employee.dept_no = department.dept_no;

¿Qué son los procedimientos almacenados?


Los procedimientos almacenados, comúnmente llamados Stored Procedures (o
SP para abreviar) son los equivalentes a los procedimientos y las funciones del Visual
FoxPro. Reciben parámetros de entrada, realizan alguna tarea y pueden devolver
valores.

Como pertenecen a la Base de Datos son independientes del lenguaje utilizado


para acceder a ella. Es decir que pueden ser invocados por un programa hecho en Visual
FoxPro, C, C++, Delphi, Java, o cualquier otro.

Hay dos clases de procedimientos almacenados: los ejecutables y los


seleccionables. Los ejecutables son los equivalentes a los procedimientos y funciones
del Visual FoxPro en cambio los seleccionables devuelven filas y se los utiliza dentro
de los SELECT.

Este es un ejemplo de un SP ejecutable:


SET TERM ^ ;

CREATE PROCEDURE ADD_EMP_PROJ(


EMP_NO SMALLINT,
PROJ_ID CHAR(5) CHARACTER SET NONE COLLATE NONE)
AS
BEGIN
BEGIN
INSERT INTO employee_project (emp_no, proj_id) VALUES (:emp_no, :proj_id);
WHEN SQLCODE -530 DO
EXCEPTION unknown_emp_id;
END
SUSPEND;
END^

SET TERM ; ^

- 37 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Y este es un ejemplo de un SP seleccionable:

SET TERM ^ ;

CREATE PROCEDURE GET_EMP_PROJ(


EMP_NO SMALLINT)
RETURNS(
PROJ_ID CHAR(5) CHARACTER SET NONE COLLATE NONE)
AS
BEGIN
FOR SELECT proj_id
FROM employee_project
WHERE emp_no = :emp_no
INTO :proj_id DO
SUSPEND;
END^

SET TERM ; ^

Para que un SP sea seleccionable:

a) Debe tener parámetros de salida declarados (y cargados, por


supuesto)
b) Debe ser escrito con un SUSPEND después de cada bloque que debe
retornar una fila

En el ejemplo de arriba el parámetro de salida es PROJ_ID (porque está dentro


del RETURNS()) y el SUSPEND está dentro del FOR ... DO. En Firebird si el ciclo
FOR ... DO tiene una sola línea, no hace falta colocarle un BEGIN...END; aunque
puedes escribirlos, por claridad, hasta que te acostumbres. El FOR ... DO podría haberse
escrito de esta manera:
FOR SELECT proj_id
FROM employee_project
WHERE emp_no = :emp_no
INTO :proj_id DO BEGIN
SUSPEND;
END;

Como ves, se le agregó un BEGIN y un END; es innecesario hacerlo cuando


después del FOR ... DO hay una sola línea pero es obligatorio cuando dentro del ciclo
FOR ... DO hay varias líneas.

¿Qué son las UDFs?


UDF = User Defined Function o Función Definida por el Usuario, también se le
llama “función externa”. El Firebird permite tener bibliotecas de funciones hechas en
cualquier lenguaje que pueda crear archivos DLL. Las funciones internas del Firebird
son pocas ¿por qué? porque así se puede mantener el motor pequeño y rápido, no tiene
sentido llenarlo de funciones, muchas de las cuales no usarás o usarás raramente. Es
mejor que las funciones sean externas así dispones solamente de las que necesitas,
ninguna más.

En Visual FoxPro tienes muchas funciones que raramente usas, por ejemplo
SIN() (seno), COS (coseno), TAN() (tangente), ASIN(), (arco seno), etc. las cuales
siempre están dentro de tus ejecutables y los hacen más grandes de lo necesario. El

- 38 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Firebird es más económico, también puedes usar esas funciones si las necesitas, pero si
no las necesitas, no están ocupando espacio.

Las funciones UDFs son globales a la Base de Datos, eso significa que una vez
declaradas las puedes utilizar en cualquier procedimiento almacenado o en cualquier
desencadenante.

Antes de usar una función hay que declararla, o sea decirle al Firebird que
deseas usar esa función en la Base de Datos abierta. Para ello se utiliza el comando
DECLARE EXTERNAL FUNCTION.

La gran mayoría de las funciones externas que puedes descargar de Internet


vienen con sus propios archivos de script, eso sirve de documentación para que puedas
saber que hacen, como llamarlas y los valores que retornan.

IMPORTANTE: Tú puedes crear tus propias funciones externas pero debes


verificarlas muy bien antes de incluirlas en tus proyectos porque una función mal hecha
puede corromper tu Base de Datos.

Las funciones externas no deberían modificar columnas (campos). Si lo hacen,


la probabilidad de que causen problemas se incrementa mucho.

Ejemplo:
DECLARE EXTERNAL FUNCTION abs
DOUBLE PRECISION
RETURNS DOUBLE PRECISION BY VALUE
ENTRY POINT ‘IB_UDF_abs’ MODULE NAME ‘ib_udf’;

Probablemente la declaración anterior te pareció complicada pero no te


preocupes, usualmente lo único que haces es un “copiar y pegar” desde el script que
descargaste de Internet al script tuyo.

¿Qué son los desencadenantes?


También llamados triggers, son unos procedimientos almacenados que se
ejecutan automáticamente cada vez que en una tabla se realiza una inserción, borrado o
modificación de fila (registro)

Pueden activarse antes de la operación o después de la operación. Para elegir


una u otra se usan las palabras clave BEFORE (antes) y AFTER (después).

Una tabla puede tener todos los desencadenantes que se desee, el orden de
ejecución de ellos depende del valor de la variable POSITION.

No reciben parámetros de entrada ni devuelven valores.

Tienen dos seudovariables internas, new y old.

New se refiere al nuevo valor que tendrá la columna, old se refiere al valor
anterior.

- 39 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Aquí hay un ejemplo de un trigger (desencadenante):

SET TERM ^ ;

CREATE TRIGGER SAVE_SALARY_CHANGE FOR EMPLOYEE


ACTIVE AFTER UPDATE
POSITION 0
AS
BEGIN
IF (old.salary <> new.salary) THEN
INSERT INTO salary_history
(emp_no, change_date, updater_id, old_salary, percent_change)
VALUES (
old.emp_no,
'NOW',
user,
old.salary,
(new.salary - old.salary) * 100 / old.salary);
END^

SET TERM ; ^

En este caso, la inserción dentro de la tabla Salary_History se realizará


solamente si el salario nuevo es distinto al salario anterior.

¿Qué son las excepciones?


Son mensajes que pueden colocarse dentro de un SP o de un trigger y que se
envían cuando ocurrió un error. En ese caso, deshacen todo lo que se había realizado
con anterioridad.

Aquí está la declaración de una excepción:


CREATE EXCEPTION UNKNOWN_EMP_ID 'Invalid employee number or project id.';

Y aquí el uso de ella:


SET TERM ^ ;

CREATE PROCEDURE ADD_EMP_PROJ(


EMP_NO SMALLINT,
PROJ_ID CHAR(5) CHARACTER SET NONE COLLATE NONE)
AS
BEGIN
BEGIN
INSERT INTO employee_project (emp_no, proj_id) VALUES (:emp_no, :proj_id);
WHEN SQLCODE -530 DO
EXCEPTION unknown_emp_id;
END
SUSPEND;
END^

SET TERM ; ^

¿Qué son los generadores?


Números secuenciales que pueden ser automáticamente insertados en una
columna. Normalmente se los utiliza para asegurar que las PK (claves primarias) tengan
un valor único.

Aquí se declara un generador:


CREATE GENERATOR EMP_NO_GEN;

SET GENERATOR EMP_NO_GEN TO 145;

- 40 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

el cual le dice al Firebird que los números de empleado deben empezar con 145.

Y aquí se usa ese generador:

SET TERM ^ ;

CREATE TRIGGER SET_EMP_NO FOR EMPLOYEE


ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
if (new.emp_no is null) then
new.emp_no = gen_id(emp_no_gen, 1);
END^

SET TERM ; ^

¿Para qué se usa SET TERM?


En Firebird, todos los comandos deben finalizar con un terminador, el
terminador por defecto es el punto y coma (;). Para cambiar ese terminador por otro se
utiliza SET TERM. Otros lenguajes también utilizan terminadores, por ejemplo Pascal,
Delphi, C, C++, Java, etc.

Cuando se escribe un procedimiento almacenado o un desencadenante hay que


cambiar al terminador por defecto porque el analizador del Firebird termina su tarea
cuando lo encuentra. Al terminar el procedimiento almacenado o desencadenante hay
que volver a colocar el terminador por defecto. Por eso verás que la primera y la última
instrucción son siempre SET TERM. En este ejemplo:

create procedure p1
as
begin
finsert into t1 values(10);
end;

si no se usa SET TERM, el analizador finalizará después del (10) y eso


ocasionaría un error, porque nunca llegó hasta el end.

El nuevo terminador puede ser cualquiera, con una condición: no debe estar
dentro del bloque de código que estás escribiendo (podrías usar la letra A pero tendrías
problema si dentro del bloque aparece una letra A). El terminador alternativo más
utilizado, el que está prácticamente estandarizado en Firebird es el ^

¿Cuándo se usan los : delante del nombre de una variable?


Habrás visto que delante de los nombres de algunos parámetros o variables
aparecen los dos puntos (:). La regla es la siguiente:

• Si son usados dentro del contexto del procedimiento almacenado (asignación


o comparación) entonces no se necesitan los dos puntos.
• Si son usados fuera del contexto del procedimiento almacenado (INSERT,
DELETE, UPDATE, SELECT) entonces sí se necesitan los dos puntos.

- 41 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Integridad Referencial
La “integridad referencial” es la capacidad de una Base de Datos de protegerse a
sí misma evitando recibir valores de entrada que puedan dañar a las relaciones.
Específicamente se trata de proteger las relaciones entre dos tablas.

¿Por qué se debería proteger las relaciones entre dos tablas?

1) Prueba de fuego. Las restricciones referenciales (especialmente cuando


usadas inteligentemente con otras restricciones) protegerán fuertemente las
reglas de negocio de la aplicación contra errores, sin importar de donde
provengan ellos. Esto es de mucha importancia cuando la Base de Datos será
manipulada por otras personas, algunas quizás con un nivel bastante bajo.
2) Velocidad de las consultas. Los índices creados automáticamente para la
integridad referencial aumentarán la velocidad de las consultas.
3) Control de calidad. Durante la etapa de desarrollo y verificación los errores
se encontrarán pronto porque la Base de Datos rechazará operaciones que
rompan las reglas.
4) Documentación automática. En los scripts que hagas podrán verse las
reglas, evitando así escribir documentos específicos (ya que todos saben que
a la mayoría de los programadores no les gusta escribir documentación).

La integridad referencial entre dos tablas se crea a través de una restricción


foreign key (clave foránea). Esta restricción protege a la tabla contra los intentos de
grabar filas que son inconsistentes con el modelo de datos.

La restricción foreign key

Una foreign key (abreviada FK) es una columna o conjunto de columnas de una
tabla que corresponde en orden exacto a una columna o conjunto de columnas de otra
tabla definida/s como primary key (abreviada PK) o como unique.

Si se implementa este modelo como dos tablas PADRE e HIJO, entonces las
filas en la tabla HIJO dependen de la existencia de una fila en la tabla PADRE.

Por ejemplo: si se tienen dos tablas, una llamada PRODUCTOS y la otra


llamada VENTASDET (detalle de ventas), las filas de la tabla VENTASDET dependen
de la tabla PRODUCTOS. O sea, no se puede vender un producto cuyos datos no se
encuentren en la tabla PRODUCTOS.

¿Qué implica esto?


1) Que primero se deben cargar los datos de los productos antes de poder
venderlos
2) Que la tabla PRODUCTOS debe tener una clave primaria (el código del
producto)
3) Que la tabla VENTASDET debe tener una restricción foreign key sobre el
código del producto.
4) Que no se puede tener una fila en VENTASDET que no haga referencia a
una fila en PRODUCTOS.

- 42 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Trabajando con las tablas .DBF del Visual FoxPro se pueden grabar registros en
VENTASDET aunque el campo Código del Producto se deje en blanco o aunque se
escriba un código inexistente. Algo así es imposible en Firebird, no se puede hacer eso,
aunque se quiera. Por lo tanto, aumenta en gran medida la seguridad y la confianza en
los datos grabados.

En Visual FoxPro:

- Aunque no exista un producto con ese Código igual se puede grabar un registro
en VENTASDET
- Aunque se deje en blanco el campo Código del Producto, igual se puede grabar
un registro en VENTASDET
- Se puede borrar un registro de la tabla PRODUCTOS aunque el código de ese
registro se esté utilizando en la tabla VENTASDET
- Se puede cambiar el código de un producto aunque ese código se esté utilizando
en la tabla VENTASDET

O sea, es más fácil “meter la pata” (hacer algo malo o incorrecto) en Visual FoxPro.
Solamente por esta característica ya deberías pensar seriamente en usar tablas Firebird.

Cuando se define una FK (Foreign Key) se le puede decir al Firebird que


acciones deberá tomar cuando se quiera borrar o modificar la PK (Primary Key). Estas
acciones pueden ser:

ON DELETE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}

ON UPDATE {NO ACTION | CASCADE | SET NULL | SET DEFAULT}

No action
Es el valor por defecto, por lo tanto puede ser (y generalmente es) omitido. Su
acción es impedir que la PK pueda ser borrada o modificada.

On Delete Cascade
Cuando se borra una fila de la tabla PADRE las filas relacionadas en la tabla
HIJO también son borradas.

On Update Cascade
Cuando se modifica un código en la tabla PADRE los códigos relacionados de la
tabla HIJO son también modificados para que todos tengan el mismo valor.

Set Null
Cuando se borra o modifica un código de la tabla PADRE los códigos
relacionados de la tabla HIJO son puestos a null, por lo tanto esas filas quedan
huérfanas. Generalmente esta acción no es recomendada ya que se pierde la ventaja de
la integridad referencial. Naturalmente esta acción no puede realizarse si la columna
código de la tabla HIJO no admite valores nulos.

- 43 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Índices
Los índices son atributos de las tablas que pueden ser localizados sobre una
columna o conjunto de columnas para acelerar la recuperación de filas.

Límites
Firebird admite hasta 256 índices por tabla.
Cada índice puede tener hasta 253 bytes.

Índices automáticos
Las restricciones PK y FK automáticamente crean sus propios índices. Cuando
crees tus índices es importantísimo no duplicar los índices que ya ha creado el Firebird
porque en ese caso el motor podría estar en la duda de cual usar (porque ambos son
idénticos) y podría decidir no usar ninguno de ellos (haciendo tus búsquedas mucho más
lentas).

Dirección de los índices


Todos los índices pueden ser ascendentes (de menor valor a mayor valor) o
descendentes (de mayor valor a menor valor).
Es un error muy común creer que con un solo índice se obtendrán los mismos
resultados tanto si se buscan valores altos como valores bajos. La regla a aplicar es la
siguiente:
• Si buscas valores bajos, debes usar un índice ascendente
• Si buscas valores altos, debes usar un índice descendente

Cuando indexar
Cada índice ocupa espacio en disco, además los índices deben ser actualizados
cuando se agregan, borran o modifican las filas, consumiendo tiempo, a veces mucho.
Por lo tanto aunque pueden ser de gran ayuda es importante crear solamente los que
sean necesarios y ninguno más. Una buena práctica es la siguiente:
• Creas tus tablas sin índices y los vas agregando a medida que los necesitas
• Crea índices sobre columnas cuyo valores son frecuentemente buscados
• Crea índices sobre columnas que frecuentemente aparecen en JOINs
• Crea índices sobre columnas que frecuentemente aparecen en los primeros
lugares de GROUP BY
• No crees índices sobre columnas que tienen muchos valores repetidos
• No crees índices sobre columnas que se usarán muy raras veces
• No crees índices sobre columnas que tienen muchos valores que nunca son
buscados, como horas y minutos
• No crees índices sobre columnas que se buscan con LIKE

- 44 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Transacciones
Recuerda que en Firebird las aplicaciones nunca tocan los datos que están
almacenados en una Base de Datos. En lugar de eso, las aplicaciones realizan
“conversaciones” con el Servidor a través de los pedidos que hacen y las respuestas que
reciben. Una conversación completa entre un cliente y el Servidor se llama transacción.

¿Por qué se usan las transacciones?

Porque cuando muchos usuarios están actualizando y consultando los mismos


datos muchos problemas pueden ocurrir:

Actualizaciones perdidas
Esto ocurre cuando dos usuarios están viendo los mismos datos. El primero de
ellos realiza algunos cambios, poco después el segundo realiza otros cambios. Por lo
tanto se pierden los cambios que había hecho el primero.

Lecturas sucias
Esto le permite a un usuario ver los cambios que otro usuario está haciendo, pero
sin tener la garantía de que esos cambios sean finales.

Lecturas no reproducibles
Ocurren cuando un usuario está seleccionando filas continuamente mientras
otros usuarios están modificando y borrando esas filas. Esto puede ser un problema o
no, depende de las circunstancias.

Filas fantasmas
Ocurre cuando un usuario puede seleccionar algunas, pero no todas, las filas
insertadas por otro usuario. Nuevamente, esto puede ser un problema o no, dependiendo
de las circunstancias.

Transacciones intercaladas
Ocurren cuando cambios en una fila por un usuario afectan a otras filas de esa
misma tabla o de otras tablas que están siendo accedidas por otros usuarios. Esto suele
suceder cuando no hay forma de controlar el orden en el cual se realizan los cambios.

Para resolver estos problemas el Firebird aplica un modelo de administración


que aísla cada tarea dentro un contexto único el cual le impide que sea completada si
pone en riesgo otras tareas. La Base de Datos no cambiará si hay algún conflicto.

Cada transacción tiene un contexto único que causa que esté aislada de todas las
demás transacciones. Las reglas para ese contexto son especificadas por la aplicación
cliente pasando parámetros de transacción.

¿Cuándo se inicia una transacción?


Cuando un Cliente pide que se inicie y recibe un handle del Servidor. Desde ese
momento la transacción está activa.

- 45 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

¿Cuándo finaliza una transacción?


Cuando el Cliente envía un pedido de commit (grabar todos los cambios) o de
roll back (deshacer todos los cambios) y ese pedido es completado.

¿Cómo se identifica una transacción?


Cada transacción tiene un número único (ID) que sirve para identificarla. De esta
manera el Firebird sabe cual es la transacción que está haciendo cada tarea. Sin embargo
no hay que usar ese número como clave primaria o clave única porque cada vez que se
restaura un backup el contador de las transacciones vuelve a cero. O sea que la primera
transacción después de la restauración tendrá el número 1, la segunda el número 2 y así
sucesivamente. Para conocer cual es el número de la transacción actual en la base de
datos activa:

SELECT CURRENT_TRANSACTION FROM RDB$DATABASE;

Una transacción, muchos pedidos

En Firebird cada operación pedida por un Cliente debe ocurrir en el contexto de


una transacción. Una transacción puede implicar muchos pedidos del Cliente y muchas
respuestas del Servidor. Una transacción puede abarcar más que una Base de Datos,
incluyendo lecturas y escrituras.

¿Cuál es la tarea del Cliente?


Iniciar todas las transacciones. Una vez que una transacción se inició es la
responsabilidad del Cliente enviar los pedidos de lectura y de escritura. También es su
responsabilidad terminar la transacción (con un commit o un roll back).

Un Cliente puede tener muchas transacciones activas.

¿Cuál es la tarea del Servidor?


Llevar la cuenta de cada transacción y mantener la vista que cada transacción
tiene del estado de la Base de Datos consistente con su contexto. Tiene que administrar
todos los pedidos de cambios a la Base de Datos para que los conflictos sean manejados
adecuadamente y así evitar que se rompa la consistencia.

Transacciones y MGA

Como ya se ha visto, las siglas MGA significan multi-generational architecture


(arquitectura de múltiples generaciones). En este modelo cada fila guardada en una base
de datos tiene un número único identificando a la transacción que escribió esa fila. Si
otra transacción escribe un cambio a esa misma fila, el Servidor escribe una nueva
versión de la fila en el disco duro. O sea que habrá dos filas similares guardadas en el
disco duro. Por eso se dice que el Servidor mantiene dos generaciones de la misma fila.

Grabación de datos

En Firebird los datos pueden ser grabados de dos formas:


a) Temporalmente
b) Permanentemente

- 46 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Siempre que se realiza un INSERT o un UPDATE o un DELETE a una tabla esa


inserción, modificación o borrado se realiza en forma temporal. Es decir, que aún es
reversible. Y mientras tanto solamente es visible dentro del contexto de la transacción
que hizo la operación, nadie más está enterado.

Una sola transacción puede realizar muchas tareas: insertar registros en una o en
varias tablas, modificarlos, borrarlos. Si se descubre algún error en alguna de esas tareas
entonces todas esas inserciones, modificaciones y borrados pueden ser desechados
(mediante un roll back). Si todo está bien y solamente si todo está bien, entonces se los
graba permanentemente en el disco (con un commit).

¿Por qué se hace así? Porque de esa manera las bases de datos siempre tienen
datos consistentes, nunca falta o sobra algo. Por ejemplo si se tiene una tabla maestro y
una tabla detalles el programador puede estar seguro que la tabla detalles tiene todas las
filas y con todos los datos correctos, sin faltar nada.

Por lo tanto:
o El usuario que realizó un INSERT, UPDATE o DELETE está viendo los
cambios que esas operaciones implican
o Los demás usuarios no los ven
o Si el usuario graba en forma permanente (con un commit), los demás
usuarios también ven los cambios
o Si el usuario desecha los cambios (con un roll back), los demás usuarios
jamás se enteraron de ellos

Por ejemplo:
- El usuario Juan cambia el número de teléfono del proveedor “TodoFrutas S.A”
- El usuario Juan imprime los números de teléfono de todos los proveedores. El
nuevo número de teléfono de “TodoFrutas S.A.” aparece en ese informe
- El usuario María imprime los números de teléfono de todos los proveedores. El
viejo número de teléfono de “TodoFrutas S.A.” aparece en ese informe
- El usuario Juan graba en forma permanente los cambios (hace un commit)
- Los demás usuarios (María y los otros) recién ahora pueden ver el nuevo número
de teléfono del proveedor “TodoFrutas S.A.”

Datos desechados

El roll back nunca falla. Nunca. Este desecha todos los cambios que se
realizaron en la transacción, tanto el que causó el error como todos los demás que se
hubieran grabado exitosamente de no haber ocurrido el error.

Por ejemplo:
• Se inicia una transacción
• Se agrega un proveedor a la tabla de PROVEEDORES
• Se agrega una compra a la tabla COMPRASCAB
• Se agregan los datos de los productos comprados a la tabla COMPRASDET
• Se descubre un error
• Se realiza un roll back de los datos. Eso implica que:
o El proveedor que se había agregado a PROVEEDORES es eliminado
o La compra que se había agregado a COMPRASCAB es eliminada

- 47 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

o Los productos que se habían agregado a COMPRASDET son


eliminados
• Se finaliza la transacción

Problemas con transacciones

Como ya se vio anteriormente, las únicas formas de finalizar una transacción son
mediante un commit o mediante un roll back. Pero ¿qué ocurre si la aplicación se colgó
o hubo un corte de energía eléctrica? En ese caso la transacción continuará activa
porque el Servidor no finalizará una transacción a menos que se le pida que lo haga.

En sistemas mal diseñados también ocurrirá lo mismo, cuando se le permite a un


usuario salir de la aplicación sin antes hacer el commit o el roll back. A estas
transacciones se las llama muertas porque no están ligadas a ninguna conexión. Y las
inserciones, modificaciones o borrados que hizo la transacción continúan dentro de la
base de datos pero nadie puede acceder a ellos.

¿Y cuál es el problema? Que si múltiples versiones de una fila están en una tabla
o si hay transacciones muertas entonces se está ocupando innecesariamente espacio en
el disco duro y las búsquedas y las consultas son más lentas. Es decir: se degrada la
performance.

Solución a los problemas

Para lidiar con esos problemas hay varias formas:


1. Hacer un backup y una restauración de la Base de Datos
2. Usar el programa GFIX.EXE (que está instalado en la carpeta \BIN del
Firebird)

El backup y la restauración solucionarán algunos de los problemas, pero no


todos. El gfix solucionará otros. Pero si aún así la base de datos es más grande de lo que
debería ser o las consultas son lentas, una revisión humana puede ser necesaria.

De todas maneras, si el entorno es el adecuado (el Servidor tiene una fuente de


energía ininterrumpida, las aplicaciones no se cuelgan, los usuarios no salen de la
aplicación sin antes hacer un commit o un roll back ), todo debería funcionar siempre
muy bien.

- 48 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Parte 3. Visual FoxPro y Firebird


Bueno, después de todas las páginas anteriores finalmente llegamos a lo que puede
resultar más interesante a los programadores en Visual FoxPro: como integrar el
lenguaje con el Firebird.

Cuando se trabaja con Cliente/Servidor hay que:


1. Conectarse a la Base de Datos
2. Ejecutar los comandos
3. Desconectarse de la Base de Datos

Esa es la forma correcta cuando tanto el Servidor como el Cliente están en una
LAN. La conexión se realiza al principio de la aplicación (Contabilidad, Ventas,
Sueldos, etc.) y la desconexión al finalizar la aplicación.

Sin embargo, si la conexión tiene problemas (suele ocurrir cuando es por


Internet), entonces hay que:

1. Conectarse a la Base de Datos


2. Ejecutar un comando
3. Desconectarse de la Base de Datos

Desde luego que esto es mucho más lento, porque el estar conectándose y
desconectándose toma un buen tiempo, pero a veces no hay otra alternativa.

Una buena práctica es la siguiente: se realiza la conexión de la primera forma


pero si se encuentran muchas o frecuentes caídas de conexión se opta por la segunda
forma.

¿Que es DSN?
Son las siglas de Data Source Name (Nombre de la Fuente de Datos) y sirve para
proveer conectividad a una Base de Datos a través de un driver ODBC.

En el DSN se especifican el nombre de la Base de Datos, la carpeta, el driver


ODBC, el nombre del usuario, la contraseña y alguna otra información relevante. Una
vez que se creó un DSN para una Base de Datos se lo puede usar en cualquier
aplicación para conectarse a esa Base de Datos.

La conexión también puede realizarse sin DSN. En este caso toda la información
necesaria para la conexión se escribe dentro de la aplicación. Si la conexión es sin DSN,
en lugar de utilizar un driver ODBC se puede usar OLE DB o algún otro método.

La primera opción (conectarse con DSN) es útil cuando varias aplicaciones


(quizás creadas con distintos lenguajes) deben conectarse a la misma Base de Datos. La
segunda opción (conectarse sin DSN) es preferible si una sola aplicación se conectará.

- 49 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Para crear un DSN

Primero, debes instalar el driver ODBC del Firebird en la computadora, luego:


Inicio
Panel de Control
Herramientas Administrativas
Orígenes de Datos (ODBC)
DSN de Sistema
Hacer click en el botón “Agregar”
Elegir: Firebird/Interbase (r) driver
Escribir el nombre que se le quiere dar a la conexión DSN
Escribir una descripción
Escribir el nombre de la Base de Datos que corresponde a la conexión
Escribir el nombre del archivo DLL del cliente (FBCLIENT.DLL)
Escribir el nombre del usuario de la Base de Datos
Escribir la contraseña de ese usuario
Escribir el conjunto de caracteres (español es ISO8859_1)

Si no ves el driver “Firebird/Interbase (r) driver” es porque aún no has ejecutado


el instalador de ese driver. Lo puedes encontrar y descargar de:

http://www.firebirdsql.org/index.php?op=files&id=odbc

busca uno que corresponda a tu versión del Windows.

Para conectarse sin DSN

Si deseas conectarte sin usar DSN (muchas veces es la opción preferible), lo


único que tendrás que hacer es instalar el driver ODBC y luego enviar un “string” de
conexión, como se verá más adelante.

Una clase para usar con Bases de Datos SQL


Desde hace muchas versiones el Visual FoxPro permite la programación
orientada a objetos (POO) y esta es una muy buena oportunidad para usarla.

Por supuesto que las Bases de Datos SQL se pueden usar sin necesidad de
objetos pero ya que se tiene esa posibilidad, ¿por qué no aprovecharla?. La POO tiene
muchas cosas buenas, entre ellas que permite que el código escrito sea reutilizable, que
todo se encuentre en un solo lugar haciendo más fácil buscar y modificar lo que se desee
y que los cambios se propagan a todos los objetos creados a partir de una clase.

La clase que se desarrollará a continuación permitirá:


• Conectarse a una Base de Datos con DSN
• Conectarse a una Base de Datos sin DSN
• Desconectarse de una Base de Datos (o de todas al mismo tiempo)
• Hallar el nombre del driver que se necesitará para la conexión
• Ejecutar comandos
• Verificar si hay una conexión activa

Naturalmente puedes agregarle las funciones o procedimientos que te parezcan


adecuados o necesarios, esta es una clase básica, se le pueden adicionar nuevas
funcionalidades, de acuerdo a las necesidades de cada quien.

- 50 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Lo primero que se debe hacer es escribir en la ventana de comandos:


modify command SQL_CLASES

Estando dentro del archivo SQL_CLASES.PRG, escribir:


DEFINE CLASS SQL_DataBase as CUSTOM
*
*
lcODBC_Driver = ""
lcServidor = ""
lcBaseDatos = ""
lcNombreConexion = ""
lcUsuario = ""
lcContrasena = ""
lnHandle = 0
lcMensajeError = ""
lnResultado = 0
lcComando = ""
lcNombreCursor = ""
llTerminarConexion = .F. && Si quiere terminar la conexión después
&& de ejecutar un comando. Útil cuando se
&& accede por Internet.
*
*
ENDDEFINE
*
*

Estas son todas las variables internas (o propiedades) de la clase que se está
creando. Pero esas propiedades por sí solas no sirven para mucho, son más útiles
cuando se crean procedimientos o funciones que las manipulan.

Función para conectarse a una Base de Datos usando DSN

Si definiste un DSN (como se explicó anteriormente), entonces puedes usar la


siguiente función para conectarte a una Base de Datos:
Function CONECTAR_CON_DSN
with This
.lnHandle = SQLConnect(.lcNombreConexion, .lcUsuario, .lcContrasena)
.lnResultado = iif(.lnHandle > 0, 1, -1)
endwith
Return(This.lnResultado)
*
*

La función SQLConnect() es la que intenta realizar la conexión, recibe como


parámetros el nombre de la conexión DSN, el nombre del usuario y la contraseña del
usuario. Si la conexión se realizó con éxito, devuelve un número entero mayor que cero
(o sea, un número natural: entero y positivo). Si por algún motivo la conexión no pudo
realizarse, devuelve un número entero y negativo.

En la propiedad lnResultado se guarda el resultado del intento de conexión. Si


vale 1 (uno) significa que tuvo éxito, si vale -1 (menos uno) que falló.

- 51 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Función para conectarse a una Base de Datos sin usar DSN

Si no se definió un DSN, se puede usar la siguiente función para realizar la


conexión a la Base de Datos:
Function CONECTAR_SIN_DSN
Local lcCadenaConexion
with This
lcCadenaConexion = "DRIVER={" + .lcODBC_Driver + "};" ;
+ "SERVER=" + .lcServidor + ";" ;
+ "USER=" + .lcUsuario + ";" ;
+ "PASSWORD=" + .lcContrasena + ";" ;
+ "DATABASE=" + .lcBaseDatos + ";" ;
+ "OPTIONS=131329;"
endwith
=SQLSetProp(0, "DispLogin", 3) && Para no mostrar caja diálogo del Login
with This
.lnHandle = SQLStringConnect(lcCadenaConexion)
.lnResultado = iif(.lnHandle > 0, 1, -1)
endwith
Return(This.lnResultado)
*
*

En este caso hay que armar una “cadena de conexión” y usar la función
SQLStringConnect().

Al igual que antes en la propiedad lnResultado se guardará el resultado del


intento de conexión. Un valor de 1 (uno) significa éxito y un valor de -1 (menos uno)
que hubo algún problema.

Función para desconectarse de una (o todas) Base de Datos SQL

Antes de finalizar tu aplicación lo correcto es que te desconectes de la Base de


Datos que estuviste usando.
Function DESCONECTAR
with This
if .lnHandle == 0 && Si quiere desconectarse de TODAS las Bases de
&& Datos.
.lnResultado = SQLDisconnect(0)
endif
if .lnHandle > 0 && Si quiere desconectarse de UNA Base de Datos y hay
&& una conexión activa, trata de desconectarse.
.lnResultado = SQLDisconnect(.lnHandle)
endif
.lnHandle = iif(.lnResultado > 0, 0, .lnHandle)
endwith
Return(This.lnResultado)
*
*

Si la desconexión se realizó con éxito entonces la propiedad lnHandle tendrá el


valor de 0 (cero) y la propiedad lnResultado el valor de 1 (1 = éxito).

Procedimiento para hallar el nombre del driver

En una computadora normalmente hay muchos drivers instalados, sin embargo


para realizar la conexión a la Base de Datos SQL necesitamos saber si uno en especial
está (o no está) instalado.

- 52 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Lo que hace el siguiente procedimiento es lo siguiente:


• Carga en un vector (o array) los nombres de todos los drivers
• Verifica si el driver que se busca está en ese vector
• Guarda en la propiedad lcODBC_driver el nombre del driver
• Guarda en la propiedad lnResultado si se encontró o no el driver buscado.
Procedure HALLARNOMBREDRIVER
LParameters tcNombreMotorSQL
Local lcNombre, loReg, lnNumError, lcSetExact, lnNumElemento
loReg = CreateObject("ODBCReg")
Dimension aVec(2000)
lnNumError = loReg.GetODBCDrvrs(@aVec)
lcSetExact = Set("EXACT")
set exact OFF && Tiene que estar en OFF para que lo pueda encontrar
lnNumElemento = AScan(aVec, tcNombreMotorSQL)
set exact &lcSetExact
Release loReg
with This
.lcODBC_Driver = iif(lnNumElemento > 0, aVec[lnNumElemento], "")
.lnResultado = iif(!Empty(.lcODBC_Driver), 1, -1)
endwith
EndProc
*
*

Función para ejecutar comandos SQL

Con la función SQLExec() se pueden ejecutar los comandos SQL (si existe una
conexión activa a una Base de Datos, desde luego). Pero ya que se está escribiendo una
clase, ¿por qué no crear una función propia que no solamente trate de ejecutar un
comando sino que también verifique antes si hay una conexión activa y en caso de no
haberla intente la conexión?
Function EJECUTAR
LParameters tcComando, tcNombreCursor
Local lnI
tcNombreCursor = iif(VarType(tcNombreCursor) <> "C", "", tcNombreCursor)
with This
.lcComando = tcComando
.lcNombreCursor = tcNombreCursor
lnI = 1
do while !.HayConexion() .and. lnI <= 30
.Conectar_sin_DSN()
if .lnResultado < 0
Wait window "No puedo conectarme al Servidor. Deberías verificar que la
red esté funcionando correctamente. Intento Nº " + Transform(lnI) TimeOut 2
endif
lnI = lnI + 1
enddo
if .lnHandle > 0 && Hay una conexión activa
.lnResultado = SQLExec(.lnHandle, .lcComando, .lcNombreCursor)
if .llTerminarConexion && Quiere terminar la conexión después de
ejecutar el comando, usualmente cuando se accede por Internet
.Desconectar()
endif
else
.lnResultado = -1
endif
endwith
Return(This.lnResultado >= 1)
*
*

Primero, verifica si hay una conexión activa, si no la hay trata de conectarse, se


hacen 30 intentos esperándose 2 segundos entre uno y el siguiente, lo que hace un total
de 1 (un) minuto de intentos. Si hay una conexión activa entonces trata de ejecutar el

- 53 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

comando pedido. Si después de eso el usuario quiere desconectarse de la Base de Datos,


se desconecta. La función devuelve .T. si el comando se ejecutó exitosamente o .F. si
ocurrió algún problema.

Función para verificar si hay una conexión activa

Antes de enviar un comando SQL es conveniente verificar que hay una conexión
activa a la Base de Datos. Porque si no la hay, ocurrirá un error, eso es seguro.
Function HAYCONEXION
Local llResultado
Try
llResultado = SQLExec(This.lnHandle, "SELECT CURRENT_TIME FROM
RDB$DATABASE")
Catch
llResultado = -1
EndTry
Return(llResultado == 1)
*
*

La forma de verificar si hay una conexión activa es la siguiente: se trata de


obtener la fecha y la hora del Servidor. Si se consiguió, si se tuvo éxito, significa que sí
hay una conexión activa, la conexión está ok. Si no se pudo obtener la fecha y la hora,
eso significa que hubo algún problema. O sea, la conexión no está activa.

Descargar las clases

Estas clases (SQL_CLASES y SQL_REGISTRYCLASS) pueden descargarse


desde:

http://www.mediafire.com/?64vd8se54g91eob
http://www.mediafire.com/?qqsh1q2z3e6kmnq

Programas en Visual FoxPro que usan Firebird


Estos programas son ejemplos que muestran como usar Bases de Datos Firebird
en Visual Foxpro.

Ejemplo Nº 1. Usando la instrucción SELECT

El comando SELECT permite realizar consultas a la Base de Datos, pero los


datos los retorna en una tabla temporal (o cursor). En este ejemplo esos datos son luego
mostrados con un BROWSE. Lo importante a notar es que si se cambia el contenido de
alguno de los campos mostrados por el BROWSE, ese nuevo valor no es actualizado en
la Base de Datos, por lo tanto la siguiente vez que se ejecute el programa se seguirán
viendo los valores originales.

Eso es distinto que cuando se trabaja con tablas .DBF. En este caso, si modificas
los campos que ves en el BROWSE, esos cambios quedan grabados en la tabla. En
cambio, cuando usas tablas SQL, los cambios que haces en un BROWSE no se graban
en la tabla original. Si quieres grabar algo en una tabla SQL debes enviar
específicamente una instrucción INSERT o UPDATE.

- 54 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

En el programa de ejemplo antes de llamar a cada SELECT se muestra un


mensaje mediante un WAIT WINDOW, para que ese mensaje desaparezca puedes
presionar cualquier tecla. Para salir del BROWSE presiona la tecla ESC (o si prefieres
puedes presionar la tecla ESC tanto para salir del WAIT WINDOW como para salir del
BROWSE).

El cursor de los ejemplos se llama TEMP (por: temporal o temporario), por


supuesto que tú puedes elegir cualquier otro nombre que desees cuando generes tus
propios cursores.

IMPORTANTE: Todos estos SELECT los puedes escribir en el programa ISQL,


como se muestra a continuación para el primero de ellos:

Y aquí se muestra el segundo SELECT del programa (donde se supone que ya


estás conectado a la Base de Datos EMPLOYEE.FDB):

Por supuesto que usar ISQL no suele ser la mejor alternativa, y en su lugar se
puede usar Flame Robin, SQL Manager o inclusive el BROWSE del Visual FoxPro
pero la gran ventaja que se tiene con ISQL es que está siempre disponible en todas las
instalaciones del Firebird.

Otra ventaja es que si el SELECT que has escrito en tu programa Visual FoxPro
no te funciona y no sabes el motivo entonces al escribirlo dentro del ISQL obtendrás
información que te resultará de utilidad para saber qué estás haciendo mal. Por ejemplo:

- 55 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

En este caso se agrupó solamente por FULL_NAME, pero a la izquierda de la


cláusula GROUP BY hay dos campos y se debe usarlos a los dos. La expresión correcta
es la siguiente:

SELECT EMP_NO, FULL_NAME FROM EMPLOYEE GROUP BY FULL_NAME, EMP_NO;

Aunque a veces parecen ser la misma cosa, agrupar es distinto que ordenar, para
agrupar (poner a las filas en grupos) se usa GROUP BY, para ordenarlas se usa ORDER
BY, para ordenarlas en forma descendente hay que agregar DESCENDING.

Ejemplo Nº 2. Una pequeña aplicación administrativa (stock, compras, ventas)

Un pequeño negocio ha pedido que se le haga una aplicación para ayudarle con
el control del mismo. Ellos se dedican a vender bebidas, es lo único que venden y no
tienen previsto vender algo más. En su lista hay cervezas, vinos, whiskies, gaseosas,
aguas minerales, pero su fuerte son las bebidas alcohólicas, en especial las cervezas. El
negocio abre los 7 días de la semana, inclusive cuando hay partidos de fútbol
importantes o algún otro acontecimiento los días Domingo tienen una venta muy
grande. No tienen sucursales ni planean tenerlas. En ese negocio trabajan dos personas:
el propietario y un empleado, quienes se van turnando los horarios. Al empleado
además de un sueldo fijo se le paga una comisión del 3% sobre las ventas realizadas.
Todas las compras y todas las ventas son al contado, a nadie se le vende a crédito, por
ningún motivo. Los clientes no pueden retirar la mercadería antes de pagarla. Las ventas
pueden ser al por mayor o al por menor (o detalle), los precios de venta son distintos
para ambos casos. Pueden vender por unidades o por cajas (o packs), las cajas (o packs)
pueden contener: 3, 6, 12, 24 unidades. Nunca devuelven productos a los proveedores ni
aceptan devoluciones de los clientes.

La aplicación se realizará en Visual FoxPro, usando Firebird SQL como motor


de la Base de Datos.

Después del análisis correspondiente se ha encontrado que se necesitarán las


siguientes tablas:
• Vendedores
• Proveedores
• Productos
• Movimientos cabecera
• Movimientos detalles

Se han determinado las siguientes restricciones:


• Ninguna fecha de compra o de venta puede faltar
• Ninguna fecha de compra o de venta puede ser anterior al 1 de enero de 2011
• Ninguna cantidad, comprada o vendida, puede faltar
• Toda cantidad, comprada o vendida, debe ser mayor que cero

- 56 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

• Ningún importe, de compra o de venta, puede faltar


• Todo importe, de compra o de venta, debe ser mayor que cero
• Todos los vendedores deben tener un código único, entre ‘000’ y ‘999’
• Todos los vendedores deben tener un nombre y en mayúsculas
• Todos los proveedores deben tener un código único, entre ‘000’ y ‘999’
• Todos los proveedores deben tener un nombre y en mayúsculas
• Todos los proveedores deben tener un teléfono
• Todos los productos deben tener un código único, entre ‘000’ y ‘999’
• Todos los productos deben tener un nombre y en mayúsculas
• Todos los productos deben tener una cantidad no negativa
• Todos los productos deben tener un precio de costo positivo
• Todos los productos deben tener un precio de venta mayorista positivo
• Todos los productos deben tener un precio de venta minorista positivo
• Todos los movimientos cabecera deben tener un tipo de movimiento (‘COM’
o ‘VEN’, significando “compras” y “ventas”, respectivamente)
• Todos los movimientos detalles deben tener un campo que los relacione con
los movimientos de cabecera

Para crear la Base de Datos, los dominios, tablas y vistas se utilizaron scripts, de
tal manera que sea muy fácil reconstruirla en caso de necesidad.

En ISQL se utiliza la instrucción INPUT para ejecutar un script, como se ve a


continuación:

Por convención los scripts tienen la extensión .SQL pero no es obligatorio, a tus
scripts puedes ponerles la extensión que quieras aunque desde luego sería preferible que
usaras .SQL para que los demás puedan entenderte fácilmente.

- 57 -
Walter R. Ojeda Valiente – Visual FoxPro y Firebird SQL

Conclusión
Aunque para quienes se acostumbraron a usar las tablas .DBF puede resultar
muy complicado al principio, realmente usar Firebird no lo es tanto. Por supuesto que sí
es más complicado pero eso se debe a que tiene mucha mayor potencia y esa mayor
potencia se paga con un incremento en la dificultad de uso. Pero la pregunta que se
deben hacer es: ¿vale la pena? ¿se compensa usar Firebird o es mejor continuar usando
las viejas conocidas tablas .DBF?

La respuesta a ambas preguntas es un rotundo sí. Las ventajas que se obtienen de


usar Firebird son muy grandes comparadas con el tiempo que se empleará en aprenderlo
a cabalidad.

Las tablas .DBF ya están obsoletas, en aplicaciones nuevas ni siquiera deberían


considerarse. Y si se las va a reemplazar entonces, sin ninguna duda, Firebird es una de
las mejores alternativas que actualmente existen.

Así que, emplearías muy bien tu tiempo adentrándote en el uso de este potente
motor SQL. Te olvidarás de tablas corruptas, índices dañados, poca seguridad de los
datos, lentitud de acceso por Internet. Es otro mundo.

Dedícate a aprender SQL. Y Firebird. Ganarás mucho.

Comentario final:
Como todo documento, éste también puede ser mejorado. Si encuentras algún
error o algo que te gustaría que se le agregara o algo que te gustaría que estuviera mejor
explicado o cualquier idea o sugerencia, házmelo saber y trataré de realizar la
modificación lo antes posible. Mi e-mail es:

wrov@hotmail.com

- 58 -

También podría gustarte