Está en la página 1de 12

Interbase Express

Delphi 5 aporta una novedad en cuanto al acceso a Bases de Datos de Interbase: una serie de componentes de datos que no utilizan la BDE sino que trabajan directamente con la API de Interbase. Son conocidos en conjunto como Interbase Express o simplemente IBX y aparecen (por defecto) en una pgina de la paleta de componentes llamada AInterbase@. Estos componentes son de distribucin libre. Desde la aparicin de Delphi 5 en el mercado se han liberado ya algunas versiones posteriores: a fines de Agosto de 2000 la versin es la 4.2. Cuando se pone una nueva a disposicin del pblico se anuncia en el sitio de la comunidad de Delphi (www.community.borland.com). Tambin se pueden enterar rpidamente en los foros de discusin de Borland (forums.borland.com) sobre el tema. Estos componentes son mantenidos por Jeff Overcash, del TeamB. Se pueden comunicar con l normalmente en el foro de discusin borland.public.delphi.database.interbaseexpress del servidor nombrado anteriormente. Algunos componentes estn pensados para reemplazar directamente a sus contrapartes basados en BDE: tenemos as un TIBTable y un TIBQuery. Sus funciones son similares a las ya conocidas. La diferencia se empieza a notar con el componente TIBDatabase, necesario para acceder a la Base de Datos. Este componente no usa los Alias que tengamos definidos -como era de esperarse, ya que es una caracterstica de la BDE- sino que requiere el nombre del archivo de la Base de Datos con todo el camino necesario. Existe tambin un componente especial para el acceso a tablas que combina la capacidad de crear la tabla con una consulta SQL arbitraria con la capacidad de hacer el resultado modificable... sin usar CachedUpdates y con total control de las sentencias SQL que se utilizan para las modificaciones a los datos (IBDataset). Pero antes de describir los controles, debemos hablar sobre las transacciones en Interbase.

Transacciones
El tema de las transacciones es muy importante en la programacin de servidores SQL, creo que aqu no hay diferencias de opinin; no obstante, muchos programadores llegan a hacer aplicaciones completas sin preocuparse por el manejo de las transacciones. En realidad, a veces ni siquiera saben qu son! Bueno, con Interbase eso no pasar: todos los accesos a la Base de Datos deben hacerse en una transaccin, y Delphi se asegura de eso requiriendo un componente IBTransaction enlazado a los datasets, adems del IBDatabase. En breve, una transaccin es un conjunto de acciones sobre la Base de Datos que se toman como una sola. Adems de aceptar o cancelar cada cambio con Post y Cancel, debemos aceptar (Commit) o cancelar (Rollback) el conjunto de cambios. Debido al diseo de Interbase, todos los comandos deben ejecutarse en el contexto de una transaccin; si no la controlamos nosotros, se empieza una automticamente antes de ejecutar cada comando y se termina (commit) tambin automticamente al finalizar el comando. Este modo es bastante costoso en cuanto a tiempo y recursos, ya que si tenemos que realizar varias operaciones seguidas se estarn arrancando y terminando transacciones por cada comando... es mejor tomar el control de la situacin, comenzar una transaccin explcitamente antes del primer comando y terminarla despus del ltimo. Interbase no soporta transacciones anidadas. As de categrico. Es por esto que el lenguaje de definicin de procedimientos y triggers ni siquiera tiene reservadas algunas sentencias para controlar este aspecto. Algunos problemas comunes:
C Hacer APost@ y olvidarse de ACommit@

Los datos no ingresan a la Base de Datos hasta que se ejecute Commit, de tal manera que si nuestra

aplicacin no lo hace y cierra la conexin, todas las modificaciones realizadas en esa transaccin se pierden.
C Mantener todo en una sola transaccin laaaaaarga

Esto no es un error en s, pero cuando se trabaja con mltiples usuarios a la vez es importante mantener las transacciones cortas. )Por qu? Porque los bloqueos se mantienen mientras dura la transaccin, y adems los otros usuarios no vern mis cambios hasta que cierre mi transaccin. Tambin hay un problema con el Arecolectador de basura@ de Interbase, pero ese problema es menor al lado de los anteriores.
C Los datos ingresados por otro usuario no se ven inmediatamente

