bases de datos con delphi - · pdf filebases de datos con delphi 1. introducción cuando...

46
Bases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos perder nunca este doble punto de vista: la aplicación será, por una parte, cliente de un servidor de base de datos y, por otra parte, será el interface de usuario de la base de datos, para todas las tablas o sólo para algunas (eso ya depende de la amplitud de la aplicación con respecto al total de los datos). Debemos centrarnos en un buen diseño de la aplicación, pues esto facilita al usuario la edición de datos, y a nosotros, como programadores, el mantenimiento, sea como sea de complejo el modelo de datos sobre el que trabajemos. Para ello, debemos conocer muy bien tanto el modelo de datos de la base de datos, como la filosofía de trabajo con bases de datos en Delphi. En este curso vamos a preocuparnos, lógicamente, de la filosofía de trabajo con Delphi. Delphi utiliza un intermediario para conectar con la base de datos: se llama BDE (Borland Database Engine). Puede conectar con diversos tipos de bases de datos de forma directa (Interbase, Paradox, Informix, ...) o bien a través de ODBC. Así pues, es el BDE el que realiza el trabajo duro de "hablar" con el servidor de base de datos, quedándonos a nosotros una tarea mucho más sencilla: poder olvidarnos de cómo es la estructura interna (a nivel de estructura de ficheros) de la base de datos, centrándonos en las tablas como idea y en el diseño de las consultas. Hay un concepto clave para todo esto: el concepto de alias. Se trata de un nombre lógico (que no tiene por qué coincidir con el nombre del fichero físico de la base de datos) con el que Delphi reconocerá a la base de datos. Así, creamos un alias para la base de datos, y desde Delphi no tendremos que preocuparnos de la ruta. Especificaremos estos datos previamente accediendo directamente al BDE Administrator desde el panel de control, o bien usando la utilidad SQL Explorer. En los anexos se detalla cómo hacerlo. Delphi separa en dos grupos los componentes de bases de datos: los componentes de acceso a datos (que se encuentran en la pestaña Data Access) y los componentes visuales que muestran datos (en la pestaña Data Controls). La filosofía es separar el contenido de la forma. Así, en los componentes visuales especificaremos cómo queremos que el usuario vea los datos, y en los componentes de acceso a datos programaremos cómo obtener los datos que necesitamos. Hay un componente muy específico que enlazará nuestro acceso a datos con nuestra visualización de datos, y que es el que se encargará de proveer al control visual de los datos que genera el control no visual de acceso a datos.

Upload: phamhuong

Post on 08-Mar-2018

228 views

Category:

Documents


5 download

TRANSCRIPT

Page 1: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Bases de datos con Delphi

1. Introducción

Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos perder nunca este doble punto de vista: la aplicación será, por una parte, cliente de un servidor de base de datos y, por otra parte, será el interface de usuario de la base de datos, para todas las tablas o sólo para algunas (eso ya depende de la amplitud de la aplicación con respecto al total de los datos). Debemos centrarnos en un buen diseño de la aplicación, pues esto facilita al usuario la edición de datos, y a nosotros, como programadores, el mantenimiento, sea como sea de complejo el modelo de datos sobre el que trabajemos.

Para ello, debemos conocer muy bien tanto el modelo de datos de la base de datos, como la filosofía de trabajo con bases de datos en Delphi. En este curso vamos a preocuparnos, lógicamente, de la filosofía de trabajo con Delphi.

Delphi utiliza un intermediario para conectar con la base de datos: se llama BDE (Borland Database Engine). Puede conectar con diversos tipos de bases de datos de forma directa (Interbase, Paradox, Informix, ...) o bien a través de ODBC. Así pues, es el BDE el que realiza el trabajo duro de "hablar" con el servidor de base de datos, quedándonos a nosotros una tarea mucho más sencilla: poder olvidarnos de cómo es la estructura interna (a nivel de estructura de ficheros) de la base de datos, centrándonos en las tablas como idea y en el diseño de las consultas.

Hay un concepto clave para todo esto: el concepto de alias. Se trata de un nombre lógico (que no tiene por qué coincidir con el nombre del fichero físico de la base de datos) con el que Delphi reconocerá a la base de datos. Así, creamos un alias para la base de datos, y desde Delphi no tendremos que preocuparnos de la ruta. Especificaremos estos datos previamente accediendo directamente al BDE Administrator desde el panel de control, o bien usando la utilidad SQL Explorer. En los anexos se detalla cómo hacerlo.

Delphi separa en dos grupos los componentes de bases de datos: los componentes de acceso a datos (que se encuentran en la pestaña Data Access) y los componentes visuales que muestran datos (en la pestaña Data Controls).

La filosofía es separar el contenido de la forma. Así, en los componentes visuales especificaremos cómo queremos que el usuario vea los datos, y en los componentes de acceso a datos programaremos cómo obtener los datos que necesitamos. Hay un componente muy específico que enlazará nuestro acceso a datos con nuestra visualización de datos, y que es el que se encargará de proveer al control visual de los datos que genera el control no visual de acceso a datos.

Page 2: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

2.i. Descripción rápida de Data access

Comenzamos dando una primera mirada a los componentes de la paleta Data access que trataremos en este curso. Todos estos componentes son no visuales y permiten que los datos lleguen a la aplicación.

Paleta DATA ACCESS

TDatabase Encapsula una conexión cliente/servidor a una única base de datos. A pesar de que si no incluimos un componente de este tipo, Delphi usa uno de forma temporal, será conveniente empezar dando a nuestra aplicación uno o más componentes de este tipo para poder añadir algunos parámetros adicionales.

TTable Representa un conjunto de datos que recupera todas las columnas y registros de una tabla de la base de datos. Tiene propiedades y métodos que nos permiten movernos por el conjunto de datos y encontrar datos que cumplan un determinado patrón de búsqueda.

TQuery Representa un conjunto de datos que recupera un subconjunto de columnas y registros de una o más tablas de bases de datos basadas en una consulta SQL. Al igual que TTable, tiene propiedades y métodos que nos permiten movernos entre los datos y escoger aquellos que cumplan ciertas características requeridas por la aplicación.

TStoredProc Representa un conjunto de datos que recupera uno o más registros de una tabla de base de datos basándose en un procedimiento almacenado definido para un servidor de base de datos. Sólo tiene sentido usarlo cuando la base de datos soporta esta característica.

TDataSource Actúa como un conducto entre otros componentes de acceso a datos y controles visuales de datos. Es el encargado de que los datos de componentes como TTable, TQuery y TStoredProc puedan mostrarse de forma cómoda para el usuario en los controles visuales de datos.

La paleta Data access tiene algunos componentes más, pero con los que describiremos en este curso, hay más que suficiente para hacer aplicaciones medianas-grandes.

2.ii. Descripción rápida de Data controls

Ahora le toca el turno a los componentes de visualización de datos:

Paleta DATA CONTROLS

TDBGrid Muestra y edita registros de conjunto de datos en formato de tabla. Puede ser la tabla completa o sólo algunas de las columnas.

TDBNavigator

Page 3: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Mueve el cursor a través de registros de un conjunto de datos, permite editar e insertar registros, almacena los registros modificados o nuevos, cancela el modo de edición y actualiza la visualización de datos. Permite una cómoda navegación por conjuntos grandes de registros.

TDBText Muestra un campo como si fuera una etiqueta.

TDBEdit Muestra y edita un campo en un cuadro de edición.

TDBListBox Muestra una lista con opciones para introducir un campo.

TDBComboBox Muestra un cuadro de edición y una lista desplegable de elecciones para editar y entrar en un campo.

TDBCheckBox Muestra y configura una condición de campo booleana en un cuadro de comprobación.

TDBRadioGroup Muestra y configura opciones únicas para un campo de un grupo de botones de radio.

TDBLookupListBox Muestra una lista con opciones derivadas de un campo en otro conjunto de datos para entrar en un campo.

TDBLookupComboBox Muestra un ComboBox de opciones derivada de un campo de otro conjunto de datos para introducirlos en un campo

3. Módulos de datos

Antes de comenzar a detallar los componentes que usaremos, vamos a hablar de esta peculiar característica de Delphi.

Un módulo de datos es una clase especial de Delphi que se usa para la gestión centralizada de componentes no visuales de una aplicación. Generalmente incluye componentes para el acceso a datos (como TDatabase, TTable, TQuery, ...), pero también puede incluir otros componentes no visuales (como TTimer, TOpenDialog, TImageList, etc). Un módulo de datos nos permite:

• Mantener todos los componentes de acceso a datos en un solo contenedor visual en modo de diseño, en lugar de duplicarlos para cada form de la aplicación

• Diseñar tablas y consultas una sola vez y usarlas en varios forms, en lugar de crearlas por separado para cada form.

• Guardarlo en el Object Repository para poder reutilizarlo.

La centralización de recursos para la aplicación quizá sea una de las características más interesantes. Por ejemplo, un cuadro de diálogo de apertura de ficheros es un recurso candidato a ser centralizado. Si tenemos una aplicación con 10 forms que necesiten de un cuadro de diálogo, tenemos dos opciones, crear 10 componentes, uno para cada form, o crear un único componente de cuadro de diálogo y usarlo en los 10 forms.

Page 4: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

El método de trabajo que usaremos será el de crear los componentes no visuales en un módulo de datos, y usarlo en todas las units que lo requieran. Así lo tendremos disponible para toda la aplicación sin tener que repetirlos. Además, alteraremos el orden de creación de forms en el proyecto, entrando en Auto-create forms de las opciones del proyecto, situando en primer lugar a nuestro módulo de datos. Haremos esto por lo siguiente: asociaremos al evento onCreate código para abrir la conexión con la base de datos, estando así disponible desde el principio de la aplicación y no después de crearse el form principal. Así, nos evitaremos problemas en el caso de que antes de que se muestre el form principal sea necesario realizar alguna operación con la base de datos.

