PDA

Ver la Versión Completa : Campos Decimals en un Grid


look
17-07-2008, 21:19:16
hola compañeros,.. tengo el un problema con un grid y una tabla de firebird , el problema es que: tengo una tabla con varios campos de tipo decimal , esta tabla la conecto a un grid , bueno el problema es que me en los campos decimals me muestra : (Bytes),:confused:, a que de debe esto ? , como puedo hacer para q no me muestre eso , y aprobechando el hilo, tengo un campo autoincremental que no me lo reconoce el delphi, que sera?

Delphius
17-07-2008, 21:26:48
Hola look,
¿Podrías explicarnos el tema de (0: bytes)? ¿Te aparece ese texto?:confused:

Por favor si nos puedes aportar detalles del caso sería mejor:
1. Versión de Firebird
2. Componentes que usas
3. Código

Y por cierto, Firebird no cuenta con el tipo incremental. ¿Podrías explicar este punto?

Saludos,

look
17-07-2008, 21:38:56
Hola look,
¿Podrías explicarnos el tema de (0: bytes)? ¿Te aparece ese texto?:confused:

Por favor si nos puedes aportar detalles del caso sería mejor:
1. Versión de Firebird
2. Componentes que usas
3. Código

Y por cierto, Firebird no cuenta con el tipo incremental. ¿Podrías explicar este punto?

Saludos,

Tienes razon amigo , veras, tengo un componente ttable, datasource y un grid , cuando pongo activa la tabla me aparece (bytes) en los campos decimasl...

edito:
firebird2.0


http://img99.imageshack.us/my.php?image=imagetx5.jpg

Delphius
18-07-2008, 07:42:40
Hola Look, la verdad es que no se que puede ser...
Me parece algo raro,

¿Realmente usas DBE? ¿Algún otro componente? ¿Instalaste y/o deisntalaste algo? Decimal ¿De que tamaño, y que precisión?

De por si, te aconsejaría que para Firebird, y sobre todo por la versión, que usaras componentes más adecuados. Estan los Zeos, MDO, IBPlus (o algo asi) entre otros... algunos son gratis, otros no.

Habría que hacer pruebas... yo hasta ahora con los componentes de la Paleta Interbase, Firebird 1.5.3 y tipos Decimal no he tenido problemas. Pero a partir de la versión 2.0 Firebird ya no se puede tener total certeza de que los componentes IBX sean totalmente compatibles con ésta.

Por el tema de incrementales, sería bueno que nos digas a que te refieres... ¿al uso de generadores/tiggers? Si es eso debes tener en cuenta que los generadores escapan al concepto de la transaccionalidad.

Saludos,

donald shimoda
18-07-2008, 07:48:02
Por el tema de incrementales, sería bueno que nos digas a que te refieres... ¿al uso de generadores/tiggers? Si es eso debes tener en cuenta que los generadores escapan al concepto de la transaccionalidad.
Saludos,

Uy amigo salteño, que bueno poder discutir algo así. Tengo entendido que no. Porque habrían de escapar al concepto de transacción? Una transacción incrementa el generador y va para delante, la que viene detrás toma el próximo número y así. Si alguna cancela se pierde ese número.

Estoy equivocado?

Hace rato que no uso generadores, para que la base sea migrable a otros motores (mssql, oracle,etc) en lugar de generar la clave primaria en el motor de base de datos la genero en la aplicación y utilizo UIDs que son GUIDS pasados a textos para que ocupen menos bytes. Se sacrifican algunos bytes pero el registro creado es único en el mundo (en teoría) y permite que varias 'sucursales' se repliquen a un central facilmente.

Bueno, me fui por las ramas. Contame que opinas (como extraño mi tierra, carajo).

Saludos.

Delphius
18-07-2008, 08:06:16
Hola paisano,

Cuado digo que escapa al concepto me refiero a que abortar el proceso no revierte al generador. Es decir, "lo hecho, hecho está". Si haces rollback no conseguirás volver a un estado anterior al generador.