Este es el problema ms comn con que se encuentran los programadores acostumbrados a las tablas locales tipo Paradox o Dbase. El problema es que al trabajar dentro de una transaccin, las modificaciones quedan Apendientes@ hasta que se cierra la transaccin. Interbase no nos permite ver los cambios pendientes de aceptacin, porque son valores que pueden desaparecer en cualquier momento. Este problema merece un tratamiento ms completo; comencemos por hablar de los niveles de aislamiento de las transacciones. Niveles de aislamiento de transacciones Cuando se trabaja en modo multiusuario1, accediendo desde varias estaciones a la misma Base de Datos, hay que tener especial cuidado con las transacciones. El servidor define niveles de aislamiento de transacciones concurrentes, que indican cmo se relacionan las transacciones simultneas entre s. Como un ejemplo, consideremos la siguiente situacin: un usuario empieza una transaccin y hace algunos cambios. Mientras todava su transaccin est activa, otro usuario empieza una segunda transaccin. El segundo usuario no ver los cambios que realice el primero, a menos que est en el modo ms bajo de aislacin (ver a continuacin). Este comportamiento puede confundir al ms pintado, ya que posiblemente las dos transacciones se hagan... en la misma mquina! Entonces sera posible realizar un cambio en una ventana y no verlo desde otra; incluso actualizando los datos con el uso de Refresh. Los niveles de aislacin de transacciones de Interbase 6 son los siguientes:
S read commited (lectura de lo aceptado): si estamos en una transaccin con este nivel de aislacin, podremos ver los cambios de los dems cuando terminen la transaccin con commit. S snapshot (lectura repetible2): se garantiza que el usuario que est en una transaccin de este tipo ver siempre los mismos datos, aunque otros usuarios hagan cambios y los acepten. No veremos los cambios hasta que cerremos nuestra transaccin. Este nivel de aislamiento es ideal para los reportes, ya que en un entorno multiusuario puede darse que cambien los datos entre el momento de la vista previa en pantalla y la impresin propiamente dicha. Este es el nivel de aislamiento preferido. S snapshot table stability (lectura repetible forzada): igual que la anterior, pero adems desde el momento que accedemos a una tabla sta se bloquea para escritura. Este nivel es propio de Interbase, y no es muy usado porque impone una restriccin muy severa a los otros usuarios, que slo estarn habilitados para leer de todas las tablas que toquemos mientras estemos en la transaccin.

Modo de bloqueo de una transaccin Otro parmetro que se puede configurar al iniciar una transaccin es el nivel de bloqueo de la misma. ste puede ser
1

Por supuesto, una transaccin puede ver cualquier cambio hecho en la misma. En otros sistemas (y en la BDE) se denomina Repeatable Read a este nivel de aislamiento.

S Modo en espera (WAIT): si hay un conflicto con otra transaccin, el proceso queda bloqueado hasta que se termina la otra transaccin. S Modo sin espera (NO WAIT): si hay un conflicto con otra transaccin, el proceso recibe un mensaje de error inmediatamente. )Cul es la razn de ser del primer modo? Pues que el conflicto puede ser temporal. Supongamos que un usuario (1) empieza una transaccin en la cual agrega un registro con un valor A en la clave primaria. Antes que este usuario haga Commit, otro usuario (2) trata de ingresar un registro tambin con el valor A en la clave primaria. Si la segunda transaccin se hace en modo WAIT, el usuario 2 queda bloqueado hasta que el primero termine su transaccin. Si (1) hace Commit, (2) recibe un mensaje de error porque la clave primaria estara duplicada; pero si (1) cancela su transaccin con Rollback, (2) puede insertar su registro sin problemas. En el caso que la segunda transaccin fuera NO WAIT, el usuario (2) recibe el mensaje de error al momento de querer insertar el registro.

Transacciones en IBX: el componente TIBTransaction