Los módulos de datos se encuentran en Delphi accediendo a New -> Data Module, dentro de la pestaña por defecto, New. Nuestra aplicación puede usar cuantos necesite. Puede ser buena idea, incluso, usar distintos módulos de datos, atendiendo a finalidades distintas, para poner en ellos los componentes no visuales, agrupados por esta finalidad.

4.i. TDatabase

El componente TDatabase nos va a permitir:

• Crear conexiones persistentes a bases de datos (esto es, permaneceremos conectados a la base de datos siempre que el componente tenga especificado que debe estar conectado).

• Personalizar el acceso a servidores de bases de datos. Por ejemplo, solicitar o no una contraseña de acceso al conectar con la base de datos.

• Controlar las transacciones y especificar sus niveles de aislamiento (aunque en este curso no vamos a hablar de transacciones).

• Crear alias BDE locales de aplicaciones. Esto es especialmente útil por lo siguiente: supongamos una aplicación que debe funcionar con una base de datos en una determinada ruta. Todos los componentes de acceso a datos que necesite la aplicación, deben estar ligados a esa base de datos vía el alias. Si, por algún motivo, cambia el alias, entonces tendríamos que cambiarlo a todos los componentes de acceso a datos. Teniendo definido un alias local, asociaremos a los componentes de acceso a datos el alias local, y así, en caso de que haya que cambiar algo, sólo tendremos que hacerlo en el componente TDatabase.

Vamos a estudiar las propiedades más importantes de este componente:

AliasName

El valor de esta propiedad será el alias BDE asociado. Delphi nos presentará un menú desplegable con los alias definidos en el sistema. De ahí será de donde tendremos que escoger uno. Si damos un valor a la propiedad DriverName entonces se elimina el valor dado a esta propiedad.

DriverName Identifica al controlador BDE del componente (esto forma parte del alias). Es autoexcluyente con AliasName, como hemos visto.

Connected Es un booleano que nos dice si estamos conectados o no a la base de datos.

DatabaseName Es el alias local a la aplicación que damos al componente. No es necesario, pero sí recomendable darle uno.

LoginPrompt Es un booleano que nos dice si se debe solicitar o no un nombre de usuario y su contraseña la primera vez que se vaya a acceder a la base de datos. Si le damos el valor False tendremos que especificar estos valores en la propiedad Params

Params Se trata de una lista con los parámetros de acceso para la conexión.

Page 5: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Params

En el inspector de objetos, al situarnos sobre la propiedad Params, podemos hacer doble click con el ratón, con lo que se abre la siguiente ventana:

En ella escribiremos lo siguiente:

USER NAME=ElNombreDelUsuario

PASSWORD=LaClaveDelUsuario

cuando pongamos a False el valor de la propiedad LoginPrompt

Resumiendo:

Cuando vayamos a realizar una aplicación de base de datos, comenzaremos creando un form de módulo de datos (un DataModule) en el que incluiremos el componente TDatabase. Pondremos los valores oportunos en sus propiedades, y le daremos un valor a la propiedad DatabaseName para tener definido un alias local. Veremos en los siguientes capítulos la utilidad de ese alias local. Para poder asociar a los componentes de acceso a datos este alias local, tendremos que estar conectados a la base de datos. En tiempo de diseño podremos conseguirlo poniendo el valor de la propiedad Connected a True. En tiempo de ejecución también podemos acudir al método Open del componente. Será conveniente protegerlo con un bloque try .. except por si se produjera algún problema en la apertura de la base de datos.

Page 6: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

4.ii. TDataSet

Este componente es el que encapsula los datos de una base de datos. No debemos usarlo directamente en nuestras aplicaciones. Para ello, tenemos a sus descendientes, los componentes de acceso a datos TTable, TQuery y TStoredProc. Sin embargo, debemos conocer bien este componente, pues es el que nos prové de propiedades y métodos comunes a sus descendientes, fundamentales para el acceso a datos.

Además, cada conjunto de datos debe tener asociado su componente TDataSource correspondiente, que es el que vincula los controles de datos visuales con los conjuntos de datos. El componente de fuente de datos es el que se encarga de canalizar los datos desde el componente de acceso a datos al componente visual.

Así que vamos a comentar las características interesantes que nos ofrece este componente (recordemos que serán comunes a sus descendientes):

En primer lugar, tenemos que saber cómo abrir y cerrar conjuntos de datos. Mientras un conjunto de datos esté cerrado, no podremos extraer datos de él. Esto se traduce en que los componentes visuales que estén asociados a él (vía un TDataSource) no mostrarán datos. Así, cuando esté abierto, sí se podrán ver los datos, e igualmente se podrá recorrer las distintas filas que pueda contener.

Por tanto, para abrir el conjunto de datos tenemos dos posibilidades que son equivalentes:

CompDescDeTDataSet.Active := True; { diseño y ejecución }

CompDescDeTDataSet.Open; { ejecución }

Y para cerrarlo tenemos otras dos, igualmente equivalentes:

CompDescDeTDataSet.Active := False; { diseño y ejecución }

CompDescDeTDataSet.Close; { ejecución }

Si hay que modificar alguna propiedad del conjunto de datos que afecte a la consulta, es necesario cerrar ANTES dicho conjunto.

Vamos a ver ahora cómo nos desplazamos por conjuntos de datos:

Cada conjunto de datos tiene un cursor (es decir, un puntero que apunta a la fila ACTUAL del conjunto). Dicha fila corresponde a los valores que pueden manipularse vía métodos de edición/inserción/borrado, y cuyos valores de campo muestran actualmente controles de dato monocampo, como TDBEdit o TDBText.

Disponemos de los siguientes métodos para desplazarnos por conjuntos de datos:

First Desplaza el cursor a la primera fila del conjunto de datos

Last Desplaza el cursor a la última fila del conjunto de datos

Next Desplaza el cursor a la fila siguiente del conjunto de datos

Page 7: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Prior Desplaza el cursor a la fila anterior del conjunto de datos

MoveBy(NumFilas: Integer)

Desplaza el cursor un número dado de filas del conjunto de datos, hacia delante si NumFilas es positivo, y hacia atrás si NumFilas es negativo

El objeto TDataSet cuenta además con las propiedades:

BOF (beginning of file)

Es TRUE si:

• Se abre el conjunto de datos • Se llama al método First del conjunto de datos • Se llama a Prior y falla (porque el cursor ya está en la primera fila) • Se llama a SetRange en un rango o conjunto de datos vacío (no veremos SetRange)

Es FALSE en todos los demás casos.

EOF (end of file)

Es TRUE si:

• Se abre un conjunto de datos vacío • Se llama al método Last del conjunto de datos • Se llama a Next y falla (porque el cursor ya está en la última fila) • Se llama a SetRange en un rango o conjunto de datos vacío (no veremos SetRange)

Es FALSE en todos los demás casos.

Marcadores

Un marcador es un objeto que nos va a permitir marcar una posición concreta del conjunto de datos, de manera que si nos movemos después por dicho conjunto, podamos más adelante volver a esta posición marcada. Para ello, Delphi cuenta con tres métodos marcador que permiten asignar un indicador a un registro de un conjunto de datos para volver al mismo posteriormente (es decir, marcamos una posición concreta):

• GetBookmark: asigna un marcador a la posición actual en el conjunto de datos • GotoBookmark: volver a un marcador creado previamente con GetBookmark • FreeBookmark: libera un marcador creado previamente con GetBookmark

Para crear un marcador es necesario declarar una variable de tipo TBookmark. Se trata de un puntero, así que tanto para liberarla definitivamente como para usarla para marcar otro registro, hemos de llamar a FreeBookmark.

Por ejemplo:

PROCEDURE HazAlgo(CONST Tbl: TTable);

Page 8: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

VAR B: TBookmark;

BEGIN

B := Tbl.GetBookmark;

Tbl.DisableControls;

TRY

Tbl.First;

WHILE NOT Tbl.EOF DO

BEGIN

{ Proceso }

Tbl.Next;

END;

FINALLY

Tbl.GotoBookmark(B);

Tbl.EnableControls;

Tbl.FreeBookmark(B);

END;

END;

Este código consta de un procedimiento al que le pasamos como argumento un objeto de tipo

va

r

Para buscar datos dentro de un conjunto de datos usaremos la siguiente función:

TTable (uno de los descendientes de TDataSet). Declaramos una variable de tipo TBookmark ymarcamos la posición actual de la tabla (será la que estuviera apuntada en ese momento por el cursor, no tiene por qué ser la primera). Nos vamos al principio de la tabla (usando el método First) y mientras no lleguemos al final (usando la propiedad EOF), procesamos lo que haya queprocesar de la fila actual, y avanzamos el cursor (usando el método Next). Terminado el proceso, volvemos a la posición marcada inicialmente y liberamos el marcador. Todo estoenglobado dentro de un bloque TRY ... FINALLY porque hemos de asegurarnos de que el marcador se libera. Nuestro proceso podría dar lugar a una excepción, así que hemos de secuidadosos.

FUNCTION TDescDeTDataSet.Locate('Campo; ...; Campo',

VarArrayOf([Valor1, ..., ValorN]), SearchOptions): Boolean;

Especificamos los campos, los valores a buscar como un array de variants (por eso he puesto

que el segundo parámetro es VarArrayOf, pero si hubiera un único campo no haría falta convertirlo a array de variant) y un conjunto de opciones de búsqueda que podeis consultar en la ayuda. Devuelve si ha tenido éxito o no con la búsqueda. De todas formas, cuando veamos el

Page 9: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

componente TQuery, casi con toda seguridad no le encontraremos mucha utilidad a esta función, pues en el componente TQuery podremos restringir la selección de datos tanto como queramos usando sentencias SQL.

Modificación de datos del conjunto de datos

Otro punto importante es saber cómo modificar los datos existentes en un conjunto de datos.

Asigna al conjunto de datos el estado dsEdit, si es que el conjunto no está ya en ese

