PDA

Ver la Versión Completa : no veo automunerico


jzginez
11-06-2004, 19:48:57
Hola a todos para empezar no se si este hilo esta bien aqui o va en Conexión con bases de datos.


Mi problema es el siguiente:

estoy usando firebird 1.5, delphi 7, componentes fibplus5_3 e IBExpert
tengo varias tablas con campos autonumericos (en todas tengo el mismo problema) y cuando ingreso datos desde el ibexpert todo marcha como era de esperarse sin nungun problema (por lo menos en la generación del autonumerico :D ), cuando programa mi aplicación en delphi 7 uso los componentes de fibplus para hacer la conección con la base y a la vez con las tablas, para prueba use un dbgrid y un dbvavigator, cuando ingreso datos en el dbgrid el autonumerico vale cero, guardo el registro y sigue valiendo cero, ingrso un nuevo registro y en los dos registros veo el valor de cero para el autonumerico, doy un refresh a la tabla y el autonumerico sigue siendo cero.

Salgo de la aplicación y entro a ibexpert para ver que paso en la tabla y ooohh sorpresa el autonumerico se genero bien, es decir si ingrese los registros 1 y 2 desde delphi mi campo id (que es el autonumerico) tiene los valores 1 y 2, el generator tiene el valor 2, etc.. todo normal.

alguien tiene una idea de por que no pueda ver el valor real del autonumerico en delphi??

guillotmarc
11-06-2004, 22:19:53
Hola.

Tu problema está en que el nuevo código se genera directamente en la base de datos (mediante un trigger), y el Dataset Delphi no se entera de que el campo ha cambiado.

Para que vuelva a leer el valor del campo, y se dé cuenta del cambio, tendrás que hacer un Refresh del Dataset.

NOTA : Puedes probar a poner la propiedad AutoGenerateValue del campo persistente, a arAutoInc, para indicarle que ese campo es asignado por la base de datos, y debe volver a leerlo. Aunque en algunos sistemas esto no funciona, no sé que tal irá con FibPlus y Firebird.

Yo lo que hago es no calcular esos campos mediante un Trigger, sinó que obtengo el nuevo valor mediante un procedimiento almacenado (IBExpert te puede crear automáticamente este procedimiento), y lo asigno al campo desde Delphi. Así el Dataset en Delphi siempre tendrá el valor que le hemos asignado manualmente, y no tienes que refrescarlo para que vaya a buscar el nuevo valor.

Saludos.

rastafarey
14-06-2004, 16:34:26
A ver si te funciona con hacer un commit y Refrescas el dataset

jzginez
14-06-2004, 19:49:16
hola gracias por las sugerencias

Para que vuelva a leer el valor del campo, y se dé cuenta del cambio, tendrás que hacer un Refresh del Dataset.
el código que me genero delphi en el dataset es el siguiente:


SELECT
ID,
DESCRIPCION
FROM
TCOLORES
Order by id

/***************************/
INSERT INTO TCOLORES(
ID,
DESCRIPCION
)
VALUES(
:ID,
:DESCRIPCION
)

/***************************/
UPDATE TCOLORES
SET
DESCRIPCION = :DESCRIPCION
WHERE
ID = :OLD_ID

/**************************/
DELETE FROM
TCOLORES
WHERE
ID = :OLD_ID

/*************************/
SELECT
ID,
DESCRIPCION
FROM
TCOLORES
WHERE
TCOLORES.ID = :OLD_ID



para el commit tengo el siguiente código.

Procedure TDataModule2.Guarda(DataSet: TDataSet);
Begin
pFIBTransaccion.CommitRetaining;
End;


y para cancelar

Procedure TDataModule2.Cancella(DataSet: TDataSet);
Begin
pFIBTransaccion.RollbackRetaining;
end;


los cuales mando a llamar en el afterpos y afterCancel respectivamente