El manejo de las transacciones en Interbase Express se centraliza en un componente que no tena par en la BDE: IBTransaction. Todos los componentes de acceso a Interbase deben enlazarse a un IBTransaction. Este componente modela una transaccin; en l encontraremos los mtodos StartTransaction, Commit y Rollback necesarios para empezar, aceptar y cancelar transacciones respectivamente. Adems de estos tres mtodos bsicos, tenemos otras opciones:
C Caractersticas de la transaccin

Haciendo doble click sobre el componente veremos un editor especial para las caractersticas de la transaccin:

Vemos que hay cuatro modos, que resultan de distintas combinaciones de las opciones de bloqueo y aislamiento descriptas ms arriba. Snapshot: no se ven los cambios realizados por las otras transacciones, pero se permite el acceso de las mismas a los datos que estamos mirando o modificando; igualmente, podemos ver los datos que otra transaccin est trabajando al mismo tiempo, aunque vemos la versin que exista al momento de iniciar nuestra transaccin. Parmetros por defecto: concurrency, nowait. Ideal para reportes. Read Commited: los cambios realizados por los otros usuarios se ven despus que acepten sus transacciones. Es el modo ms comn, ya que asegura la coherencia de los datos a la vez que nos muestra las modificaciones hechas por los dems. Parmetros por defecto: read_commited, rec_version, nowait.

El parmetro rec_version hace que slo veamos la ltima versin estable (aceptada) de los registros. La alternativa es no_rec_version, con lo que indicamos al servidor que solamente se puede ver un registro si no hay versiones pendientes de aceptacin. En el caso que desde otra transaccin se haya modificado un registro pero todava no se haya hecho commit, el servidor no nos dejara acceder al registro. Read-Only Table Stability: esta transaccin no puede acceder a datos que hayan sido cambiados desde que empez, ni permite a otras transacciones que accedan a los datos que sta haya ledo. Parmetros por defecto: read (slo lectura, en este modo no se pueden modificar los datos), consistency (garantiza que los datos vistos por esta transaccin no cambien... mediante el restrictivo mtodo indicado al principio). Read-Write Table Stability: igual que la anterior, pero ahora la transaccin tiene permisos de lectura y escritura. Parmetros por defecto: write, consistency. Por ejemplo supongamos una tabla Mascotas con los siguientes datos:

Mascotas Nombre Lul Tom Pinky Categoria Perro Gato Ratn Raza Caniche Angora Estupidis mousiis Edad 5 3 6 Id 89 908 346

Supongamos que esta base de datos se accede desde dos terminales a la vez -A y B. Veamos algunos casos tpicos (las acciones se suponen en la secuencia dada). Para el caso no importa si usamos un IBTable, IBQuery con IBUpdateSQL o un IBDataset. Indique despus de cada accin que datos ve cada usuario: 1) A inicia una transaccin en modo Snapshot. B inicia una transaccin en modo ReadCommited. A pide el contenido de la tabla Mascotas. )Qu obtiene?
Lo mismo que est arriba

B modifica la tabla de mascotas, arreglando la edad de Tom que no es 3 sino 4. B hace ACommit@ y vuelve a abrir la tabla.
A: lo mismo. B: Tom modificado

A actualiza la vista de los datos cerrando y abriendo la tabla pertinente, pero sin salir de su transaccin.
A: lo mismo (no ve los cambios)

A modifica la edad de Lul, que no es 5 sino 4. Hace ACommit@ y vuelve a abrir la tabla.
A ve ahora el cambio anterior de B. B todava no ve el cambio de A.

B cierra y abre la tabla. )Qu obtiene?


Ahora B puede ver los cambios de A

B emite la instruccin ASelect * from Mascotas where Edad=4". )Qu obtiene?


Los registros de Lul y Tom.

B agrega un registro a la tabla de Mascotas, con los siguientes valores: APaco@, ALoro@, AAptrida@, 10, 79.

Hace ACommitRetaining@. A actualiza la vista cerrando y abriendo la tabla.


A no ve los cambios de B hasta que no cierre su transaccin.