Append lmacena los datos pendientes, desplaza el registro actual al final del conjunto de datos,

Insert lmacena los datos pendientes y asigna al conjunto el estado dsInsert.

Post Intenta almacenar el nuevo registro, o modificar el registro existente, en la base de

Cancel ancela la operación actual y asigna al conjunto el estado dsBrowse.

Delete limina el registro actual y asigna al conjunto de datos el estado dsBrowse.

Por ejemplo:

Para ello, contamos con los siguientes métodos: Edit

estado, o si está en modo dsInsert. Entonces, podremos editar datos. Ay asigna al conjunto de datos el estado dsInsert. A

datos. Si hay éxito, se asigna al conjunto de datos el estado dsBrowse. Si no, se mantiene el estado. C E

Tbl.Edit;

Tbl.FieldValues['Campo'] := Valor;

Tbl.Post;

Ponemos la tabla para editar, usamos la propiedad FieldValues para acceder al campo Campo, y

Previo al estudio de los descendientes de TDataSet será necesario estudiar los componentes de

n

Dentro del objeto TDataSet, hay un evento que cabe destacar, el evento OnCalcFields, que nos

• Hay un conjunto de datos abierto te visual a otro, o de una columna a otra en un

• la base de datos

almacenamos en este campo el valor Valor. A continuación, usando el método Post cerramos la edición, almacenándose los datos.

campo, que se engloban en el objeto TField. Este objeto da formas de acceder a los campos individuales de un conjunto de datos. Todos los componentes de conjunto de datos cuentan cotantos objetos TField como campos tenga la tabla/consulta/etc. Los veremos en capítulo aparte.

sirve para decidir los valores de los llamados campos calculados en función de los valores de los campos normales. Si la propiedad AutoCalcFields del conjunto de datos es TRUE, entonces se produce un evento OnCalcFields si:

• El foco se desplaza de un componenTDBGrid (rejilla de datos) Se recupera un registro de

Page 10: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Si el valor de un campo no calculado cambia, se llama a este evento independientemente de si AutoCalcFields es TRUE o FALSE. Veremos en el capítulo dedicado a TField qué es un campo calculado, y qué es un campo no calculado.

Hay que tener cuidado con este evento y no llamar a Post dentro del código del manejador del evento: aunque AutoCalcFields es FALSE, OnCalcFields es llamado si hay un Post. Hacer Post en el evento sería recursivo y habria desbordamiento de pila.

¿Resulta confuso todo esto? Quizá un poco. Hay que tener en cuenta que llegados a este punto aún no hemos visto cómo llevar a la práctica este componente que no vamos a tratar directamente, ni cómo usarlo exactamente, ni cómo podemos mostrar los datos, ni...

No hay que olvidarlo: no usaremos este componente sino sus descendientes, y todo lo que hemos visto aquí es puramente teórico pero imprescindible para avanzar. Es en los siguientes capítulos donde se empieza a manipular de lo que se habla aquí.

4.iii. TDataSource

Se trata de un componente de base de datos no visual que sirve de conducto entre un conjunto de datos y un componente de visualización de datos en un form. Es necesario que cada control de datos esté asociado a un componente TDataSource para poder manipular y visualizar los datos.

Propiedades interesantes

DataSet Especifica el nombre del conjunto de datos del que este componente obtiene los datos. Puede también asignarse a un conjunto de datos de otro form para sincronizar los componentes de visualización de datos de los dos forms.

Enabled Nos dice si está conectado a un conjunto de datos.

AutoEdit Especifica si los conjunto de datos conectados al TDataSource entran automáticamente en modo Edit cuando el usuario empieza a introducir los componentes de visualización vinculados al conjunto de datos.

Eventos interesantes

OnDataChange Este evento se da cada vez que el cursor se desplaza a un nuevo registro. Si se llama al método Next, Previous, Insert o cualquier otro que implique un cambio de posición del cursor, se llamará a este evento.

OnUpdateData Se produce cada vez que los datos están a punto de actualizarse, es decir, tras llamadas a Post pero antes de que los datos se almacenen definitivamente en la base de datos.

OnStateChange Se produce cada vez que cambia el estado del conjunto de datos asociado al TDataSource.

Veremos su utilidad cuando estudiemos los componentes gráficos, pues es en ese momento cuando hay que elegir un descendiente adecuado de TDataSet, asociarle un TDataSource para, en el componente gráfico, asociar el mismo TDataSource. Entonces tendremos conectados el componente gráfico con el TDataSet vía el TDataSource.

Page 11: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

4.iv. TField: Uso de campos

Vamos a ver en este capítulo un objeto muy importante y útil, el objeto TField. Este objeto representa columnas de bases de datos individuales en conjuntos de datos. No lo usaremos directamente en nuestras aplicaciones, sino que emplearemos sus componentes descendientes. Cada uno de ellos representa un tipo de dato distinto en una columna del TDataSet correspondiente al componente de conjunto de datos. Estos tipos son:

Nombre del componente Nombre del componente Nombre del componente

TStringField TSmallIntField TIntegerField

TBooleanField TFloatField TCurrencyField

TDateField TTimeField TDateTimeField

TVarBytesField TBlobField TMemoField

TWordField TBCDField TBytesField

TGraphicsField TAutoIncField TNumericField

Este componente no es visual, y tampoco está visible en tiempo de diseño. Los TField están asociados a un componente de conjunto de datos y dan a componentes de datos como TDBGrid acceso a ciertas columnas de bases de datos vía ese conjunto.

Aunque se verá más adelante, voy a intentar explicar esto de forma más inteligible. Como ya sabemos, en una aplicación de base de datos tenemos, por una parte, componentes visuales que mostrarán los datos y nos dejarán cambiarlos y, por otra parte, componentes no visuales que obtienen los datos a mostrar. En medio tenemos a TDataSource, que es el conducto entre unos y otros, el que realiza el paso efectivo de la información. Podemos tener un control visual en que queramos mostrar varias columnas fijas de una determinada consulta. Bien, pues TField va a ser nuestro aliado. Definiremos lo que se llaman campos persistentes que podrán ser referenciados desde el componente visual para poder fijar las columnas a mostrar. Lo iremos viendo poco a poco.

Al abrirse un conjunto de datos, se genera un componente de campo para cada columna de datos de la tabla o consulta correspondiente. Delphi usa BDE para determinar el tipo correcto de componente de campo que se debe asignar a cada columna (los que hemos visto en la tabla). Este tipo, además, determina las propiedades del campo así como cómo debe mostrarse. Por ejemplo, si se da el caso de que para una columna se genera un TFloatField, entonces tendremos una propiedad que nos permitirá decirle el formato que queremos de visualización. Si es, por ejemplo, de dos decimales, este formato sería 0.00#. También podríamos fijar el número de dígitos a mostrar. Es sólo un ejemplo. Como veremos, los componentes de campo tienen propiedades comunes, y luego habrá otras específicas del tipo de campo que sea.

En modo de diseño, estos componentes se crean de forma dinámica si el correspondiente conjunto de datos tiene a True su propiedad Active. En tiempo de ejecución también se generan de forma dinámica. No obstante, es recomendado crear componentes de campo persistentes. Si, por ejemplo, tenemos un control TDBGrid que se basa en una estimación del número de campos, al añadir uno nuevo la aplicación podría responder de forma "extraña". Pero si el número de campos viene definido de antemano, estos problemas no se dan. Estos campos definidos "de antemano" son los que llamamos campos persistentes.

Entre otras ventajas, nos ofrecen las siguientes:

• Restricción de los campos del conjunto de datos a un subconjunto de las columnas disponibles en la base de datos correspondiente.

Page 12: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

• Definición de nuevos campos basándose en columnas de la tabla o consulta correspondiente al conjunto de datos.

• Definición de campos calculados. • Modificación de las propiedades de edición y visualización de los componentes de campo.

Con los componentes de campo persistentes tenemos garantizado que cada vez que se ejecute la aplicación se usarán y mostrarán las mismas columnas, en el mismo orden, incluso si ha cambiado la estructura física de la base de datos.

Cómo se crean

Para crearlos usaremos el editor de campos. Se inicia haciendo doble click sobre un componente de conjunto de datos (un descendiente de TDataSet). Presenta el siguiente aspecto:

También podemos acceder a él pulsando con el botón derecho del ratón sobre el componente de conjunto de datos y escogiendo la opción "Fields Editor" que se nos mostrará en el menú contextual. Notar que en la barra de título pone NombreForm.NombreComponenteConjuntoDeDatos.

Ahora tenemos que añadir aquí los campos que queramos que sean persistentes. Para ello, pulsamos con el botón derecho del ratón sobre el Editor de Campos, con lo que aparece el menú:

Page 13: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Entonces nos aparece una lista con todos los campos disponibles. Por ejemplo:

Los campos que nos aparecen son los correspondientes a la tabla seleccionada (si elegimos como componente conjunto de datos TTable) o a la consulta SQL (si elegimos TQuery). En este ejemplo, los campos son los resultantes de una consulta SQL en un componente de tipo TQuery. Si no termináis de verlo claro, en el ejemplo desarrollado de la agenda iremos viendo paso a paso qué es lo que debemos hacer y por qué.

Podemos crear nuevos campos o eliminar campos que hayamos puesto en la lista. Además, podemos ordenarlos como queramos, pinchando sobre el campo a cambiar de sitio y arrastrándolo a la nueva posición.

Para crear un campo nuevo (es decir, uno que no existe y por tanto no aparece en la lista de campos disponibles) pulsaremos con el botón derecho del ratón sobre el Editor de Campos y elegiremos la opción New Field... del menú contextual. Se nos abrirá una ventana como esta:

Page 14: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Vamos a estudiar únicamente los dos primeros tipos de campo, Data y Calculated. El tercer tipo, Lookup puede ser estudiado como ejercicio buscando en la ayuda de Delphi (si no lo he dicho ya, la ayuda de Delphi es muy completa y un buen lugar donde encontrar documentación de forma estructurada; además, es muy buena en general).

