7-07-1998

Bases de Datos IV

Despues presentaros la estrella de los componentes de las bases de datos (por lo menos desde mi punto de vista), voy a empezar a meterme en materia, pero antes comentaros que el resto de los componentes que hay en la pestaña DataControls de Delphi, son iguales que sus "homólogos" comunes, con la particularidad que contiene las dos conocidadas propiedades que permiten acceder a una tabla, que son: DataSource donde indicaremos el componente TDataSource el cual está conectado a la tabla que queremos acceder, recordad que el componente TDataSources hace de "interprete" o "puente" en una tabla y los componentes; DataField, es la propiedad en la cual se indica el campo de la tabla que queremos mostrar.

El tema principal de este capítulo es la busqueda de datos en una tabla, para ello nos vamos a valer del de varios métodos que nos pone a disposición el componente Ttable. El método más común es Locate, el cual nos permite buscar en una tabla, por una condición en un columna o por varias colunmas. Locate es una función que devuelve True o False, según ha tenido éxito o no, y si ha sido fructuosa su busqueda la tabla muestra la fila que ha cumplido la condición. Para poder usar esta función se han de pasar una serie de parametros, la definición de este método de busquda según la ayuda de Delphi es:
Locate(const KeyFields: string; const KeyValues: Variant; Options: TLocateOptions)

El primer parametro es el campo o campos por los cuales queremos hacer la busqueda, así si tenemos una tabla donde tenemos los clientes, y queremos hacer una busqueda por el campo Ciudad, es en este primer parametro donde debemos poner el nombre del campo.
El segundo, contiene la condición, por ejemplo si estamos buscando clientes en la ciudad de Vigo, ponemos Vigo en este campo. Un ejemplo rápido de esto sería:
Table1.Locate ('ciudad','jorge',[]);
Hay que tener en cuenta que es un campo del tipo Variant, y es así en lugar de ser una cadena normal, porque si estamos haciendo una busqueda por dos campos, hemos de pasar dos condiciones para la busqueda. Por ejemplo, si la busqueda aparte de la ciudad queremos saber los clientes que se llaman Jorge, debemos escribir una línea como esta:
Table1.Locate ('ciudad;nombre',VarArrayOf( ['Vigo', 'Jorge'] ), [] )
Por último esta Options, que indica como se ha de realizar la busqueda, si se ignoran las mayusculas, y/o se hacen busquedas parciales en los campos Alfanuméricos, esto quiere decir que se mostraran las filas que contengan Jorge y Vigo en sus respectivos campos además que otros datos, o sea que la busqueda no es exacta. Por ejemplo:
Table1.Locate ('ciudad;nombre',VarArrayOf( ['Vigo', 'Jorge'] ), [ loCaseInsensitive, loPartialKey]);

Puedes especificar un ambas opciones, una sola, o ninguna como en los ejemplos anteriores. En el programa de ejemplo que estoy preparando se hace uso de esta función ampliamente.

Cuando lo que se necesita es buscar un valor, y obtenerlo se usa Lookup, cuya definición es:
function Lookup(const KeyFields: string; const KeyValues: Variant; const ResultFields: string):

Esta función puede buscar un dato en una columna y si lo encuentra nos devuelve el valor de una o más columnas que especifiquemos en el el tercer parametro. El tipo de valor devuelto es del tipo Variant.Además tiene la caracteristica cuando encuentra el registro especificado el puntero que indica el registro actual no es modificado, o sea no se mueve la tabla. Un ejemplo del uso de esta función sería:
Var
V : Variant;
Begin
V := Table1.LookUp ('Nombre','Jorge','ciudad;Telefono');
If V <> Null Then
ShowMessage (V[0],V[1]);
end

Lo que he hecho aquí es hacer una consulta a la tabla, donde quieria que me devolviese el valor del campo Ciudad y Telefono de la fila que compliera la condición que el campo Nombre fuese igual a Jorge. Luego he comprabado el resultado de la operación, y si ha sido un éxito consultamos visualizamos el primer y segundo elemento, ya que hemos pedido dos elementos.

Los métodos de busqueda que hemos visto hasta ahora son muy efectivos, ya que usan unos algoritmos muy depurados, y además la tabla sobre la cual se hace la consulta no tiene porque tener ningun tipo de indice asociado a ella. Pero existen otros métodos alternativos que permiten mostrar datos segun una condición, pero siempre que exista un indice asociado a la tabla.

Existe dos funciones que permiten un busqueda apoyandose en el indice activo (reitero la condición de la existencia de los indices porque sino no funciona), que son:

FindKey funciona de una manera parecida al Locate, pero siempre sobre el indice activo, así si tenemos una tabla de clientes, y queremos buscar el nombre de un cliente, la tabla tiene que estar ordenada por ese campo. Un ejemplo:
Begin
If Not Table1.FindKey ('Jorge') Then
ShowMessage ('Lo he encontrado)
Else
ShowMessage ('No lo he encontradao');
end;

Las tablas tiene un método muy util, que permite filtrar el contenido de la tabla, así podemos limitar el número de filas que veremos según una condición y lo más interesante es que si la tabla esta filtrar y aplicamos el método Locate o Lookup, estos solo se ejcutarán sobre las filas que cumplen la condición de filtrado. Por lo tanto la combinación de ambos métodos es realmente potente. Los filtros no necesitán que la tabla este filtrado, por lo tanto se pueden aplicar sobre cualquier campo.

Para ello debemos activar la propiedad Filtered del componente Ttable, poniendo su valor en True, e interceptar el evento OnFilterRecord, en el debemos escribir la condición que debe cumplir la tabla, y devolver la evaluación de la condición (si es verdad o falso) por medio de la variable Accept declarada en el procedimiento del evento, por ejemplo:

procedure TDataModule2.Table1FilterRecord(DataSet: TDataSet;
  var Accept: Boolean);
begin
  Accept := DataSet ['Tema'] = Filtro;  
end;

Lo que hago aqui es indicar que la tabla se filtre por el campo Tema, y que las filas que se acceptan serán aquellas en las que el valor del campo tema sea igual al contenuido en la variable filtro que es del tipo String. Este ejemplo esta extraido de la aplicación que estoy desarrollando para el cursillo, la variable Filtro ha sido definida a nivel Publico dentro del fomulario, pero eso ya os lo explicaré cuando empecemos a ver la aplicación.

Después cuartro capítulos llenos de teoría (pura y dura), el próximo voy a empezar a explicar una aplicación que he desarrolado para el cursillo. No es nada del otro mundo, es una pequeña base de datos que sirve para llevar una lista de juegos y sus correspondientes trucos. Los juegos están ordenados por nombre y clásificados por temas, que puede añadir el usuario. Ire explicando los diversos problemas que se plantean, y como los solucioné, dejando a un lado la teoría y volviendo más a la práctica.