A borra el registro de Tom. Hace ACommitRetaining@.


B tiene que refrescar (no es necesario que cierre y abra su tabla) para ver los datos.

Repita el ejercicio con otras combinaciones: 2) Las dos transacciones de tipo ReadCommited 3) A tipo ReadCommited y B tipo ReadTableStability 4) A tipo WriteTableStability y B tipo ReadCommited 5) los dos con tipo Snapshot

Los modos ms usados son el Snapshot y el ReadCommited, ya que permiten el acceso concurrente a los mismos datos.

C Transacciones que mantienen el contexto

Una caracterstica que a veces es molesta: cuando cerramos una transaccin ya sea con Commit o con Rollback, se cierran todos los controles de datos asociados a la misma. Interbase libera los recursos de la transaccin, por lo que los controles se deben desconectar. Para evitar el tener que abrir nuevamente todo, podemos indicar a Interbase que termine la transaccin pero que mantenga los recursos internos -el contexto de la transaccin. De esta manera mantenemos los componentes conectados aunque aceptamos o cancelamos la transaccin como corresponde. El componente IBTransaction tiene dos mtodos que permiten trabajar de esa manera: CommitRetaining y RollbackRetaining (ste slo en IB 6). Hay un pequeo problema con esta manera de proceder: mientras no cerremos totalmente la transaccin, se evita que el Arecolector de basura@ de IB trabaje. Esto no debera ser un problema a menos que la aplicacin se mantenga funcionando de esa manera durante horas, das, tal vez semanas... en cuyo caso podemos acomodar las cosas haciendo un backup y restore a intervalos regulares. Cuando se hace un Backup se eliminan los datos temporales (la Abasura@) y al recuperar la Base de Datos queda limpia de polvo y paja.

El componente IBTransaction se asocia a uno o ms componentes IBDatabase. Una de estas bases de datos se toma como la base de datos por defecto, y es la nica que se puede definir en tiempo de diseo con la propiedad DefaultDatabase. Las dems, si las hay, hay que agregarlas por programa a la propiedad Databases.

El componente TIBDatabase
Las diferencias entre este componente y su equivalente en la BDE se refieren principalmente al manejo de las transacciones. En la BDE, el componente Tdatabase se encarga de la conexin con la Base de Datos y el manejo de las transacciones. Ahora, en IBX, tenemos como vimos un componente especial para las transacciones. Haciendo doble click en el componente IBDatabase vemos el editor especial de sus propiedades:

Aqu podemos seleccionar de forma simple el archivo de Bases de Datos, el nombre de usuario por defecto para la conexin, la contrasea y el rol que tomar ese usuario. Estos parmetros se pueden acceder en tiempo de ejecucin a travs de la propiedad Params, (en la forma de parejas clave=valor).

El componente IBDataset
El componente IBDataset es como una tabla: se pueden ver, modificar, borrar e insertar registros. Pero en este control podemos especificar como se realizarn estas acciones, proveyendo las sentencias SQL adecuadas. El componente automticamente usar la que corresponda segn la operacin que queremos hacer, por ejemplo si es IBDataset1.Delete se ejecutar la sentencia SQL indicada para los borrados. Tambin tenemos otra libertad: la consulta de seleccin, la que crea la tabla de resultados, se puede escribir libremente con todos los recursos de la instruccin SELECT. No sucede as con las sentencias SQL de modificacin, borrado o insercin, que normalmente trabajarn con una sola tabla. Para guardar las modificaciones en ms de una tabla podemos usar un procedimiento almacenado o el evento OnUpdateRecord. Veamos primero el caso ms comn y luego nos complicaremos con los otros. El formato de las sentencias SQL es similar al empleado en el componente UpdateSQL (usado cuando se trabaja con Cached Updates), con los modificadores AOLD_@ y ANEW_@ para indicar los valores antiguos y nuevos respectivamente de los campos. TIBDataset provee espacio para 5 sentencias SQL:

SelectSQL Es la sentencia que se ejecutar para traer los registros de la Base de Datos. Por ejemplo, si queremos trabajar con los registros de la tabla Customers de la base de datos Mastsql.gdb que viene con los ejemplos de Delphi, pondramos en esta propiedad la siguiente sentencia:
SELECT * FROM customer

Se pueden especificar condiciones con WHERE, como siempre, o restringir la cantidad de columnas a ver especificando los nombres en lugar del A*@. Se puede tambin tener una unin de tablas. Es decir... cualquier sentencia de seleccin de registros vlida sirve para esta propiedad. Para introducir esta propiedad no tenemos un generador de sentencias SQL grfico como el SQL Builder que usamos con la BDE. No obstante, tampoco estamos tan mal como para tener solamente un memo. El editor de la propiedad SelectSQL es el siguiente:

Vemos que este editor nos muestra en una lista las tablas disponibles, y cuando seleccionamos una se nos muestran en otra lista los campos de esa tabla. Como siempre, la mejor manera de entender el funcionamiento de esta herramienta es probndola. As que (a escribir! Prueben a hacer sentencias complejas, con uniones de tablas y cosas as.

RefreshSQL Esta sentencia se ejecuta (si existe) cada vez que cambia el contenido de un registro. Su funcin es traer de la tabla el valor actualizado del registro modificado. Para seleccionar el registro correcto, debemos conocer el valor de la clave primaria del registro modificado; en esto nos ayudan las variables especiales NEW_. Por ejemplo, para refrescar la consulta anterior sera suficiente (notemos que la clave primaria de la tabla Customer est formada por el campo CustNo):
SELECT * FROM customer WHERE custno = :NEW_CustNo

Aqu tenemos todava una ayuda adicional: la variable >NEW_= se asume siempre que no se especifique y sea pertinente. La sentencia anterior quedara simplemente
SELECT * FROM customer WHERE custno = :CustNo

DeleteSQL Esta sentencia se ejecuta cuando se borra un registro. Usamos el modificador AOLD_@ para identificar el registro a borrar:
DELETE FROM customer WHERE custno = :OLD_custno

InsertSQL Sentencia para insertar un nuevo registro. Los valores recientemente ingresados se acceden con el modificador ANEW_@:
INSERT INTO customer (custno,company,addr1, ...) {todos los campos que queremos insertar} VALUES (:NEW_custno,:NEW_company,:NEW_addr1, ...)

Tambin aqu se toman por defecto los parmetros >NEW_=. Es decir, la sentencia anterior sera equivalente a la siguiente:
INSERT INTO customer (custno,company,addr1, ...) {todos los campos que queremos insertar} VALUES (:custno,:company,:addr1, ...)

ModifySQL Sentencia para actualizar los datos. Aqu utilizamos los dos modificadores: para identificar el registro a actualizar, AOLD_@ y para referenciar los valores nuevos que ponemos, ANEW_@.
UPDATE customer SET custno = :NEW_custno, company = :NEW_company, ... WHERE custno = :OLD_custno, company = :OLD_company, ...

A esta altura, ya se darn cuenta de la equivalencia con la sentencia siguiente:


UPDATE customer SET custno = :custno, company = :company, ... WHERE custno = :OLD_custno, company = :OLD_company, ...

Aunque en principio es posible identificar el registro con solamente los valores de la clave primaria, poniendo como condicin que los dems campos sean tambin iguales a los valores anteriores nos cubrimos por si alguien cambi ya el registro desde otra terminal. En ese caso, no ocurrir nada... y la modificacin se pierde!.

Podemos usar tambin procedimientos almacenados en el servidor usando la sentencia SQL EXECUTE PROCEDURE <nombre procedimiento> <parametro1 [,parametro2,...]> en lugar de las sentencias SQL directas. Consulte la documentacin de Interbase para mayores datos sobre EXECUTE PROCEDURE. En la versin 4.2 se ha agregado un editor especial para construir las sentencias SQL de modificacin y refresco a partir de la de seleccin (similar al que se utiliza en el componente UpdateSQL para actualizaciones diferidas), en el men contextual del componente:

En la lista de la izquierda aparecen los campos que se usan para identificar el registro actual (normalmente, la clave primaria) y en la lista de la derecha los campos que se pueden actualizar. Si por ejemplo hay un campo calculado en la tabla (creado en la definicion de la tabla, no con los componentes de Delphi) no deberamos incluirlo en la lista de la derecha, ya que estos campos no son editables. Usando este editor, en la mayora de los casos solamente tendremos que escribir una de las cinco sentencias SQL: la de Select. Las dems se escriben solas, como podemos ver seleccionando la pestaa SQL despus de presionar el botn Generate SQL:

En resumen: es un componente muy interesante por el grado de control que nos permite sobre las operaciones a realizar en la Base de Datos, incluyendo la opcin de realizar una consulta sobre varias tablas relacionadas a la vez. Es equivalente a usar una tabla con Actualizaciones Diferidas (Cached Updates), conectada a un componente UpdateSQL. Con este componente podemos tambin usar Actualizaciones Diferidas, aunque no necesitamos componentes

UpdateSQL por razones obvias. Simplemente recordemos que para aplicar las actualizaciones debemos llamar al mtodo ApplyUpdates del IBDataset o del IBTransaction (NO del IBDatabase). Asimismo, si tenemos dos componentes IBDataset enlazados en relacin Master/Detail, debemos desconectar la relacin (propiedad datasource en nil) antes de aplicar las actualizaciones y restaurar el enlace despus. Si llamamos al mtodo ApplyUpdates del IBTransaction (que aplica las actualizaciones a varias tablas en secuencia) se invoca automticamente a CommitRetaining cuando se finaliza sin problemas.

El componente TIBSQL
Este es otro componente que no tiene contraparte en la BDE. Se trata de un contenedor para una sentencia SQL. Parecido al Tquery, pero con una diferencia muy importante: no se puede enlazar a un Datasource. Por lo tanto, no podemos usar directamente los controles de datos con este componente. Se trata de un acceso rpido y conveniente a los medios para ejecutar una sentencia SQL sin la sobrecarga que tienen los componentes que trabajan con controles de datos. Viene muy bien para ejecutar sentencias SQL aisladas, como por ejemplo para buscar rpidamente un registro de una tabla. Porque aunque no tenga las estructuras necesarias para conectarse a un Tdatasource, puede devolver una tabla; slo que ahora tendremos que extraer nosotros los datos por programa, usando la funcin FieldByName por ejemplo. Para ejecutar la sentencia SQL no usamos Open, sino ExecQuery. Cuidado porque en el componente IBSQL tambin hay un AOpen@, pero esta vez es una propiedad que indica si est abierta la consulta o no. Otra diferencia es la forma de acceder los parmetros: no existe una funcin ParamByName. Ahora debemos usar la propiedad Params, y dentro de sta tenemos una funcin ByName. Por lo tanto, una instruccin que antes se escribira
Query1.ParamByName('Nombre').AsString:= 'Pepe';

ahora quedara
IBSQL1.Params.ByName('Nombre').AsString:= 'Pepe';

La propiedad Params est definida como sigue:


property Params: TIBXSQLDA

el tipo TIBXSQLDA es una clase auxiliar interna (la crea y la destruye el componente IBSQL). Cuando usamos la funcin ByName, obtenemos una instancia de una clase TIBXSQLVAR. Esta clase tiene las propiedades AsString, AsBoolean, AsInteger, AsDateTime, etc.

Los siguientes componentes son similares a los correspondientes de la BDE (se distinguen por las letras 'IB' en el nombre), salvo la necesidad de especificar la transaccin a utilizar en la propiedad Transaction. Veremos luego algunas consideraciones a la hora de migrar aplicaciones creadas con la BDE a IBX; por ahora, repasemos estos componentes y sus diferencias con los ya conocidos.

10

El componente TIBTable
Este componente tiene por misin imitar el comportamiento de una tabla comn de la BDE: simplemente especificamos los parmetros de conexin (las propiedades Database y Transaction) y el nombre de la tabla que deseamos acceder, y trabajamos como si se tratara de una tabla local. Claro que para hacer esto posible es necesario crear Aatrs de la cortina@ las sentencias SQL necesarias para la comunicacin con el servidor. Por ejemplo, si hacemos Table1.Delete internamente se genera y se enva al servidor una sentencia SQL delete from. Lo mismo sucede con las inserciones y modificaciones. Este mecanismo es muy cmodo y prctico para hacer el programa rpidamente... por desgracia, no tendremos control sobre las secuencias SQL que se enven y estamos restringidos a una sola tabla. Si deseamos traer datos de otras tablas debemos crear campos lookup, y esto hace que todo sea ms lento -especialmente si traemos varios registros a la vez, como con una grilla. En resumen: no se aconseja el uso de las tablas en las aplicaciones Cliente/Servidor. Utilice mejor un IBDataset.

El componente TIBQuery
Este componente Aimita@ al componente Tquery normal de la BDE: sirve para ejecutar una instruccin SQL almacenada en la propiedad SQL. La nica diferencia que notamos es que ahora necesitamos explicitar la transaccin en la que trabajamos, con la propiedad Transaction.3 Los parmetros se trabajan como antes, normalmente accedidos con la funcin ParamByName.

El componente TIBStoredProc
Como se imaginarn, este componente es el smil del TstoredProc de la BDE. Aparte de tener que especificar la transaccin todo lo dems sigue igual: indicamos en la propiedad StoredProcName el nombre del procedimiento almacenado en la Base de Datos, y en Params -aqu s tenemos disponible la funcin ParamByName- ponemos los valores de los parmetros de entrada y leemos los valores de los parmetros de salida.

Consideraciones prcticas
Como siempre, hay muchas formas de hacer las mismas operaciones; los detalles generalmente se vuelven

Internamente, por lo menos hasta la revisin 4.3, hay otra diferencia: el componente TIBQuery desciende directamente de TIBCustomDataset, por lo que hereda cinco propiedades de tipo TIBSQL (en el componente TIBDataset se utilizan las cinco con los nombres que ya vimos: SelectSQL, InsertSQL, DeleteSQL, RefreshSQL, ModifySQL).

11

claros con la experiencia, por lo que intentar dar un pantallazo de lo que mi experiencia me ha mostrado sobre el uso de estos componentes. Lo que sigue son, por lo tanto, opiniones personales.
C Altas, Bajas, Modificaciones de tablas: conviene usar el componente IBDataset, por el control que nos ofrece en las instrucciones que enva al servidor. Se puede afinar mucho su comportamiento, y nos permite otras posibilidades como por ejemplo alterar el orden en que se muestran los datos. C Usar encuentros de tablas (joins) para obtener campos de ms de una tabla, en lugar de definir campos lookup. Los campos de bsqueda (lookup) hacen que el proceso de abrir simplemente una tabla sea terriblemente lento. En una tabla de alrededor de 25000 registros donde uno de los campos era lookup, demor casi 15 segundos en abrir! Y mostrando esta tabla en una grilla, no les cuento lo que era navegar... C Para las bsquedas rpidas o filtrados prefiero un componente TIBSQL con parmetros antes que ejecutar un Locate en una tabla o una consulta con IBQuery. De este modo, la consulta o filtrado se ejecuta en el servidor -mucho ms rpidamente- y sin cargar a nuestra aplicacin con los recursos que debe disponer cuando tiene que almacenar los datos de conexin con un Datasource. Por supuesto que si deseamos acceder a los datos con controles de datos, deberamos usar un IBQuery o un IBDataset. C Cuando tengan un proceso complicado o que implica varias tablas, conviene escribir un procedimiento almacenado en la Base de Datos y ejecutarlo con un IBStoredProc. C Mucho cuidado con las transacciones... uno de los mayores problemas con los que me he encontrado es el cambio de mentalidad a este respecto. Una buena planificacin de las transacciones evitar luego dolores de cabeza buscando datos que no se ven pero estn, o lidiando con bloqueos no deseados.

12