Definición de campos de datos

Imaginad que quereis cambiar, por el motivo que sea, el tipo de dato de un campo. Por ejemplo, teneis un campo de tipo TSmallIntField y queréis convertirlo en TIntegerField. Dado que no podemos cambiar el tipo de dato de forma directa, tendremos que usar un campo de este tipo para substituir al existente. Los pasos a seguir (en la ventana que hemos visto antes) son:

1. En primer lugar, hemos de asegurarnos que en el apartado Field type tenemos seleccionado Data.

2. Introducimos como nombre de campo el nombre de un campo persistente que exista (aquel del que queremos cambiar su tipo) en el campo Name. No hemos de introducir un nombre nuevo, sino uno que exista.

3. Elegir el nuevo tipo de dato seleccionándolo del combo Type. 4. Introducir el tamaño del campo en la opción Size si es necesario (en los tipos

TStringField, TBytesField y TVarBytesField).

Con todos los datos necesarios introducidos, ya podemos pulsar el botón OK. Ya tenemos definido nuestro campo; podremos cambiar sus propiedades en el Inspector de Objetos.

Definición de campos calculados

Un campo calculado nos muestra valores que el evento OnCalcFields del objeto conjunto de datos calcula en tiempo de ejecución. Para crear un campo calculado, seguiremos los siguientes pasos:

1. En primer lugar, nos aseguraremos de que en el apartado Field type tenemos seleccionado Calculated.

2. Elegimos el tipo de datos seleccionándolo del combo Type. 3. Le damos un nombre en el campo Name. Hemos de introducir un nombre nuevo, no el de

un campo que ya exista. 4. Introducir el tamaño en Size si es necesario.

Con todo esto, pulsamos OK y ya tenemos creado nuestro campo calculado. Ahora habrá que acudir al evento OnCalcFields del conjunto de datos correspondiente y escribir el código que asignará un valor a nuestro campo calculado.

Algunas propiedades de los componentes de campo

Propiedad Breve descripción

Aligment Nos permite alinear a la izquierda, derecha o centro el contenido del campo

Calculated Si es True nos indica que el contenido del campo es calculado en el evento onCalcFields del respectivo componente fuente de datos.

DisplayFormat Especifica el formato de los datos que se muestran (no disponible para todos los tipos de campo).

Page 15: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

DisplayWidth Ancho, en caracteres, de una columna de un TDBGrid que muestra el campo.

FieldName Especifica el nombre de la columna real de la tabla de la que el campo toma sus datos.

ReadOnly Si es True muestra los valores del campo, pero no permite editarlos.

Por ejemplo, un componente de campo de tipo TStringField no cuenta con la propiedad DisplayFormat.

Cuando hagáis vuestras propias aplicaciones os daréis cuenta de que si teneis un componente de conjunto de datos, llamémosle ConjuntoDeDatos, cuando creéis un campo persistente, por ejemplo CAMPO_PERSISTENTE, el objeto de campo que se crea recibe el identificador (el nombre para Delphi) ConjuntoDeDatosCAMPO_PERSISTENTE.

En una aplicación, podemos acceder al valor de una columna de la base de datos vía la propiedad Value del componente de campo correspondiente haciendo (por ejemplo):

EdNombreAlumno.Text := ConjuntoDeDatosNOMBRE_ALUMNO.Value;

Esto va bien para las cadenas, pero en otros tipos de campos será necesario hacer una conversión; para ello, el componente de campo dispone de unos métodos que nos permitirá hacer esta conversión. Vamos a ver una tabla en la que mostramos estas funciones de conversión y apuntamos el tipo de campo para el que dicha función va bien:

Tipo de campo / función

AsVariant AsString AsInteger AsFloat AsCurrency AsDateTime AsBoolean

TStringField OK OK OK OK OK OK OK

TIntegerField OK OK OK OK OK

TSmallIntField OK OK OK OK OK

TWordField OK OK OK OK OK

TFloatField OK OK OK OK

TCurrencyField OK OK OK

TBCDField OK OK OK

TDateTimeField OK OK OK OK OK

TDateField OK OK OK OK OK

TTimeField OK OK OK OK OK

TBooleanField OK OK OK

TBytesField OK OK

TVarBytesField OK OK

TBlobField OK OK

TMemoField OK OK

Page 16: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

TGraphicField OK OK

En caso de duda, usar AsVariant.

Vamos a hacer un pequeño inciso mostrando el resultado de algunas conversiones "especiales":

De String a Boolean: Únicamente convierte los valores "True" o "Yes" a True y los valores "False" o "No" a False. El resto genera excepciones. De Float a Integer: Redondea al entero más cercano. De DateTime a Float: Convierte fechas al número de días transcurridos desde el 31 de diciembre de 1899 y las horas a una fracción de 24 horas. De Boolean a String: Convierte True a "True" y False a "False".

En cualquier caso, una conversión no válida generará una excepción.

Varios ejemplos de uso:

EdNombre.Text := ConjuntoDeDatosNOMBRE_ALUMNO.AsString;

EdApellidos.Text := ConjuntoDeDatosAPELLIDOS_ALUMNO.AsString;

DTPickerFechaNac.Date := ConjuntoDeDatosFECHA_NAC_ALUMNO.AsDate;

Curso := ConjuntoDeDatosCURSO_ALUMNO.AsInteger;

ConjuntoDeDatosREPETIDOR_ALUMNO.AsBoolean := ChkBxRepetidor.Checked;

Otras formas de acceder a los campos:

También podemos acceder a los valores de los campos vía la propiedad Fields del objeto de conjunto de datos. Esta propiedad es de tipo array, por lo que necesitaremos saber la posición de un campo en el objeto conjunto de datos, siendo la primera columna la 0.

Por ejemplo: EdNombre.Text := ConjuntoDeDatos.Fields[2].AsString;

Esto sería si supiéramos que la tercera columna es la del nombre. Una alternativa que evita saber el orden correcto es usar el método FieldByName. Así, lo siguiente sería equivalente al ejemplo anterior:

EdNombre.Text := ConjuntoDeDatos.FieldByName('NOMBRE_ALUMNO').AsString;

Page 17: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

4.v. TTable

Gracias a este componente vamos a poder trabajar con los datos de cualquier fila y columna de una tabla concreta de la base de datos. Hemos de recordar que es un descendiente de TDataSet, así que todo lo dicho para TDataSet es válido para TTable.

Creación de un componente TTable

Siempre que queramos usar un componente TTable, los pasos fundamentales a seguir son estos:

1. Insertar el componente bien en un form bien en un Data Module y darle nombre en Name.

2. Definir en la propiedad DatabaseName la base de datos a la que estará ligado. 3. Definir en la propiedad TableName el nombre de la tabla a la que hará referencia. 4. Insertar un componente TDataSource en el form o en el Data Module y asignar a su

propiedad DataSet el nombre de la tabla (i.e., su propiedad Name).

Nota: DatabaseName puede ser un alias de BDE (aparecerá en un desplegable junto a esta propiedad) o bien una ruta completa. Es recomendable que sea un alias BDE porque si cambiamos la base de datos de sitio, sólo tendremos que cambiar en el alias este dato y no en todos los componentes que hagan referencia a ella. Es más recomendable aún que sea el nombre de algún componente TDatabase que exista en la aplicación, porque si cambiara el alias, únicamente habría que cambiarlo aquí.

Búsqueda de registros

Para buscar registros usaremos el método Locate ya visto en la explicación de TDataSet. Este método nos desplazará el cursor a la primera fila que coincide con el conjunto de criterios de búsqueda especificados. Un ejemplo puede ser:

Exito := Tabla.Locate('NOMBRE_ALUMNO', 'Juan', [loPartialKey]);

No hay mucho más que decir; el resto ya fue estudiado con TDataSet.

4.vi. TQuery

Este componente puede usarse con servidores de bases de datos remotos (en la version Client/Server Suite de Delphi), con bases de datos Paradox y dBase y con bases de datos compatibles con ODBC (como Access). Gracias a este componente vamos a poder acceder a varias tablas al mismo tiempo (vía un JOIN, claro está) o acceder de forma automática a un subconjunto de filas y columas de una tabla o tablas. Hemos de recordar que también es un descendiente de TDataSet, así que todo lo dicho para TDataSet es válido para TQuery.

Los criterios de selección son sentencias SQL y pueden ser estáticos (todos los parámetros de la sentencia se dan en tiempo de diseño) o dinámicos (algunos o todos los parámetros se dan en tiempo de ejecución).

Creación de un componente TQuery

Page 18: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Siempre que queramos usar un componente TQuery, los pasos fundamentales a seguir son estos:

1. Insertar en el componente bien en un form bien en un Data Module y darle nombre en Name.

2. Definir en la propiedad DatabaseName la base de datos a la que estará ligado. 3. Especificar la sentencia SQL en la propiedad SQL del componente y definir, si es

necesario, los parámetros de la misma en la propiedad Params. 4. Insertar un componente TDataSource en el form o en el Data Module y asignar a su

propiedad DataSet el nombre del query (i.e., su propiedad Name).

Consultas estáticas y dinámicas

Vamos a distinguirlas con un ejemplo. Supongamos que escribimos en la propiedad SQL (veremos a continuación cómo asignar valores a esta propiedad) el texto:

SELECT NOMBRE_ALUMNO FROM ALUMNOS WHERE NOTAMEDIA >= 5 AND EDAD = 15

Todos los valores para la cláusula WHERE vienen dados de forma explícita. Es una consulta estática, porque todos los valores vienen dados. Sin embargo, si en vez de eso escribiéramos:

SELECT NOMBRE_ALUMNO FROM ALUMNOS WHERE NOTAMEDIA >= 5 AND EDAD = :Edad