Hay unos cuantos hilos que tratan el tema y se proponen soluciones. Algunos asignan el valor desde el cliente, lanzando una consulta contra el generador y obtener el próximo numero para asi asignarlo... otros aplican un contra-geneador que decrementa...
Solo hay que darse una escapada hacia el sub-foro de Interbase/Firebird y buscar. No soy de buenas palabras para explicarlo bien (admito que me cuesta un poquito explayarme en esto:p), hay un buen documento (http://www.intitec.com/varios/transacciones-0.2.6.pdf) (como otros) que trata el tema de las transacciones en Firebird dando vueltas por la red, y creo que hasta está en FTP del club.

No se si me explico.

Saludos,

donald shimoda
18-07-2008, 08:18:05
Hola paisano,
Cuado digo que escapa al concepto me refiero a que abortar el proceso no revierte al generador. Es decir, "lo hecho, hecho está". Si haces rollback no conseguirás volver a un estado anterior al generador.


Si, totalmente de acuerdo. Y la preocupación viene cuando llegas a 4 mil millones de registros (entre los exitosos y los que no) nunca llego ninguna base mía a ese número usando generadores, pero como que es una posibilidad es una posibilidad! Por eso uso UID.

No se si me explico.
Saludos,

Perfectamente. Vos entendiste lo que yo te dije. :rolleyes:

Saludos.

Delphius
18-07-2008, 09:29:41
Pues acabo de hacer una prueba con DBE.
Yo tengo instalado el driver ODBC 2.0.0 que se encuentra disponible en el sitio Oficial (no volvi a fijarme si hay alguno más nuevo).

Metí un TTable, un DataSource, un Grid, una tabla con campo Decimal... hice la conexión y puedo verlos sin problemas.

¿Será porque usas a versión 2.0 de Firebird? Prueba con la 2.1.1 que es más estable.

Sería bueno que nos indiques más información puesto que me resulta raro esto.

Saludos,

donald shimoda
18-07-2008, 14:36:00
¿Será porque usas a versión 2.0 de Firebird? Prueba con la 2.1.1 que es más estable.
Saludos,

Amigo, por si acaso solo para que no pierda tiempo en eso, yo tengo en producción en muchos sistemas funcionando las 24 horas del día firebird 2.0.3 así que dudo mucho que sea la versión de firebird.

Si puedes crea un pequeño caso de prueba y lo pruebo a ver que sucede.

Danos la descripción de los campos que están molestando por favor, así te podemos ayudar mejor.

Saludo.

RONPABLO
18-07-2008, 15:55:46
Donald, lo de los UIDs suena interesante, si no te molesta nos podrias decir con que crea los UIDs?? y en donde los crea... desde la aplicación o desde la base de datos?...

Delphius
18-07-2008, 16:11:31
Amigo, por si acaso solo para que no pierda tiempo en eso, yo tengo en producción en muchos sistemas funcionando las 24 horas del día firebird 2.0.3 así que dudo mucho que sea la versión de firebird.

Si puedes crea un pequeño caso de prueba y lo pruebo a ver que sucede.

Danos la descripción de los campos que están molestando por favor, así te podemos ayudar mejor.

Saludo.
Si no es la versión de Firebird... entonces.... ¿que puede ser? ¿El DBE? ¿El ODBC? ¿El Delphi (algo difícil que sea este el problema)?
Pues hasta que no aparezca look, podríamos seguir adivinando.

Donald, lo de los UIDs suena interesante, si no te molesta nos podrias decir con que crea los UIDs?? y en donde los crea... desde la aplicación o desde la base de datos?...
No quisiera ser aguafiestas, pero sería bueno que Donald expusiera el tema en un hilo nuevo. Aunque si se considera que complementa y/o que puede ayudar a tratar la segunda duda de look no hay problema.

Saludos,

donald shimoda
18-07-2008, 16:15:37
Donald, lo de los UIDs suena interesante, si no te molesta nos podrias decir con que crea los UIDs?? y en donde los crea... desde la aplicación o desde la base de datos?...

Claro amigo, con mucho gusto.

Si utilizas un UDF, que es basicamente una dll generado por delphi y que colocas en la carpeta de udfs de tu servidor delphi, entonces puedes crear luego un procedure en tu base que antes de insertar LLAME al codigo de la udf, genere el UID y lo asigne a tu clave primaria.

Si lo haces en tu delphi (lo cual te la libertad de moverlo entre motores de base de datos el dia de mañana) simplemente le asignas el valor al campo, llamando a la función de la librería que a continuación te copio.


unit uGUID;
interface

type

PUUIDc = ^TUUIDc;

TUUIDc = array[0..21] of AnsiChar;



PGUIDc = ^TGUIDc;

TGUIDc = array[0..35] of AnsiChar;



function UUIDCreate(uuid: PUUIDc): PUUIDc; stdcall;

function GUIDcreate(guid: PGUIDc): PGUIDc; stdcall;

function GUIDtoUUID(guid: PGUIDc; uuid: PUUIDc): PUUIDc; stdcall; overload;

function GUIDtoUUID(aGUID: TGUID): string; overload;



function GenGUID(Full: Boolean = False; upperCase: Boolean = False): string;

function GenUUID: string;



implementation



uses SysUtils;



function GenGUID(Full, upperCase: Boolean): string;



var

aGUID: TGUID;



begin

CreateGuid(aGUID);

Result:= GuidToString(aGUID);

if not Full then

Result:= System.Copy(Result, 2, 36);

if upperCase then

Result:= AnsiUpperCase(Result);

end;



const

URLchars: array[0..63] of AnsiChar = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-';



function GUIDcreate(guid: PGUIDc): PGUIDc;



var

s: string;



begin

s:= GenGUID(False);

Move(s[1], guid^, SizeOf(guid^));

Result:= guid;

end;



function GUIDtoUUID(guid: PGUIDc; uuid: PUUIDc): PUUIDc;



var

x, i: Integer;

s: string;

aGUID: TGUID;

aGuidArray: array[0..1] of Int64 absolute aGUID;



begin

SetLength(s, SizeOf(guid^));

Move(guid^, s[1], SizeOf(guid^));

aGUID:= StringToGuid(s);

for x:= Low(uuid^) to High(uuid^) do

begin

i:= x div 11;

uuid[x]:= URLchars[aGuidArray[i] and $0000003F];

aGuidArray[i]:= aGuidArray[i] shr 6;

end;

Result:= uuid;

end;



function UUIDCreate(uuid: PUUIDc): PUUIDc;



var

x, i: Integer;

aGUID: TGUID;

aGuidArray: array[0..1] of Int64 absolute aGUID;



begin

CreateGuid(aGUID);

for x:= Low(uuid^) to High(uuid^) do

begin

i:= x div 11;

uuid[x]:= URLchars[aGuidArray[i] and $0000003F];

aGuidArray[i]:= aGuidArray[i] shr 6;

end;

Result:= uuid;

end;



function GUIDtoUUID(aGUID: TGUID): string;



var

x, i: Integer;

aGuidArray: array[0..1] of Int64 absolute aGUID;



begin

SetLength(Result, 22);

for x:= 1 to 22 do

begin

i:= Pred(x) div 11;

Result[x]:= URLchars[aGuidArray[i] and $0000003F];

aGuidArray[i]:= aGuidArray[i] shr 6;

end;

end;



function GenUUID: string;



var

uuid: TUUIDc;

begin

UUIDCreate(@uuid);

SetLength(Result, SizeOf(uuid));

Move(uuid, Result[1], SizeOf(uuid));

end;



end.

La definición del campo FIREBIRD sería.

CREATE DOMAIN GUID AS CHAR(22) CHARACTER SET ISO8859_1 COLATE ES_ES


Es muy importante lo del charset porque generara unos chars muy raros.

P.D. Perdón por la calidad del identado, el formateador de código del foro lo destrozo, ni idea por que. :(

Espero que te sirva. Saludos.
Saludos.

donald shimoda
18-07-2008, 16:28:08
Si no es la versión de Firebird... entonces.... ¿que puede ser? ¿El DBE? ¿El ODBC? ¿El Delphi (algo difícil que sea este el problema)?
Pues hasta que no aparezca look, podríamos seguir adivinando.

exacto no sabemos ni que compos usa...

No quisiera ser aguafiestas, pero sería bueno que Donald expusiera el tema en un hilo nuevo. Aunque si se considera que complementa y/o que puede ayudar a tratar la segunda duda de look no hay problema.
Saludos,

Te vi tarde... :(

Será que el moderador puede mover este post a un hilo nuevo?

Saludos.

RONPABLO
18-07-2008, 16:42:18
Yo en un principio creí que era bueno hacer una pregunta en otro hilo pero al final me pareció que complementaba algo de lo que se hablaba aquí mismo...

RolphyReyes
18-07-2008, 16:48:47
Saludos.
NO es por aguarle la fiesta a nuestro compañero donald shimoda pero este articulo es muy interesante sobre el uso de GUID como campo primario (IbExpert DataBase Performance Newsletter)


Did you ever thought about possibilities to improve your database performance? Sure, a Database System like Interbase or Firebird is able to speed up typical operations internally, but in a lot of cases, there are very easy but powerful improvements.
Here is one more example:

Use the right Datatype!
Due to some customers ideas, we wanted to know how many influence the changes between GUID and Int32 or Int64 Primary Keys will havein the database design regarding performance.
So we created 3 different databases on a windows machine.
Each will have two simple tables (m for master, d for detail).

Here is the DB structure for Int32 IDs:
Código SQL [-] (http://www.clubdelphi.com/foros/#) CREATE TABLE M ( ID INTEGER NOT NULL PRIMARY KEY, TXT VARCHAR(30));

Código SQL [-] (http://www.clubdelphi.com/foros/#)CREATE TABLE D ( ID INTEGER NOT NULL PRIMARY KEY, M_ID INTEGER REFERENCES M(ID), TXT VARCHAR(30));


Here is the DB structure for Int64 IDs:
Código SQL [-] (http://www.clubdelphi.com/foros/#) CREATE TABLE M ( ID BIGINT NOT NULL PRIMARY KEY, TXT VARCHAR(30));

Código SQL [-] (http://www.clubdelphi.com/foros/#)CREATE TABLE D ( ID BIGINT NOT NULL PRIMARY KEY, M_ID BIGINT REFERENCES M(ID), TXT VARCHAR(30));


Here is the DB structure for GUIDs:
Código SQL [-] (http://www.clubdelphi.com/foros/#) CREATE TABLE M ( ID CHAR(32) NOT NULL PRIMARY KEY, TXT VARCHAR(30));

Código SQL [-] (http://www.clubdelphi.com/foros/#)CREATE TABLE D ( ID CHAR(32) NOT NULL PRIMARY KEY, M_ID CHAR(32) REFERENCES M(ID), TXT VARCHAR(30));

For creating the GUID, we are using a UDF from www.ibexpert.com/download/udf/uuidlibv12.zip (http://www.ibexpert.com/download/udf/uuidlibv12.zip)
Código SQL [-] (http://www.clubdelphi.com/foros/#) DECLARE EXTERNAL FUNCTION GUID_CREATE CSTRING(36) CHARACTER SET NONE RETURNS PARAMETER 1 ENTRY_POINT 'fn_guid_create' MODULE_NAME 'uuidlib';

In the next step we will just show you how to create the stored procedure to generate the data in the GUID DB.
Código SQL [-] (http://www.clubdelphi.com/foros/#) CREATE PROCEDURE INITDATA (ANZ INTEGER) AS declare variable m varchar(40); declare variable d varchar(40); declare variable dx integer; begin while (anz>0) do begin m=guid_create(); m=strreplace(m,'-',''); insert into m(id,txt) values (:m,current_timestamp); dx=10; while (dx>0) do begin select guid_create() from rdb$database into :d; d=strreplace(d,'-',''); insert into d(id,txt,m_id) values (:d,current_timestamp,:m); dx=dx-1; end anz=anz-1; end end

A Procedure to create the Integer ID Data is much easier using a generator.

After we have created all 3 databases with the param 500000 (which means 500000 master and 5 milllion detail records are created), we disconnect and reconnect again to see that any cache influence will not change the results.

To do the typical SQL Operation, we start a select that joins all records from all tables

select count(*) from m join d on d.m_id=m.id


Here are the results over all
Operation/Info Int32 Int64 GUID
DB Size 505 MB 550 MB 1030 MB
INITDATA(500000) 271s 275s 420s
Backup 49s 54s 90s
Restore 124s 127s 144s
Select 22s 22s 49s

Resume
The changes between Int64 and Int32 can almost be ignored, but the changes to a GUID is a problematic design. The integer datatypes will give you better performance.



Pagina: http://www.firebirdnews.org/?p=998

donald shimoda
18-07-2008, 17:18:25
Saludos.
NO es por aguarle la fiesta a nuestro compañero donald shimoda pero este articulo es muy interesante sobre el uso de GUID como campo primario (IbExpert DataBase Performance Newsletter)
Pagina: http://www.firebirdnews.org/?p=998

Amigo Rolphy, por favor si aca estamos todos para aprender. Muy buena la info.

La diferencia es que usa mayor cantidad de digitos un GUID que un UID.

Justamente la idea de usar UIDs es porque la longitud de campor requerida es MENOR que usando GUIDS, esa es la ventaja, mientras se mantienen las características de los GUIDS.

22 chars de los UIDS contra 36 de los GUIDs, no es poca cosa...

Saludos.

RolphyReyes
18-07-2008, 18:30:33
Empezado por donald shimoda
Amigo Rolphy, por favor si aca estamos todos para aprender. Muy buena la info.

Sí, verdaderamente y me alegra bastante que sea de tu interés.

Entiendo que la diferencia es "considerable" porque son 14 caracteres menos, pero lo que veo es que aun sigue siendo Alfanumérico y no numérico del todo;
que es justamente lo que incide en el rendimiento de la base de datos.

Mencionas que teniendo un sistema "multi-sucursales" que se repliquen en un servidor es más fácil realizar el proceso, creo más bien que eso va a depender de tu estructura de la BD, porque si es "multi-sucursales" debes de un campo que identifique cual sucursal es la propietaria del registro, y tu clave primaria pude seguir siendo un entero.

Lo que quiero explicar al final, es que no me imagino una BD con 100 tablas y todas sus claves primarias sean Varchar, cuando realices algún tipo de consulta pienso que se sembrara el servidor o tu respuesta tardara bastante.

Es lo que creo!!! :rolleyes:

donald shimoda
18-07-2008, 19:05:14
Mencionas que teniendo un sistema "multi-sucursales" que se repliquen en un servidor es más fácil realizar el proceso, creo más bien que eso va a depender de tu estructura de la BD, porque si es "multi-sucursales" debes de un campo que identifique cual sucursal es la propietaria del registro, y tu clave primaria pude seguir siendo un entero.


Buen punto. Pero que sucede cuando los datos NO SON de una sucursal sino del conjunto. Ejemplo clientes, o productos.
Son datos que quiero agregar en una sucursal y que automáticamente sean validos en la BD central, se entiende? Con enteros no podes hacerlo.


Lo que quiero explicar al final, es que no me imagino una BD con 100 tablas y todas sus claves primarias sean Varchar, cuando realices algún tipo de consulta pienso que se sembrara el servidor o tu respuesta tardara bastante.

Mis pruebas dicen lo contrario. ;)

Mira, hasta donde yo se (sacado de la lista firebird) los indices son mas óptimos en cuanto a respuesta proporcionalmente a cuanto mas datos diferencian los campos, es decir cuando menos se repiten los datos en la clave primaria.

Por tanto una consulta combinada encontrará los datos más rápidamente cuanto mas DIFERENCIAL sea la clave.

Lo único que jode es en el tamaño , si quieres buscarle un pero. Pero la verdad que en estos días, no es el primer punto a mirar en mi opinión cuando se diseña una base. Sino usemos archivos planos y listo. :)

Saludos.

look
19-07-2008, 16:59:11
hola compañeros, solo es para disculparme por no haber seguido la continuidad del hilo , lastimosamente he estado enfermo y por eso no segui , bueno y ahora saldo de viaje,...


saludos....:)

Delphius
19-07-2008, 17:16:13
hola compañeros, solo es para disculparme por no haber seguido la continuidad del hilo , lastimosamente he estado enfermo y por eso no segui , bueno y ahora saldo de viaje,...


saludos....:)
No hay problema look, gracias por avisar. Que te mejores. Y cuando puedas darte una "escapadita" nos comentas sobre el tema. Pues como ya Donald y yo mencionamos, es algo bastante raro.

Saludos,