guillotmarc:
NOTA : Puedes probar a poner la propiedad AutoGenerateValue del campo persistente, a arAutoInc,
No sabia de esta propiedad pero tambien ya la provee y no funciono

Yo lo que hago es no calcular esos campos mediante un Trigger, sinó que obtengo el nuevo valor mediante un procedimiento almacenado
El procedimiento ya lo tenia ( cuando cree mi tabla le indique a ibexpert que me crearo todo lo que decia, mas vale que sobre y no que falte :D )

No entendia para que me servia pero ahora con tu comentario empiezo a entender lo llame con un pFIBStoredProc lo ejecuto pero en ese punto me gana la ignorancia despues que hago??

les escribo la ddl de mi tabla para que me den su opinion a ver si no esta ahi el error



CREATE GENERATOR GEN_TCOLORES_ID;

CREATE TABLE TCOLORES (
ID INTEGER NOT NULL,
DESCRIPCION NOMBRES /* VARCHAR(30) */
);


ALTER TABLE TCOLORES ADD PRIMARY KEY (ID);


SET TERM ^ ;

/* Trigger: TCOLORES_BI */
CREATE TRIGGER TCOLORES_BI FOR TCOLORES
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_TCOLORES_ID,1);
END
^

CREATE PROCEDURE SP_GEN_TCOLORES_ID
RETURNS (
ID INTEGER)
AS
BEGIN
EXIT;
END^


SET TERM ; ^

guillotmarc
14-06-2004, 20:23:05
Yo capturo el evento AfterInsert del Dataset en Delphi, y en ese evento llamo al procedimiento almacenado, asignando su resultado al campo de clave primaria.

Saludos.

jzginez
14-06-2004, 20:28:42
master me disculparas pero la parte que no entiendo es como capturo el resultado del procedimiento

guillotmarc
14-06-2004, 20:35:49
Llámame Marc por favor (lo de master es un poco exagerado).

Este seria un ejplo. de código en el AfterInsert ;


procedure qryClientesAfterInsert(Dataset:TDataset);
begin
IBSp.ExecProc;
DataSet.FieldValues['ID'] := IBSp.Params.ParamValues['ID'];
end;


Solo tienes que leer el valor del parámetro de salida.

Saludos.

jzginez
15-06-2004, 03:44:12
Gracias Marc por el código te comento que ya solucione mi problema, te cuento como estuvo el relajo por si lo llegas a necesitar o alguien mas del foro usa los componentes fibplus:

Revise los ejemplos que trae fibplus y en estos si se ve el incremento de los campos autonumericos así que cree una aplicación copiando textualmente el código de la aplicación y usando la base de ejemplo y aun así en el ejemplo funcionaba y en mi copia no.

Lo que mejor hise fue modificar la aplicación ejemplo para que leyera mi base de datos en lugar de la del ejemplo por si estaba mal mi autonumerico y para mi sorpresa en tiempo de ejecución cuando intentaba insertar un nuevo registro en la tabla me marco error indicando que no encontraba el generador COMPANIES_GEN_ID el cual usa la base de ejemplo por lo cual volvi a revisar las propiedades del componente pfibdataset (segun yo ya las abia revisado bien :rolleyes: ) y para sorpresa me encontre que tiene la propidad AutoUpdateOptions donde una de sus subpropiedades (por llamarlas de algun modo) son:

GeneratorName donde das el nombre de tu generador
KeyFields donde indique el campo autonumerico
UpdateTableName nombre de la tabla a modificar ( :confused: aunque seha la misma)

y ooooohhhhhhhhhh gran sorpresa ya funciono

nuevamente gracias por tu ayuda gracias a eso ya entendi el porque ibexpert me crea un procedimiento para mis autonumericos y como hacer uso de este en delphi.


P.D. En lo personal lo de master es porque considero que tu y otros mienbros del foro son amos en el uso de interbase, muchas veces con su primera respuesta me amplian la duda pero siempre termino sabiendo mas de lo que esperaba