Vemos que aparece, en vez de un valor concreto para la edad, el valor :Edad. Eso quiere decir que en tiempo de ejecución, de acuerdo a los criterios que exija nuestro programa, asignaremos el valor adecuado de la edad según la situación. La forma de especificar estos nombres variables es anteponiendo dos puntos al nombre que le queramos dar. Luego, en el código, asignaremos el valor adecuado usando el método ParamByName del componente TQuery. Por ejemplo, para nuestro caso anterior podría quedar como sigue:

QAlumnos.ParamByName('Edad').AsInteger := 17;

Notar que el nombre del parámetro, en la llamada al método ParamByName, no lleva los dos puntos. Los dos puntos se ponen única y exclusivamente en la consulta, para distinguirlos de un valor estático y para saber que el identificador que va a continuación es el que se debe esperar en el programa.

Dónde especificar la consulta SQL

El componente TQuery tiene una propiedad llamada SQL que es donde se almacena la consulta a enviar a la base de datos. Podemos introducirla en tiempo de diseño pulsando sobre ella (se nos abre el editor de consultas) o en tiempo de ejecución, asignando a la propiedad Text de la propiedad SQL el texto completo de la consulta. Hay que señalar que esta propiedad SQL es de tipo TStringList, por ello contamos con una propiedad Text así como el resto de propiedades de estos objetos. En tiempo de ejecución, antes de asignar cualquier valor a la propiedad SQL la consulta debe estar cerrada. Esto lo conseguimos con el método Close que ya estudiamos en el objeto TDataSet. Así, un ejemplo de asignación en tiempo de ejecución puede ser:

Page 19: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

QAlumnos.Close;

QAlumnos.SQL.Text := 'SELECT NOMBRE_ALUMNO FROM ALUMNOS WHERE EDAD = 15';

Para más información, repasad TDataSet y consultad en la ayuda de Delphi.

5.i. TDBGrid

Este componente nos permite mostrar los registros de un TDataSet en forma tabular:

Para asociar este componente con el TDataSet del que obtiene los datos, hemos de poner en su propiedad DataSource el nombre del TDataSource asociado al TDataSet. Si la propiedad State del DBGrid toma el valor csDefault, el aspecto de los registros se determina a través de las propiedades de los campos incluidos en el TDataSet asociado al DBGrid.

Si el TDataSet asociado al DBGrid consta de componentes de campo persistentes (ya vimos cómo crearlos en el capítulo correspondiente), éstos permanecen aunque se cierre el TDataSet, de manera que las columnas asociadas a estos campos conservarán también sus propiedades aunque se cierre el TDataSet.

Podemos personalizar una DBGrid precisamente gracias a los objetos de campo persistentes. Así, en tiempo de diseño podremos dejar la DBGrid lista para que funcione exactamente como queremos que se muestre siempre. La forma de hacerlo es la siguiente. En primer lugar, nos vamos a la propiedad Columns y hacemos doble click sobre el botón de los puntos suspensivos. Entonces se nos abre una ventana como la siguiente:

Page 20: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Añadimos tantas columnas como queramos pulsando New. En principio, todas ellas no están asociadas a campos. Si pulsamos sobre una columna concreta, entonces en el Inspector de objetos nos muestra todas las propiedades de esa columna. El título de la columna puede tener su propio formato, independientemente del formato de la columna, pudiendo poner el título en negrita de color clNavy y la columna en cursiva de color clMaroon con fondo clInfoBk. Hay una propiedad que nos interesa mucho: FieldName. Si pulsamos, se nos abre un desplegable con todos los componentes de campo persistentes que hayan sido definidos para el TDataSet. Elegimos uno y ya está. Repetimos la operación con las restantes columnas, y ya tenemos el DBGrid completamente personalizado.

Ejemplo: Creación de una agenda

I. Diseño de la base de datos y las operaciones

Como ejemplo de uso de base de datos con Delphi, vamos a acudir al socorrido ejercicio de crearnos una agenda con los datos de nuestros conocidos. Para evitar simplificar demasiado con una única tabla en la base de datos, añadiremos un pequeño extra en este ejemplo: los contactos estarán agrupados por categorías, lo que nos da la siguiente estructura (podeis añadir/eliminar los campos que queráis):

Como vamos a usar Interbase, primero crearemos la base de datos bajo el usuario que queramos que sea su dueño. Si no sabeis dar de alta usuarios, o no sabeis crear la base de datos, id al anexo sobre Interbase. Yo le voy a dar el nombre Agenda.gdb.

A continuación tenemos que crear las tablas. Podemos hacerlo directamente en el IBConsole, o podemos crear un alias BDE y entonces crear las tablas con el SQL Explorer. Yo voy a hacerlo usando la segunda opción, porque de todas maneras, necesitaremos el alias BDE para cuando llegue el momento de diseñar la aplicación con Delphi. Recordad que en el anexo 1 encontrareis

la información necesaria para crear alias BDE y en el anexo 3 hay un pequeño manual de uso de SQL Explorer.

Elijáis el camino que elijáis, hay que crear las tablas, para lo cual vamos a introducir las siguientes sentencias SQL:

CREATE TABLE CATEGORIAS(

IDCATEGORIA INTEGER NOT NULL,

DESCRIPCION VARCHAR(255) NOT NULL,

PRIMARY KEY(IDCATEGORIA)

Page 21: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

);

CREATE GENERATOR GENIDCATEGORIA;

CREATE TABLE CONTACTOS(

IDCONTACTO INTEGER NOT NULL,

CATEGORIA INTEGER NOT NULL,

NOMBRE VARCHAR(100) NOT NULL,

APELLIDO1 VARCHAR(100) NOT NULL,

APELLIDO2 VARCHAR(100),

TELEFONO VARCHAR(20) NOT NULL,

MOVIL VARCHAR(20),

DIRECCION VARCHAR(255),

EMAIL1 VARCHAR(255),

EMAIL2 VARCHAR(255),

WEB1 VARCHAR(255),

WEB2 VARCHAR(255),

PRIMARY KEY(IDCONTACTO)

);

CREATE GENERATOR GENIDCONTACTO;

ALTER TABLE CONTACTOS

ADD FOREIGN KEY(CATEGORIA) REFERENCES CATEGORIAS(IDCATEGORIA);

Una vez introducidas, vamos a pensar en las operaciones básicas de gestión de estos datos: ás

inserción, edición, eliminación y búsqueda. Dejaremos claras cuáles serán las sentencias SQLque llevarán a cabo cada una de las operaciones, con lo que el desarrollo del programa será msencillo.

Gestión de la tabla CATEGORIAS

Comenzaremos con la tabla CATEGORIAS. Entre otras cosas, empezamos por ella porque ningún

esto de

campo de esta tabla depende de que exista un valor previo en otra tabla (cosa que no sucede enla tabla CONTACTOS). La clave primaria de esta tabla es IDCATEGORIA. Me gusta usar enteros como claves primarias porque son más simples. Si estamos seguros de que la combinación NOMBRE + APELLIDO1 + APELLIDO2 es única podríamos usarla como clave primaria, por ejemplo. Personalmente, prefiero que la clave primaria sea un entero independiente del rinformación. Es un criterio que he ido adoptando con el tiempo y que quizá vosotros veáis innecesario.

Page 22: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Para generar los valores sucesivos de la clave primaria utilizo un generador, GENIDCATEGORIA. Le pongo el prefijo GEN porque así lo identifico rápidamente como generador de los valores del campo que le sigue, IDCATEGORIA en este caso. Así que vamos ya a ver en qué consisten las operaciones básicas para esta tabla.

Inserción

Cuando se crea un generador, se inicializa automáticamente a 0. Así que, cuando insertemos un nuevo registro, debemos incrementar este valor, e insertarlo junto con la descripción de la categoría. Por tanto, las sentencias necesarias para insertar una nueva categoría serían:

INSERT INTO CATEGORIAS(

IDCATEGORIA

, DESCRIPCION

) VALUES (

GEN_ID(GENIDCATEGORIA, 1)

, :Descripcion

);

¿Qué es :Descripcion? Es un parámetro. Con eso quiero decir que la descripción a insertar será la que se nos dé en el programa.

Edición

El único campo que podemos editar es la descripción de la categoría, ya que el ID permanece invariable. Es un dato que al usuario no le sirve y que no le vamos a mostrar (el exceso de información siempre es peligroso), pero que nosotros vamos a tener disponible (veremos cómo cuando entremos en el desarrollo con Delphi, por ahora, asumimos que es así). Por tanto, actualizar el registro será tan sencillo como:

UPDATE CATEGORIAS

SET DESCRIPCION = :Descripcion

WHERE IDCATEGORIA = :Id

;

Eliminación

Por supuesto, tras asegurarnos de que el usuario realmente quiere eliminar ese registro, procederemos a realizar la operación de borrado:

DELETE FROM CATEGORIAS

WHERE IDCATEGORIA = :Id

Page 23: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Cuidado con la operación de borrar, si no pusiéramos la cláusula WHERE, se borraría la tabla completa.

Búsqueda

Únicamente va a tener sentido buscar una categoría por su nombre. Una sentencia sencilla que nos daría esto sería:

SELECT * FROM CATEGORIAS WHERE DESCRIPCION LIKE %LoQueBuscamos%

pero en lugar de eso, vamos a usar el método Locate de los descendientes de TDataSet. Cuando desarrollemos la aplicación veremos que es bastante sencillo :-)

Gestión de la tabla CONTACTOS

Al contrario que con la otra tabla, ésta sí que depende de otra tabla. En el dibujo se ha mostrado que hay una relación entre la tabla CONTACTOS y la tabla CATEGORIAS, y es que todo contacto pertenece a una categoría, por ello, antes de crear un contacto, debe existir la categoría a la que se le quiere asociar. Así, creadas las categorías necesarias, ya podemos dar de alta contactos.

