Que es HyperBase Suite?
HyperBase Suite es un
conjunto de herramientas que permiten implementar de forma fácil, rápida y
segura la capa de lógica de negocio en las aplicaciones corporativas. Es un middleware de Datos, Procedimientos,
Reportes y Gráficos entre otros.
HyperBase está diseñado para
trabajar sobre redes de públicas de internet, lo cual exige que implemente
opciones de recuperación de conexiones de forma automática, redundancia de
conectividad, escalabilidad y los más importante conexiones seguras, por eso
HyperBase maneja todas sus conexiones bajo protocolos SSL además de
encriptación con llave privada y compresión de datos.
Que son los componentes HBX?
Los componentes HBX
representan las herramientas de conexión al HyperBase en sus dos versiones, en
la versión Local y versión Server. en
otras palabras podría decirse que los componentes HBX permiten la conexión a
las bases de datos, ejecutar consultas y procedimientos almacenados sobre las
bases de datos y en el caso del server, permite ejecutar consultas y
procedimientos almacenados sobre HyperBase.
Opcionalmente en el caso que
estén disponibles los módulos de Report Server y Chart Server, permiten la ejecución de de reportes y
gráficos estadísticos en forma remota al servidor.
Para que plataformas están
disponibles los Componentes HBX?
En modo Local solo están
disponibles para Windows, desde las versiones XP en adelante, con conexión al
servidor, existen versiones para Android, IOS (IPhone, IPad), MAC OSX y
Windows.
Que lenguajes soportan los HBX?
Hay conectores nativos para
PHP, Java, C++ y Delphi sobre Windows, también existen drivers ActiveX y ODBC
en Windows que permite la conexión desde cualquier lenguaje que soporte este
tipo de conexiones, por otro lado Android, IOS y OSX solo están soportados en
lenguaje Delphi y C++ de Embarcadero RadStudio XE5.
A que bases de datos permiten
conectarse los componentes HBX?
Permite las conexiones
nativas a Oracle, MS SQL Server, IBM DB2, Postgres, Interbase, FireBird, MySQL,
Informix, SyBase ASA, SyBase ASE y otros por medio de ODBC.
Que se requiere para la
distribución de la aplicación final?
Los componentes HBX son
Royalty Free, eso quiere decir que puede distribuir los componentes como parte
de su aplicación sin ningún costo para el cliente final. Sin embargo es posible
que sea necesario instalar software adicional cliente que es distribuido con el
motor de la base de datos. En el caso
particular de Postgres Sql, será necesario adquirir el driver correspondiente.
Existen dos modos de
utilizar los componentes HBX, el modo Local y el Modo Server, El modo local
funciona como una aplicación Cliente/Servidor tradicional, mientras que en modo
server se convierte en una aplicación N-Tiers (Multiples capas), eso permite
construir o partir de aplicaciones Cliente/Servidor tradicionales y llevarlas a
aplicaciones de 3-Capas de una forma fácil e intuitiva.
En modo Local los conectores
HBX requieren la instalación en el equipo cliente de los drivers para su
conexión y dependiendo del motor de base de datos, podría requerir la
instalación del software del cliente de la base de datos en cada una de las
máquinas donde se ejecutará el programa.
En modo Remoto y
aplicaciones desarrolladas en lenguajes diferentes a Delphi XE5, se requiere de
solamente un archivo .dll que realiza la conexión con el servidor HyperBase.
Para las aplicaciones
desarrolladas en Delphi XE5 y posteriores,
la conexión con el servidor HyperBase no requiere ningún tipo de archivo
adicional, así que bastará con el ejecutable para su ejecución de forma remota.
Descripción básica de uso en los diferentes lenguajes, PHP,
Java, C y Delphi.
Realizaremos una breve
descripción del funcionamiento de los componentes HBX en los diferentes
lenguajes.
PHP.
Ejercicio realizado en PHP, realiza una consulta a la
tabla ciudades, guarda el contenido en formato XML en una carpeta local y luego
muestra el resultado de la consulta en una página HTML.
<?php
include '\http\www\sig\hbclasses.php';
$HbConn = new THbConn("","","127.0.0.1",211,"Login","Password");
$HbConn->DoConnect();
$Query
= $HbConn->NewQuery("DbScript","Select * from
ciudades",-1);
$Query->Open();
$Query->SaveToFile("c:/temp/queryciudades.xml");
//echo
$Query->GetXmlData();
$Query->First();
while
($Query->Eof() != TRUE)
{
print($Query->FieldValue("NOM_CIUDAD"));
print("<br>");
$Query->Next();
}
$HbConn->DoDisconnect();
?>
JAVA.
Ejercicio
realizado en Java, realiza una consulta a la tabla ciudades y muestra el
resultado de la consulta en una página HTML.
public static void main(String[] args) {
JHBConnection con =
new JHBConnection("","","127.0.0.1",211,"Login",
"Password");
con.DoConnect();
JHBQuery query =
con.NewQuery("DbScrip", "select * from ciudades ",-1);
query.Open();
int n =
query.FieldCount();
//System.out.println(n);
for (int i = 0; i
< n; i++) {
System.out.println(query.GetField(i).getFFieldName()+"="+
query.FieldByName("nom_ciudad").GetAsString());
}
query.Close();
query.Destroy();
new JNIFrame(){
public void
cerrando(JHBConnection con){
System.out.println("cerrando2...");
if(con!=null
&& con.GetConnected())
con.Destroy();
}
};
}
}
C Estandar.
Ejercicio realizado en C Estandar, no se utiliza la
Programación orientada a objetos ni ninguna de las características modernas del
lenguajes.
void main(void)
{
int
DbHandle;
int
TableHandle;
int I;
DbHandle = RHBNewConnection("", "");
I =
RHBOpenConnection(DbHandle, "127.0.0.1", 211,"Login","Password");
TableHandle = RHBNewQuery(DbHandle, "DbScript", "Select *
from Ciudades", -1);
RHBOpen(TableHandle);
RHBSaveToFile(TableHandle, "c:\\temp\\queryciudades.xml");
RHBFreeQuery(TableHandle);
RHBCloseConnection(DbHandle);
printf("Fin\n");
}
Delphi consola.
Ejercicio
realizado en Delphi compatible desde Delphi 7 hasta Delphi XE5, en sistemas
operativos Windows, Mac, Android y el IOS.
Var
DbConn : THBXConnection;
Query: THbQuery;
begin
DbConn := THBXConnection.Create(
'serverhost',
'211', 'login', 'password');
DbConn.ConnectionType := TcxNative;
DbConn.Open;
Query := DbConn.NewQuery('DbScript','select * from
ciudades');
Query.Open;
Query.SaveToFile(FilePath+'queryciudades.xml',
dfXMLUTF8);
While
not Query.Eof do
Begin
//La siguiente instrucción cambia de
acuerdo a la plataforma
//Dado que Writeln es de tipo consola
Writeln(Query.Fields[0].FieldName+' :
'+Query.Fields[0].AsString);
Query.Next;
End;
Query.Close;
DbConn.Close;
end;
Delphi Visual.
Ejercicio realizado en Delphi compatible desde Delphi
7 hasta Delphi XE5, en sistemas operativos Windows, Mac.
El
código fuente sería el siguiente:
Delphi IPhone, IPad o Android.
Ejercicio realizado en Delphi XE5 para Android o IOS,
en el uso de dispositivos móviles es indispensable el uso del servidor
HyperBase, no es posible trabajar en modo Local.
Esta es una lista de los
componentes HBX y los comparamos con los BDE que son los más conocidos de
Delphi.
Componentes HBX
|
|
|
THbxConnection:
Este componente realiza la
conexión a un servidor ya sea remoto o local, En el caso de conexión Local,
es el mismo componente quien administra las diferentes conexiones a bases de
datos a las cuales se tiene acceso. si
es conexión Remota, será el servidor HyperBase quien administrará las
conexiones a las bases de datos.
|
|
|
|
|
|
|
THbQuery:
El componente de Query
permite cumplir una gran variedad de funciones, desde simular una tabla en
memoria, representar una tabla de la base de datos, un query con la propiedad
"Request live" activada, un store procedure y los sqlUpdate query
entre otras cosas..
|
|
|
|
|
|
|
|
THBClientCallBacks:
Este componentes solo está
disponible a partir de la versión XE2 de Delphi y permite la comunicación de
mensajes entre las aplicaciones cuando trabajan con el servidor HyperBase. Implementa un Middleware de mensajes entre
los clientes del HyperBase,
permitiendo el envío de mensajes o comandos P2P y Broadcast.
Nota: Solo funciona en
modo Server y versiones Delphi XE2 en adelante
|
|
|
|
|
THBServerList:
Permite la implementación
del LoadBalance desde el Cliente, Este componentes administra una lista de
servidores de los cuales el HbxConnection seleccionará para conectarse si
está habilitada la opción de LoadBalance, en caso de no estar disponible el
servidor, lo marcará como no disponible e intentará con el siguiente en la
lista
Nota: Solo funciona en
modo Server Server y versiones Delphi XE2 en adelante
|
|
Configuración de conexiones en modo Local
Es posible utilizar las
conexiones a bases de datos en tiempo de diseño dentro del Delphi, sin embargo para la instalación de los
clientes, se recomienda realizar la configuración dinámicamente dentro del
programa.
Las conexiones locales están
disponibles solo para Windows y desde Delphi 7 en adelante, para MAC OSX, IOS o Android solo está
disponible la versión de conexión remota al HyperBase Server.
La herramienta para la
configuración de las conexiones en Windows es el DbAdmin, en ella es posible
crear conexiones a las bases de datos comerciales más conocidas o por medio de
ODBC a otras conexiones a Bases de Datos.
Es posible Administrar
conexiones a bases de datos sobre la LAN, que serán utilizadas por las
aplicaciones tanto en tiempo de ejecución utilizando el componente
THBXConnection.
Las conexiones del HyperBase
en modo Local LAN utilizan el mismo sistema de conexión del DBExpress, esto
quiere decir que son conexiones nativas a las bases de datos, y tienen
adicionalmente un conector ODBC que permite realizar conexiones por medio de esta
tecnología.
Nota: Es
necesario iniciar el DbAdmin con permisos de Administrador, ya que requiere
almacenar información en el Registry del systema. Esta opción se realiza así para evitar
configuraciones no autorizadas.
Cómo Configurar una base de datos en tiempo de ejecución
Para implementar la
funcionalidad de conexión Local en HyperBase, se distribuye con los componentes
HBX un Mini Servidor de HyperBase, que implementa las funcionalidades básicas
del servidor y que permite mantener la compatibilidad en todas las versiones de
Delphi.
En los
siguientes diagramas se muestra la arquitectura de los dos modelos, en el modelo Server las conexiones a las
bases de datos y los permisos de acceso se le asignan directamente al servidor
HBServer, por medio de una herramienta
llamada HB SqlTools, en este modelo no
es posible crear una conexión a una base de datos en tiempo de ejecución. Solamente el administrador podrá crear nuevas
conexiones y con los permisos adecuados sobre el servidor.
En el modelo local la conexión se realiza en forma directa y
el servidor local se ejecuta en el mismo equipo con la aplicación y se
distribuye como un archivo .dll con el nombre de HBLConn.dll, el cual debe ser
distribuido junto con el ejecutable.
En este modelo Local, primero es necesario realizar la
conexión con el servidor HBServer Local y luego se le indica la acción que se
quiere realizar, en el caso que nos ocupa, adicionar una nueva conexión a la
base de datos.
En este ejemplo primero es necesario
conectarse al servidor local, para ello se instancia la propiedad DbConn.ConnectionType := TcxLocal, de
esta manera el conector utilizará el modelo Cliente/Servidor local, como la
conexión se realiza en el mismo computador, no se requiere especificar ningún
otro parámetro como Host, Login o Password.
Una vez realizada la conexión con el
servidor, se procede a adicionar un alias de la base de datos, junto con los
parámetros de conexión, esta función
sobrescribe cualquier conexión previa, incluyendo las definidas en el DBAdmin.
Esta conexión solo estará disponible en
tiempo de ejecución, si desea establecer una conexión en tiempo de diseño, debe
realizarse por medio de la herramienta DBAdmin, descrita en la sección
anterior.
Var
DbConn:
THBXConnection;
Query:
THbQuery;
DbParams : TStringList;
begin
DbParams := TStringList.Create;
DbParams.Add('HBDriverType=DBX');
DbParams.Add('RoleName=RoleName');
DbParams.Add('User_Name=sysdba');
DbParams.Add('Password=masterkey');
DbParams.Add('ServerCharSet=');
DbParams.Add('SQLDialect=3');
DbParams.Add('ErrorResourceFile=');
DbParams.Add('LocaleCode=0000');
DbParams.Add('BlobSize=-1');
DbParams.Add('CommitRetain=False');
DbParams.Add('WaitOnLocks=True');
DbParams.Add('IsolationLevel=ReadCommitted');
DbParams.Add('Trim Char=False');
DbParams.Add('GetDriverFunc=getSQLDriverINTERBASE');
DbParams.Add('LibraryName=dbxint.dll');
DbParams.Add('VendorLib=GDS32.DLL');
DbParams.Add('Database=\MYDATABASE.GDB');
DbParams.Add('DriverName=InterBase');
DbConn
:= THBXConnection.Create(Self);
DbConn.ConnectionType := TcxLocal;
DbConn.AddDataBase('DbName', DbParams);
DbConn.Open;
Una vez conectado al
servidor HbServer Local, es posible realizar otras operaciones con la conexión
como las siguientes:
·
Function TestDb(Params: TStrings; Var Msg: String): Boolean
Esta
función permite probar la conexión antes de adicionarla, simplemente indica si
fue posible conectarse a la Base de Datos y en caso de error, en la variable
Msg retornará el mensaje correspondiente.
·
Function RemoveDataBase(DbName: String): Boolean
Elimina
una base de datos de la configuración, se libera la conexión con la base de
datos.
·
Function ClearDataBases: Boolean
Elimina
todas las conexiones a las bases de datos definidas en el HBServer local, el
sistema retornará a las conexiones definidas en el DbAdmin por defecto.
Otras funciones del HBXConnection
Procedure GetDataBaseNames(DbNames:
TStrings);
Procedure GetTableNames(DbName: String; List:
TStrings;
SystemTables: Boolean =
False);
Procedure GetFieldNames(DbName: String;
TableName: String; List: TStrings);
Procedure GetIndexNames(DbName: String;
TableName: String; List: TStrings);
Procedure GetProcedureNames(DbName: String;
List: TStrings);
Procedure GetProcedureParams(DbName,
ProcedureName,
PackageName: String; List:
TStrings);
Function NewQuery(DbName, Sql: String): THbQuery;
Function TestDb(Params: TStrings; Var Msg: String): Boolean;
Function AddDataBase(DbName: String; Params: TStrings): Boolean;
Function RemoveDataBase(DbName: String): Boolean;
Function ClearDataBases: Boolean;
Function BeginTransaction(DbName: String): String;
Procedure CommitTransaction(IdTransaction:
String);
Procedure RollBackTransaction(IdTransaction:
String);
DESCRIPCIÓN DE FUNCIONALIDADES THBXCONNECTION
Manejo de Transacciones (Modo
Local)
El manejo de transacciones
se ha implementado en el modo Local para mantener compatibilidad, sin embargo
en modo servidor no es posible implementar este mismo modelo ya que el modelo
es desconectado y por lo tanto una operación puede iniciarse en un servidor y
terminar en otro completamente diferente.
Existe en el HBServer
métodos para implementar las transacciones, sin embargo es un modelo diferente
y por lo tanto será necesario modificar el código en los puntos donde se
utilicen transacciones.
Las transacciones se definen
por cada conexión a base de datos, aunque los identificadores de cada
transacción llevan un consecutivo único sin importar la base de datos. Veamos
un ejemplo:
Var
DbConn: THBXConnection;
Query:
THbQuery;
IdTran: String;
begin
DbConn
:= THBXConnection.Create(Self);
IdTran
:= DbConn.BeginTransaction('DBName');
Query
:= DbConn.NewQuery('DBName', '');
Try
Query.Sql.Text := 'insert into Paises
values(:CodPais, :NomPais)';
Query.Params.ParamByName('CodPais').AsString
:= '100';
Query.Params.ParamByName('NomPais').AsString
:= 'Colombia';
Query.Execute;
Query.Sql.Text := 'insert into Ciudades '+
'values(:CodCiudad, :NomCiudad, :CodPais)';
Query.Params.ParamByName('CodCiudad').AsString
:= '0101';
Query.Params.ParamByName('NomCiudad').AsString
:= 'Armenia';
Query.Params.ParamByName('CodPais').AsString
:= '100';
Query.Execute;
DbConn.CommitTransaction(IdTran);
Except
On E: Exception do
Begin
DbConn.CommitTransaction(IdTran);
ShowMessage('No se guardaron los cambios, '+
'se
presentó el siguiente error'+#$D#$A+ E.Message);
End;
End;
El modelo de transacciones funciona igualmente en el entorno visual, se inicia la transacción almacenando el Id de
la transacción en una variable global,
se pueden realizar todas las operaciones sobre las tablas y finalmente
se realiza el Commit o el RollBack.
Si
se inicia una transacción, todas las operaciones sobre esa base de datos están
sujetas a la terminación con el Commit o el RollBack, de no hacerlo se pueden
presentar problemas de consistencia en los datos presentados al usuario
posteriormente y es posible que la base de datos aplique automáticamente el RollBack,
perdiendo los datos definitivamente.
Qué pasa con el ApplyUpdates y las
transacciones?
Las
modificaciones que se realizan en ambiente visual o directamente sobre el
resultado de un Select se procesan en memoria, por lo tanto se almacenarán en
la base de datos definitivamente al aplicar la función ApplyUpdates.
El
ApplyUpdates, crea una transacción en la base de datos y almacena físicamente
todos los cambios realizadas desde la última vez que se ejecutó el
ApplyUpdates. pero aún así, si se ha
iniciado una transacción, se puede deshacer ejecutando la función RollBack. En otras palabras tiene prioridad la
transacción sobre el ApplyUpdates.
Debe
tener en cuenta que el ApplyUpdates se aplica sobre una sola tabla, mientras
que las transacciones cubren todas las modificaciones realizadas a diferentes
tablas de la misma base de datos.
Observación: Reiteramos que el manejo de transacciones
debe limitarse lo más posible, debido a que en el modelo desconectado no es
posible implementar las transacciones de la misma manera y será necesario crear
procedimientos en el servidor HyperBase para implementar esta funcionalidad.
Multitareas (THRead Safe)
Los componentes HBX no son
Thread Safe, por lo tanto hay que tener cierto cuidado en el manejo de las
multitareas cuando se conectan a las bases de datos. La mejor forma de trabajar en crear una
Conexión por cada multitarea y liberarla al finalizar la multitarea. Veamos un ejemplo.
Types
TMyThread
= class(TThread)
private
DbConn: THBXConnection;
Query:
THbQuery;
protected
procedure Execute; override;
public
constructor
Create;
end;
implementation
constructor TMyThread.Create();
begin
inherited Create(True);
FreeOnTerminate := True;
DbConn
:= THbxConnection.Create(Nil);
DbConn.ConnectionType := tcxLocal;
Query
:= DbConn.NewQuery('MyDbName','select * from dosomething');
Suspended := False;
end;
procedure TMyThread.Execute;
begin
DbConn.Open;
Query.Open;
Try
Repeat
//Aquí hace lo
necesario con la base de datos
....
//Aquí hace lo
necesario con la base de datos
Until Condición;
Except
On E: Exception do
Begin
//Aquí toma
medidas con respecto a los errores
End;
End;
end;
Cada tarea debe configurar
completamente la conexión a base de datos en caso que sea dinámica, el
THBXConnection puede leer las configuraciones creadas por el DbAdmin.
DESCRIPCIÓN DE FUNCIONALIDADES THBQUERY
Conectar a una base de datos
Antes de realizar cualquier
operación sobre la base de datos, es indispensable conectar el componente con
la base de datos, para ello se utilizan las siguientes propiedades.
Var
Query :
THbQuery;
begin
Query
:= THbQuery.Create(Nil);
Query.RemoteServer := DbConn;
Query.ProviderName := 'dsProvider';
Query.DatabaseName := 'MyDbName';
Query.Sql.Text := 'Select * from ciudades';
Query.OnReconcileError
:= DoReconcileError;
Query.Open;
End;
·
RemoteServer: Debe apuntar al componente
THBXConnection.
·
ProviderName: Es una constante, siempre
debe ser 'DsProvider';
·
DatabaseName: Indica sobre cual base de
datos se realizará la consulta.
·
Sql: El sql que corresponde a
la consulta.
El componente no reporta
algunos errores inmediatamente, dado que son validados por el servidor tanto en
el caso Local como el Remoto, así que esos errores disparan un evento llamado DoReconcileError, Delphi proporciona rutinas
especificas para el manejo de este tipo de errores, siempre es aconsejable
crear un evento para controlar estos errores al crear un Query.
Types
TyMyClasss = Class...
private
procedure DoReconcileError(DataSet:
TCustomClientDataSet;
E:
EReconcileError; UpdateKind: TUpdateKind;
var
Action: TReconcileAction);
end;
implementation
procedure TFDataModule.DoReconcileError(DataSet:
TCustomClientDataSet;
E:
EReconcileError; UpdateKind: TUpdateKind;
var
Action: TReconcileAction);
begin
Raise
Exception.Create(E.Message);
end;
Ejecución de Procedimientos
remotos
Los componentes de HBX
permiten ejecutar tanto los Procedimientos Almacenados (Store Procedures) de la
base de datos, como los Meta Procedimientos de HyperBase, en esta sección solo
hablaremos de los Store Procedures de la base de datos, en el manual del Server
se presentará la forma de crear Meta Procedures, la asignación de permisos de
ejecución y la manera de llamarlos desde el HbQuery.
Consideremos este ejemplo de
un procedimiento en Interbase, el cual tiene como único parámetro de entrada el
valor entero de la edad y retornará una lista de los empleados que son mayores
de dicha edad:
create procedure
get_name (employee_age integer)
returns
(employee_name char(30))
as
begin
for select name
from employee
where age >
:employee_age
into
:employee_name
do
suspend;
end
El Sql de ejecución del
procedimiento sería así:
Query.Sql.Text := 'Select * from Get_Name(27)';
Query.Open;
Paso de Parámetros en un Store
Procedure:
El paso de parámetros es
igual que en cualquier consulta, se le antepone dos puntos (:) a la
variable, es importante definir el tipo,
en especial cuando son fecha, ya que pueden presentar inconsistencia por
formatos:
Query.Sql.Text := 'Select * from Get_Name(:Edad)';
Query.Params.ParamByName('Edad').AsInterger := 27;
Query.Open;
Guardar cambios localmente sin
aplicar
Dado que los componentes
trabajan desconectados, es posible que la conexión al servidor se pierda en
cualquier momento, pero esta situación no debe ser un problema, ya que si se
recupera la conexión el sistema continuará normalmente, pero en el caso de no
poder recuperarse, es posible guardar los cambios localmente y posteriormente
recuperar los cambios y aplicarlos.
veamos el procedimiento:
Query.Sql.Text := 'Select * from ciudades';
Query.Open;
Query.Append;
Query.FieldByName('Cod_Ciudad').AsString
:= '2020';
Query.FieldByName('Nom_Ciudad').AsString
:= 'Bucaramanga';
Query.Post;
Try
Query.ApplyUpdates(0);
Except
Query.SaveToFile('\temp\ciudades.xml',
dfXMLUTF8);
End;
End;
Procedure
RecuperaModificados
Begin
Query.Sql.Text := 'Select * from ciudades';
Query.Open;
Query.LoadFromFile('\temp\ciudades.xml',
dfXMLUTF8);
Query.ApplyUpdates(0);
End;
Leer los datos del Query por
bloques
La Suite de HyperBase está
diseñada para trabajar sobre redes lentas como las de internet, por lo tanto
puede llegar a ser un grave problema intentar traer el resultado de un Sql que
retorne un millón de registros. Así que
existen dos el Server tiene una variable que limita el número máximo de
registros que un usuario puede solicitar, después del cual, el servidor da por
terminada la consulta.
En segunda instancia el
cliente puede solicitar que solamente traiga un pequeño bloque de esos
registros, por ejemplo, solamente los 100 primeros registros:
Query.Sql.Text := 'Select * from ciudades';
Query.PacketRecord := 100;
Query.Open;
Para traer los siguientes
100 registros es posible ejecutar el comando GetNextPacket, en caso de querer
cambiar el número de registros a traer, es posible cambiar la variable PacketRecord.
Query.PacketRecord := 500;
Query.GetNextPacket;
Si se hace un recorrido por
la tabla, esta traerá automáticamente cada paquete en la medida que lo
necesite, no es necesario realizar ningún llamado a la función del
GetNextPacket. El siguiente ejemplo recorrerá toda la tabla hasta llegar al
final, recuperando bloques de 100 registros cada vez que llega al final del
bloque.
While not Query.Eof do
Begin
//Aquí se
realizan las operaciones
.....
Query.Next;
End;
Try
Query.ApplyUpdates(0);
Except
Query.SaveToFile('\temp\ciudades.xml',
dfXMLUTF8);
End;
End;
Nota: La
Propiedad RecordCount se refiere al número de registros que están cargados en
la tabla, no al total de registros de esa tabla en la base de datos.
THBQuery como Memory Table
El THBQuery también puede
comportarse como una tabla de memoria, sin ninguna conexión a las bases de datos, Es posible crear la estructura de la tabla
manualmente o leer un archivo xml guardado previamente de una consulta de la
base de datos.
Para crear el dataset de
forma manual, hay que agregar los campos y los indices, utilizando las
propiedades de FieldDefs e IndexDef, es
importante si se desea posteriormente guardar estos datos en alguna tabla
identificar bien los tipos de datos, ya que si no coinciden, deberá realizar la
actualización de la tabla manualmente:
Var
Query :
THbQuery;
begin
Query
:= THbQuery.Create(Nil);
Query.FieldDefs.Add('Codigo', ftString,
20, True);
Query.FieldDefs.Add('Nombre', ftString,
40, True);
Query.FieldDefs.Add('Fecha', ftDateTime,
0);
Query.IndexDefs.Add('Idx', 'Codigo', [ixPrimary]);
Query.CreateDataSet;
Note que no se asignó ningún
valor a la propiedad RemoteServer ni al ProviderName, de hacerlo, el DataSet intentará buscar la
tabla en el servidor generando un error al no encontrar el sql correspondiente.
Es posible leer en un
DataSet los datos previamente guardados por una consulta, como lo hemos visto
en los ejemplos durante este documento,
si se requiere hacer esto, no se requiere asignar las propiedades de
conexión al servidor.
Var
Query :
THbQuery;
begin
Query
:= THbQuery.Create(Nil);
Query.LoadFromFile('c:\temp\consulta.xml');
....
Nota: El llamado a la función LoadFromFile o LoadFromStream borra
automáticamente cualquier configuración manual que se haya realizado a la
estructura del DataSet.
THBQuery "Live Query"
con múltiples tablas
Con algunos componentes de
conexión a bases de datos solo es posible editar consultas que hacen referencia
a una tabla en particular, usualmente las consultas que involucran múltiples
tablas son de lectura solamente.
Con los HBX es posible crear
consultas de múltiples tablas y asignar una como la tabla primaria, de tal
suerte que se pueden modificar los campos de dicha tabla, los campos restantes no estarán incluidos en
las modificaciones.
Dos conceptos se deben tener
en cuenta para lograr este objetivo, en primer lugar todos los campos
correspondientes a la llave primaria de la tabla principal deben estar
involucrados en la consulta y en segundo lugar, se debe asignar la propiedad
TABLENAME antes de abrir la consulta, para que el servidor pueda asignar la
tabla modificable por defecto.
Var
DBConn:
THBXConnection;
Query:
THbQuery;
begin
DBConn
:= THBXConnection.Create(Self);
DbConn.Open;
Query
:= DbConn.NewQuery('MyDbName','');
Query.OnReconcileError := DoReconcileError;
Query.Sql.Add('SELECT *');
Query.Sql.Add('FROM CIUDADES');
Query.Sql.Add(' INNER JOIN PAISES ON
(CIUDADES.ID_PAIS=PAISES.ID_PAIS)');
Query.TableName := 'CIUDADES';
Query.Open;
If Query.Locate('IDCIUDAD','76001',[]) then
Begin
Query.Edit;
Query.FieldByName('NOMBRE_CIUDAD').AsString
:= 'SANTIAGO DE CALI';
Query.Post;
Query.ApplyUpdates(0);
End;
Nota: Si no se asigna el evento DoReconcileError, el sistema no
captura los errores correspondientes si llegasen a ocurrir.