Esta tabla también tiene como clave primaria un ID que será generado vía su generador asociado GENIDCONTACTO por medio de la función GEN_ID que ya hemos usado. He elegido los siguientes campos como obligatorios (especificado vía el NOT NULL que hay en la definición de algunos campos): IDCONTACTO, CATEGORIA, NOMBRE, APELLIDO1, TELEFONO. No he escogido APELLIDO2 porque no siempre sabemos el segundo apellido de una persona, y tampoco he escogido MOVIL porque un contacto cualquiera en principio no tiene por qué tener móvil, pero sí un TELEFONO, ya que la agenda se supone que es de teléfonos. Y la DIRECCION tampoco es obligatoria porque no tenemos por qué saber dónde vive. Lo mismo con el resto de campos. Son datos opcionales.

Inserción

Tras comprobar que los campos no nulos contienen valores, tendremos que escribir la siguiente consulta de inserción (los campos opcionales los represento entre []):

INSERT INTO CONTACTOS(

IDCONTACTO, CATEGORIA, NOMBRE, APELLIDO1[, APELLIDO2]

, TELEFONO[, MOVIL][, DIRECCION][, EMAIL1][, EMAIL2]

[, WEB1][, WEB2]

) VALUES (

GEN_ID(GENIDCONTACTO), :Categoria, :Nombre, :Apellido1[, :Apellido2]

, :Telefono[, :Movil][, :Direccion][, :Email1][, :Email2]

[, :Web1][, :Web2]

);

Page 24: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Es obvio que de alguna manera hemos de conocer el IDCATEGORIA correcto para asociarlo al campo CATEGORIA. No hay ningún problema: veremos cómo nos ayuda Delphi en este sentido.

Edición

La edición es semejante a la inserción y queda como ejercicio para el lector ;-)

No hay que preocuparse por cómo localizar los ID adecuados: Delphi sigue ayudándonos en este trabajo.

Eliminación

Previo asegurarse de si de verdad se va a eliminar el registro o no, la sentencia para eliminar el registro es análoga a la vista con las categorías y queda de nuevo como ejercicio ;-)

Búsqueda

Aquí podemos buscar por varios campos: por nombre, por apellido, por teléfono, ... al igual que con la tabla de CATEGORIAS, dejaremos el trabajo de la búsqueda al método Locate de los objetos descendientes de TDataSet ;-)

Seguimos en el próximo capítulo diseñando la parte gráfica de la aplicación. Estudiad todo lo que hemos pensado hasta el momento, en particular, la relación entre las tablas.

Ejemplo: Creación de una agenda

II.I Diseño del interface de la aplicación: Categorías

Una vez pensada la estructura de la base de datos así como las operaciones a realizar, vamos a diseñar el interface de la aplicación. Por variar un poco, vamos a crear un form con un TPageControl que contendrá dos TTabSheet: uno será la ficha de contactos y otro será la ficha de categorías:

Page 25: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Además, vamos a tener en un DataModule el componente TDatabase:

De las propiedades del TDatabase cabe destacar:

AliasName = Agenda

DatabaseName = DBGlobal

LoginPrompt = False

Name = DBGlobal

En el evento OnCreate del DataModule escribiremos este código:

procedure TDM.DataModuleCreate(Sender: TObject);

begin

DBGlobal.Params.Values['USERNAME'] := TuNombreDeUsuario;

DBGlobal.Params.Values['PASSWORD'] := TuContraseña;

try

DBGlobal.Open;

except

ShowMessage('Error abriendo la base de datos: cerrando aplicación');

Application.Terminate;

end;

end;

Para que reconozca ShowMessage debéis incluir la unit Dialogs, y para que reconozca al objeto Application debéis incluir la unit Forms. Además, hemos de colocar esta unit dentro del fichero del proyecto la primera de entre todos los forms que se crean. Así, lo primero que comprobamos al arrancar es que podemos conectar con la base de datos; si es así, pues ya se crean los forms y si no, se termina la aplicación.

Ahora que ya tenemos el DataModule con la base de datos, comenzaremos con la ficha de categorías por ser la más sencilla:

Page 26: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Por partes: la idea de funcionamiento (que aplicaremos también a los contactos) es que no vamos a crear categorías ni editarlas directamente sobre la DBGrid, sino que lo haremos aparte (concretamente en un panel). Los botones de gestión son de tipo TSpeedButton y los he llamado SBtnNuevo, SBtnEditar, SBtnEliminar, SBtnBuscar y SBtnOKBuscar. Cuando estemos editando datos en el panel, estos botones se deshabilitarán y al revés, cuando no estemos editando será el panel quien esté deshabilitado.

El panel inferior recibe el nombre de PnlEdicion, tiene Caption = '' y BevelOuter = bvLowered. Dentro contiene los componentes que usaremos para crear nuevas categorías o editar las existentes. Concretamente, tenemos el edit EdCategoria, el label LblTipoModif, que nos dirá si estamos creando una nueva categoría o editando una existente y los TBitBtn BtnAceptar y BtnCancelar.

Hemos colocado un DBGrid, DBGCategorias, un Table, TblCategorias y un DataSource, DSCategorias. El DataSource tiene por valor en su propiedad DataSet = TblCategorias. TblCategorias tiene en su propiedad DatabaseName = DBGlobal (debemos incluir la unit del DataModule para que esté disponible) y en su propiedad TableName = CATEGORIAS. El DBGrid tiene en su propiedad DataSource = DSCategorias y hemos definido una columna que mostrará el valor del campo persistente DESCRIPCION (he añadido los dos campos de la tabla a la lista de campos persistentes), por tanto, para esta columna, FieldName = DESCRIPCION. Además, al DBGrid le hemos quitado la posibilidad de que pueda editarse sobre él, el indicador de registro actual y que pueda cambiarse el tamaño de la columna.

Empezaremos definiendo qué debe suceder en los eventos OnShow y OnCreate. El código para estos eventos será ampliado cuando trabajemos con la pestaña de contactos.

procedure TFrmAgenda.FormCreate(Sender: TObject);

begin

HabilitarPanelEdicion(False);

end;

Page 27: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

procedure TFrmAgenda.FormShow(Sender: TObject); begin

TblCategorias.Close;

TblCategorias.Open;

end;

Por otro lado, definimos los siguientes procedimientos que nos serán útiles para realizar la gestión.

procedure TFrmAgenda.HabilitarBotonesGestion(Habilitar: Boolean);

begin

SBtnNuevo.Enabled := Habilitar;

SBtnEditar.Enabled := Habilitar;

SBtnEliminar.Enabled := Habilitar;

SBtnBuscar.Enabled := Habilitar;

end;

procedure TFrmAgenda.HabilitarPanelEdicion(Habilitar: Boolean);

var

i: Integer;

begin

PnlEdicion.Enabled := Habilitar;

for i := 0 to PnlEdicion.ControlCount - 1 do

PnlEdicion.Controls[i].Enabled := Habilitar;

VaciarCamposEdicion;

end;

procedure TFrmAgenda.CerrarEdicion;

begin

HabilitarPanelEdicion(False);

HabilitarBotonesGestion(True);

end;

procedure TFrmAgenda.VaciarCamposEdicion;

Page 28: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

begin EdCategoria.Text := '';

LblTipoModif.Caption := '';

end;

procedure TFrmAgenda.RefrescarCategorias(Id: Integer);

begin

TblCategorias.Close;

TblCategorias.Open;

if Id > 0 then

begin

TblCategorias.Locate('IDCATEGORIA', Id, []);

DBGCategorias.SetFocus;

end;

end;

Ahora valos bot

mos a definir los procedimientos de crear, editar y eliminar registros. La idea será que ones Nuevo y Editar pondrán los valores pertinentes en los campos y luego, al pulsar el

botón Aceptar, en función de una variable que llamaremos GestionNuevo: Boolean (privada dentro de la definición del form) sabremos si tenemos que hacer un INSERT o un UPDATE. El botón de Cancelar simplemente vaciará el edit del panel de edición y retornará el control a los botones de gestión. Para Eliminar primero pediremos confirmación.

Vamos primero a crear una nueva tabla en la base de datos, cuya definición será:

CREATE TABLE AUXILIAR(

COLUMNA INTEGER

);

La ucont

saremos para incrementar el valor del generador para los ids, tanto de categorías como de actos. Debemos insertar una única fila en esta tabla pudiendo contener cualquier valor

entero, por ejemplo, 1. Este detalle es muy importante; lo que haremos a continuación no funcionará si esta tabla no tiene una y sólo una fila con un valor numérico cualquiera. Recordad

que en la estructura de la base de datos se vio que hay un id en cada tabla que es único. Este ides el que nos permite distinguir un registro de otro. Además, incluimos en el form un objetoTQuery al que llamaremos QConsulta en cuya propiedad DatabaseName pondremos el valor DBGlobal. Este query nos servirá para realizar la consulta siguiente:

SELECT GEN_ID(GENIDCATEGORIA, 1) FROM AUXILIAR;

Page 29: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

que nos devolverá el siguiente valor a insertar del generador. Así, creamos la siguiente función:

function TFrmAgenda.GenID(Generador: String): Integer;

begin

QConsulta.Close;

QConsulta.SQL.Text := 'SELECT GEN_ID(' + Generador + ', 1) FROM AUXILIAR;';

QConsulta.Open;

Result := QConsulta.Fields[0].AsInteger;

end;

que usaremos en el lugar apropiado. Vamos a ver ahora cómo preparamos los controles según si os el botón Nuevo o el botón Editar: pulsam

procedure TFrmAgenda.SBtnNuevoClick(Sender: TObject);

begin

GestionNuevo := True;

HabilitarPanelEdicion(True);

HabilitarBotonesGestion(False);

LblTipoModif.Caption := 'Nueva categoría';

EdCategoria.SetFocus;

end;

procedure TFrmAgenda.SBtnEditarClick(Sender: TObject);

begin

if TblCategoriasIDCATEGORIA.AsInteger > 0 then

begin

GestionNuevo := False;

HabilitarPanelEdicion(True);

HabilitarBotonesGestion(False);

LblTipoModif.Caption := 'Editando categoría';

EdCategoria.Text := TblCategoriasDESCRIPCION.AsString;

end;

end;

Page 30: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Como podeis ver, en Editar la condición dice que si no hay ids (es decir, no hay registros, cuando se crea el primer registro su id es 1) entonces no hace nada, pero si hay ids,

preparo el edit del panel de edición con el valor del campo seleccionado. porque

Al pulsar el botón Eliminar ejecutaremos la siguiente acción:

procedure TFrmAgenda.SBtnEliminarClick(Sender: TObject);

var

Id: Integer;

begin

Id := TblCategoriasIDCATEGORIA.AsInteger;

if (Id > 0) and (

Application.MessageBox('¿Está seguro de que desea eliminar el registro seleccionado?',

'Eliminar registro',

MB_YESNO + MB_ICONQUESTION

) = IDYES

) then

begin

TblCategorias.Delete;

RefrescarCategorias(0);

end;

end;

Si pulsamos el botón Cancelar tendremos:

procedure TFrmAgenda.BtnCancelarClick(Sender: TObject);

begin

if Application.MessageBox('¿Está seguro de que desea cancelar la edición de los datos?',

'Confirmación de cancelación',

MB_YESNO + MB_ICONQUESTION

) = IDYES then

CerrarEdicion;

end;

Page 31: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Y si pulsamos Aceptar:

procedure TFrmAgenda.BtnAceptarClick(Sender: TObject);

var

Id: Integer;

begin

if GestionNuevo then

begin

Id := GenID('GENIDCATEGORIA');

TblCategorias.Close;

TblCategorias.Open;

TblCategorias.Insert;

TblCategoriasIDCATEGORIA.AsInteger := Id;

TblCategoriasDESCRIPCION.AsString := EdCategoria.Text;

TblCategorias.Post;

RefrescarCategorias(Id);

CerrarEdicion;

end

else { not GestionNuevo -> Editando existente }

begin

Id := TblCategoriasIDCATEGORIA.AsInteger;

TblCategorias.Edit;

TblCategoriasDESCRIPCION.AsString := EdCategoria.Text;

TblCategorias.Post;

RefrescarCategorias(Id);

CerrarEdicion;

end;

end;

Page 32: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Aquí tenemos un ejemplo de la aplicación funcionando:

tratamos la búsqueda. Para la búsqueda, en primer lugar pondremos, en tiedad Enabled del botón OK a False. Después, al botón buscar le asig

y GroupIndex = 1. A continuación, escribimos el siguiente cód:

Por último, empo de diseño, la propi naremos AllowAllUp = True botón Buscar

igo para el

procedure TFrmAgenda.SBtnBuscarClick(Sender: TObject);

begin

SBtnNuevo.Enabled := BtnBuscarPulsadoCategorias;

SBtnEditar.Enabled := BtnBuscarPulsadoCategorias;

SBtnEliminar.Enabled := BtnBuscarPulsadoCategorias;

if not BtnBuscarPulsadoCategorias then

begin

EdBuscar.Enabled := True;

SBtnBuscar.Down := True;

SBtnOKBuscar.Enabled := True;

BtnBuscarPulsadoCategorias := True;

EdBuscar.SetFocus;

end

else

begin

EdBuscar.Text := '';

Page 33: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

SBtnBuscar.Down := False; EdBuscar.Enabled := False;

SBtnOKBuscar.Enabled := False;

BtnBuscarPulsadoCategorias := False;

end;

end;

Y para el botón OK escribimos el siguiente:

procedure TFrmAgenda.SBtnOKBuscarClick(Sender: TObject);

begin

if BtnBuscarPulsadoCategorias then

begin

if EdBuscar.Text = '' then

begin

ShowMessage('Debe escribir un texto para realizar la búsqueda');

EdBuscar.SetFocus;

end

else

begin

if TblCategorias.Locate('DESCRIPCION', EdBuscar.Text, [loCaseInsensitive, loPartialKey]) then

DBGCategorias.SetFocus

else

ShowMessage('No se encuentra ninguna categoría con esa descripción');

SBtnBuscar.Down := False;

EdBuscar.Text := '';

EdBuscar.Enabled := False;

SBtnOKBuscar.Enabled := False;

BtnBuscarPulsadoCategorias := False;

SBtnNuevo.Enabled := True;

SBtnEditar.Enabled := True;

SBtnEliminar.Enabled := True;

end;

Page 34: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

end; end;

Con lo que ya tenemos funcionando toda la parte de definición de categorías para nuestra agenda. En el capítulo siguiente, daremos cuerpo a la parte de contactos. Tened en cuenta que, visto lo que hemos visto aquí con tanto detalle, me saltaré algunas partes dejándoos a vosotros

eis un poco y las desarrolleis. Vereis como no es tan difícil.

cio

Ampliar el programa no permitiendo repetir categorías. Sugerencia: usar un SELECT sobre la

rtado vamos a ver los aspectos más básicos que necesitaremos configurar para poder acceder a nuestras bases de datos desde un programa Delphi. Arrancaremos el programa

lo

que pens

Ejerci

tabla AUXILIAR con la función EXISTS de SQL.

A1. Borland Database Engine

En este apa

de configuración de BDE accediendo a la ruta Panel de control -> BDE Administrator, conque se nos abrirá la ventana:

A la izquierda, en la pestaña Databases tenemos una lista con todos los alias que hayamos dado de alta. A la derecha no tenemos nada porque no hemos seleccionado alias alguno. Si pulsamos sobre un alias cualquiera, la parte derecha cambia y se muestra la configuración del alias, que podremos editar.

Page 35: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Vamos a comenzar creando un nuevo al s podremos hacer referencia a la base de datos desde D mos New... y a continuación escogemos el

ias. Con este nuevo aliaelphi. Para ello, pulsamos en el menú Object, elegi

tipo de base de datos de la lista que nos ofrece:

Trataremos con Interbase por ser un gestor que da suficiente potencia a lato y con buena calidad. Para ello, elegimos como nombre de dri

nuevo alias, con un nombre temporal nuestro) y con un indicador de que es necesario aplida:

base de datos, así como que es gratui ver INTRBASE. Hecho esto, veremos aparecer el (a espera de que nosotros pongamos el icar los cambios para dar la tarea por conclu

alla nos han aparecido las opciones por defecto parA la derecha de la pant a este nuevo alias:

Comenzaremos cambiando n el lugar de INTRBASE1, que es el que sugiere por defecto:

el nombre del alias, escribiendo DBPrueba e

Ahora vamos a centrarnos en las opciones más importantes que nos ofrece:

BLOB SIZE

Page 36: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Tamaño máxi insertarlo o recuperarlo de la que tenga un tamaño entre 32 y 1000 Kb

BLOBS TO CACHE Es el número máxi a vez en el ordenador cliente. No es conveni valor suele variar entre 64 y 65536.

LANGDRIVER Es el ju e dejar en blanco el campo.

MAX ROWS Es el número de fi ta. Si dejamos el valor -1 (reco mplan la condición de la consulta.

OPEN MODE Es el modo de apertura de l es formas de abrirla:

READ ONLY que no podremos

escrib

READ/WRITE Es la izar cualqui

gurado el acceso a la red, se escribirá de una de las siguientes formas:

Acceso local

En red con TCP/IP bajo

n TCP/IP bajo NombreMaquina:Ruta/Fichero.gdb

En r

USER NAre de usuario que se tomará por defecto al establecer la conexión con el servidor.

endable usar un nuevo usuario. Si no queremos que el sistema nos muestre

ombre del usuario cuando vayamos a establecer la conexión, lo dejaremos en blanco.

NAME. Usaremos una base de datos local, así que en simplemente escribiremos la ruta mos Prueba. En el apartado de Interbase veremos cómo dar de alta usuarios.

lsando el botón de "Aplicar"

mo en Kb que podrá tener un campo de tipo Blob al base de datos. Es recomendable

mo de blobs que pueden estar almacenados a lente que sea una número muy grande. El

ego de caracteres usado por la base de datos. Es recomendabl

las que devolverá la base de datos al hacer una consulmendado), nos devolverá todas las filas que cu

a base de datos. Sólo hay dos posibl

La base de datos se abre en modo lectura, con loir registros ni actualizarlos

opción por defecto. Teniendo esta opción, podremos realer tipo de operación sobre la base de datos

SERVER NAMENombre del servidor y ruta dentro del mismo vía el que se accede a la base de datos. Depende de cómo esté confi

Unidad:\Ruta\Fichero.gdb

Windows NombreMaquina:Unidad:\Ruta\Fichero.gdb

En red coUnix

ed con NETBEUI NombreServidor\\Unidad:\Ruta\Fichero.gdb

La extensión gdb es propia de los ficheros de Interbase.

ME NombCuando instalamos Interbase hay un usuario administrador por defecto, que es SYSDBA.Será recomel nEsto no querrá decir que no haya un usuario definido, sólo que no se verá qué nombre es.

Dejaremos todas las opciones por defecto para nuestro alias, salvo dos, SERVER NAME y USER SERVER NAME

encuentra el fichero. Por otra parte, como nombre de usuario pondre en la que se

Finalizamos pupartir de

, con lo que ya tenemos dado de alta el alias. A

DBPrueb

Si in irla pulsando e del alias, el programa nos dará un error informándonos de que e datos. Hemos creado el alias,

ahora podremos acceder a la base de datos desde Delphi simplemente refiriéndonos aa.

tentamos abr el + que hay al lado del nombr no puede acceder a la base d

Page 37: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

pero momento hemos creado físicamente la base de datos. En el capítulo de Interbase veremos cómo hacerlo.

A2. InterBase

Vamos a crear una base de datos Interbase. Para ello, abriremos el programa IBConsole, que se instala de forma automática (en los sistemas Windows NT y Windows 2000 se carga de forma automática), tendremos que

sotros de forma manual.

Recién idefinido masterk

Sobre la opción InterBase Servers pulsaremos con el botón derecho del ratón, con lo que se nos despliega el siguiente menú:

en ningún

junto con Interbase. Si el servicio de Interbase no se carga

arrancarlo no

nstalado el servidor de Interbase, al abrir el programa IBConsole no tendremos s servidores ni más usuarios que el usuario por defecto, SYSDBA, cuya clave de acceso esey.

Elegimos y accedemos a la pantalla que nos permite dar de alta el servidor local. un servidor local, no tendremos accesible la opción de dar de alta un

servidor remoto. En la pantalla que vemos:

Register...Hasta que no registremos

Page 38: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

rellenaremos los campos USER NAME res respectivos SYSDBA y masterkey (muy importante que la clave esté en mi botón OK y ya tenemos registrado el servidor local, a. Ahora podemos crear bases de datos en el servidor local, regi mportante si queremos acceder a ellas, pues sólo veremos las regi ores remotos (uno o varios).

Comenzaremos viendo cómo crear un nuevo usuari strado el servidor local, el aspecto de la pantalla principal ones:

y PASSWORD con los valonúsculas). Pulsamos el

que será nuestra propia máquinstrar bases de datos existentes (i

stradas) y registrar servid

o. Cuando hemos regi cambia un poco, mostrándonos estas opci

Si pulsamos sobre Users . Para crear uno nuevo, accedemos a la opción nos muestra entonces la ventana:

veremos únicamente al usuario SYSDBAUser security del menú Server. Se

en la que pulsaremos el botón New, con lo que se vacían los campos USER NAME y PASSWORD para que los rellenemos con los del nuevo usuario. Una vez introducidos los datos, pulsamos el botón Apply, con lo que ya tenemos dado de alta el usuario.

Ahora vamos a crear la base de datos. Lo primero de todo será hacer login como el usuario que queramos que tenga acceso a la base de datos, así que si estamos como SYSDBA y queremos que el usuario sea PEPE, tendremos que "desregistrarnos" como SYSDBA y registrarnos como PEPE en el servidor Local Server.

Page 39: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Estando en mos Create database...

Local Server, subopción Databases, pulsamos el botón derecho y elegi, con lo que se nos abre la ventana:

Rellenamos el nombre dar a la base de datos, y pulsamos OK

del fichero (ruta completa) y el alias que le vamos a:

El directorio debe existir, o de lo contrario se nos mostrará un error de escritura. Creada la base de datos, InterBase nos muestra la pantalla:

Page 40: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Podemos crear tablas, dar del alta registros, en SQL Explorer, del propio Delphi, que es el mente, se parecen tanto y son tan intuitivos, que no vale la pena repetir lo mismo.

para poder acceder a la base de datos desde Delphi, tenemos que haber creado un alias para ella, bien sea desde BDE Administrator o desde SQL Explorer. Crear un alias desde InterBase no quie hi sólo lo reconocerá si ha sido creado desde sus herrami

A3. SQL Explorer

El programa SQL Explorer nos permite examinar bases de datos cuyo alias tengamos dado de alta con mucha comodidad: separa los elementos de la base de datos en categorías: dominios,

ente situándonos sobre el campo a modificar, actualizar valores de los generadores, editar procedimientos... y también nos permite introducir sentencias SQL con las que podremos crear tablas, modificarlas, crear procedimientos, generadores, etc. En última instancia, si se nos ha olvidado crear el alias a la base de datos con el programa BDE Administrator, con SQL Explorer podremos hacerlo siguiendo exactamente los mismos pasos.

Para mostrar el manejo básico de este programa, trabajaremos con un ejemplo muy sencillo (y típico): supongamos que tenemos una librería, y únicamente necesitamos una base de datos formada por una tabla con los siguientes datos:

• Código Libro • Título • Autor • Tema • Editorial • Precio • Unidades • ISBN

Ya podemos empezar a trastear con nuestra recién creada base de datos. etc. Para ello, podemos emplear la utilidad ISQL, o bi

que describimos brevemente en el anexo siguiente. Real

No hay que olvidar que

re decir que Delphi lo vaya a reconocer. Delpentas.

tablas, generadores, funciones, procedimientos... Podremos modificar registros de las tablas sin necesidad de acudir a sentencias SQL, simplem

Page 41: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Lo prim os campos de l dades" van a ser de ti

Ejecutamos el s de esta que

a siguiente

ero que tenemos que hacer es pensar de qué tipo de dato va a ser cada uno de la tabla. Parece lógico pensar que los campos "Código Libro","Precio", "Uni

po numérico, mientras que los demás serán de tipo carácter.

programa SQL Explorer, que viene con Delphi, para dar de alta el aliabase de datos. En el anexo anterior vimos cómo crear la base de datos desde InterBase, asíahora ya podemos abrirla con SQL Explorer y crear tablas. Al ejecutarlo, se nos muestra l

pantalla:

Si pulsamos en el iconito del + que hay a la izquierda de nuestra base de datos:

se nos abre una ventana en la que tenemos que introducir el nombre de usuario y la contraseña del usuario activo en Interbase cuando creamos la base de datos:

Page 42: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Entrados estos datos correctamente, se despliega una lista con varias entradas:

también veremos que el botón izquierdo de abrir se ha pulsado automátierta, y podemos trabajar con ella. Podríamos haber conseguido l

éndonos sobre ella y pulsando ese botón. Luego la cerraremos con la opción CLOSEen "despulsando" el botón de abrir. Al abrirla, aparece en la ventana de la

apa: ENTER SQL. Podemos distinguir una base de datos abierta de una que no l icono que la acompaña está rodeada por un cuadrado de colo

Si nos ponemos sobre ella, veremos esto:

Además, camente: la base de datos está abi o mismo poni del menú OBJECT, o bi derecha una nueva sol o está porque el r verde, como se ve en el dibujo.

Como hemos creado la base de datos, pero no le hemos añadido tablas, comprobamos pulsando el icono + que esa entrada de la lista está vacía:

Así que la primera sentencia que vamos a introducir será la de la creación de la tabla. Para ello, escribimos lo siguiente:

CREATE TABLE LIBROS(

CODIGO INTEGER NOT NULL,

TITULO VARCHAR(255) NOT NULL,

AUTOR VARCHAR(100),

TEMA VARCHAR(100),

EDITORIAL VARCHAR(50),

Page 43: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

PRECIO INTEGER, UNIDADES INTEGER,

ISBN VARCHAR(25),

PRIMARY KEY (CODIGO)

);

y pulsamos sobre el botón de ejecutar. Tables sí que contiene una entrada: la tabla que acabamos de crear. Si a propia tabla, nos aparecen más opciones:

Podemos ver que ahora nos ponemos sobre l

De aquí, la pestaña que más nos in DATA. ENTER SQL ya la conocemos, y TEXT únicamente nos muestra la definición de la tabla. Útil por si olvidamos de

teresa en este momento es

qué tipo eran los campos. Si nos ponemos sobre DATA, nos aparece esto:

Page 44: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

ores a los campos directamente, sin necesidad de escribir sentencia parte superior derecha de la ventana ha salido una barra de botones que

nuación casi completamente (únicamente nos dejaremos dos de elbarra de botones nos va a servir para movernos entre registros, añadir registros, borrar

stros, actualizarlos...

n embargo, como estamos aprendiendo, vamos a ver primero un ejemplo de insercia instrucción INSERT de SQL. Para ello, empezamos por situarnos en la introducimos lo siguiente:

CODIGO, TITULO, AUTOR, TEMA, EDITORIAL, PRECIO, UNIDADES, ISBN

, 'Manual de Matematicas'

Aquí podemos dar val as SQL. Además, en lexplicamos a conti los). Esta

regi

Si ón de un registro con l pestaña ENTER SQL, e

INSERT INTO LIBROS(

) VALUES (

1

, 'I. Bronshteim'

, 'Matematicas'

, 'Mir'

, 1500

, 10

, '5-38588-5'

);

como se puede ver en el gráfico:

Page 45: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

Al pulsar sobre el barra de estado pone "1 rows were affected"hemos actualizado lo s botones de la parte superior derecha:

botón de ejecutar la instrucción, veremos que en la. Si nos vamos a la solapa DATA, aún no veremos nada: eso es porque no

s datos. Vamos a explicar ahora para qué sirven lo

sar el botón de actualizar datos para poder ver el resultado de la Así que tendremos que pulinserción:

aben todos los datos, con ayuda de las barras de desplazamiento podremos ir do que los valores han sido introducidos correctamente.

do esto, podemos seguir introduciendo datos para practicar con SQL, o directamente en la DATA. Además, podemos también investigar qué sucede con las sentencias UPDATE,

DELETE y SELECT. Como último ejemplo de este capítulo, vamos a ver el resultado de una dos registros más que podeis insertar a vuestro gusto como

SELECT * FROM LIBROS WHERE PRECIO > 1000;

Como no ccomproban

Con tosolapa

SELECT (previamente, he insertadoejercicio ;-) ). Escribimos lo siguiente:

Page 46: Bases de datos con Delphi - · PDF fileBases de datos con Delphi 1. Introducción Cuando queramos desarrollar una aplicación con Delphi que dé acceso a una base de datos, no debemos

ar sobre el botón que ejecuta la instrucción, obtenemos: Y al puls

legar al campo PRECIO: Al desplazarnos hasta l

observamos que lo

Usar este programa p s bastante sencillo. Normalmente haremos todo este trabajo en la pestaña ENTER SQL. Además, cada elemento tiene

datos rs se han definido sobre

ella (entre otros). Los procedimientos almacenados nos dirían cuáles son los parámetros de

s campos han sido devueltos correctamente.

ara crear generadores, triggers, procedimientos, etc. e

siempre la opción de desplegar datos sobre él. Por ejemplo, una tabla concreta despliega sobre quién es la clave primaria, qué claves ajenas tiene o qué trigge

entrada, las vistas sus columnas... Es un programa muy intuitivo y agradable de manejar, así que el resto del aprendizaje os lo dejo a vosotros ;-)