Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Mi generador me incrementa doble y no de a 1 (https://www.clubdelphi.com/foros/showthread.php?t=70203)

Tcmn 06-10-2010 18:04:34

Mi generador me incrementa doble y no de a 1
 
Hola tengo Firebird 2.1, IBExpert Delphi 6 y XP. Voy iniciando con Firebird e hice una tabla maestro y una detalle que con un generador le asigna su valor a un campo de autonincremento en ambas tablas pero en vez de generarme de a 1 me lo hace al doble. Ejemplo

CLaVE usuario
1er registro 1 jose
2do registro 3 pedro
3er registro 5 Juan

Los generadores que hice con IBExpert esta asi:

CREATE OR ALTER TRIGGER G_CVEEQUIPO_BI FOR EQUIPOS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
NEW.cveequipo=gen_id(gen_equipos_id,1);
end


CREATE OR ALTER TRIGGER PERSONAS_BI FOR PERSONAS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
NEW.CVEPERSONA=gen_id(gen_personas_id,1);
end

Alguien sabe que se me esta pasando porque en Delphi cada vez que doy de alta algun registro me pasa lo arriba citado. Saludos

guillotmarc 06-10-2010 18:08:01

Lo más probable es que de alguna forma llames dos veces al generador cada vez que insertas un registro.

Por ejplo., al insertar un registro, automáticamente el Trigger se dispara e incrementa el generador. Pero a la misma vez, quizás tu programa consulta el generador (incrementándolo) para asignar un valor al campo.

Comprueba cuando se supone que se asigna ese valor de clave primaria, y asegúrate de que solo llamas una vez al generador.

Tcmn 06-10-2010 18:23:30

Estoy haciendo pruebas y curiosamente cuando doy de alta un registro y lo cancelo al generar otro registro me da el sig valor y luego lo cancelo y al dar de alta otro valor me vuelve a dar el sig. Ejemplo
Clave usuario
Ejecuto Insert 1 juan
Cancel
Ejecuto Insert 2 Lpez
Cancel
Ejecuto Insert 3 juana
Cancel
Ejecuto Insert 4 Luis
Post
Ejecuto Insert 6 Luisito (si notas como antes guarde me lo dobla)
Post


Saludos

Casimiro Noteví 06-10-2010 19:02:52

Si lo das de alta, el generador avanza, aunque luego lo canceles.
Supongo que con "cancelar" te refieres a hacer un rollback. Pero el 'beforeinsert' ya se ha ejecutado y ha avanzado el generador.

Tcmn 06-10-2010 19:09:20

Cita:

Empezado por Casimiro Notevi (Mensaje 378603)
Si lo das de alta, el generador avanza, aunque luego lo canceles.
Supongo que con "cancelar" te refieres a hacer un rollback. Pero el 'beforeinsert' ya se ha ejecutado y ha avanzado el generador.

Estoy de acuerdo con eso pero aun mi incognita es ¿por qué dobla el valor cuando sí guardo?

Saludos

guillotmarc 06-10-2010 19:14:29

¿ Estas totalmente seguro que no llamas a estos mismos generadores en ningún otro sitio ?.

¿ Quizás en algunto evento AfterPost en Delphi ?.

Tcmn 06-10-2010 19:52:25

Probe directo en IBExpert y obviamente ahi todo va bien. En delphi sigue igual.
las unicas lineas de codigo que tengo en el IBDataSet ligado a tabla AYUDANTES
es:

procedure TDataModule2.IBAyudantesAfterCancel(DataSet: TDataSet);
begin
DataModule2.IBTransaction1.RollbackRetaining;
end;

procedure TDataModule2.IBAyudantesAfterDelete(DataSet: TDataSet);
begin
DataModule2.IBTransaction1.CommitRetaining;
end;

procedure TDataModule2.IBAyudantesAfterPost(DataSet: TDataSet);
begin
DataModule2.IBTransaction1.CommitRetaining;
end;

procedure TDataModule2.IBAyudantesNewRecord(DataSet: TDataSet);
begin
IBAyudantesCVEPERSONA.Value:=IBPersonasCVEPERSONA.Value;
end;//Esta linea es porq es una tabla detalle de la tabla maestra "PERSONAS"

En el IBDatabase y el IBTransaction al que esta ligado no he puesto una linea de codigo.
No se si sea alguna propiedad que deba modificar o que.

Disculpen mi ignorancia pero es la primera vez que trabajo con Firebird.

Al González 06-10-2010 19:57:45

El disparador no valida si el campo ya viene con valor. Una buena práctica es añadir un If al código del disparador para no darle valor al campo si éste ya trae uno.

Tcmn no ha dicho qué componentes de acceso está utilizando, pero según lo que comenta sobre las altas y los cancels, estoy casi seguro que:

1. Usa un evento OnNewRecord / AfterInsert de esos componentes para llamar al generador.

o bien:

2. Está utilizando IBX con la propiedad GeneratorField.ApplyEvent = gamOnNewRecord (lo cual no es mala idea).

Si fuera lo anterior, para resolver el problema creo que bastaría con añadir el clásico "IF (NEW.ID IS NULL) THEN" a los disparadores. A menos que a Tcmn le interese que esas claves sean consecutivas (algo que no debería ser requisito en una llave primaria ;)).

Saludos. :)

Al González.

P.D. Acabo de ver su nuevo comentario donde nos indica que sí está utilizando IBX. Tcmn, ¿cómo estás utilizando la propiedad GeneratorField del componente de datos?

Tcmn 06-10-2010 21:01:06

Asi es el asunto era poner On server en la propiedad que dice Al Gonzalez.
Asunto solucionado muchas gracias y saludos

guillotmarc 06-10-2010 21:43:30

En el futuro no está de más hacer los triggers como ha propuesto Al (te habrías ahorrado este problema, aunque es mejor haberlo tenido y saber exactamente donde estás asignando la clave primaria).

Es decir :

Código SQL [-]
CREATE OR ALTER TRIGGER G_CVEEQUIPO_BI FOR EQUIPOS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
if (NEW.vceequipo is null) then NEW.cveequipo=gen_id(gen_equipos_id,1);
end

guillotmarc 06-10-2010 21:45:14

O bien, si te gusta más esta sintaxis :

Código SQL [-]
CREATE OR ALTER TRIGGER G_CVEEQUIPO_BI FOR EQUIPOS
ACTIVE BEFORE INSERT POSITION 0
AS
begin
NEW.cveequipo = coalesce(NEW.cveequipo, gen_id(gen_equipos_id,1));
end

rastafarey 07-10-2010 05:00:48

Resp
 
Los generadores son harina de otro costal. Lo que quiere decir que se escapan del control transacional y lo mas seguro es que lo estas asignando en los componentes(dataset) y aparte lo incrementas en el dispador. Verifica que no sea eso lo que te esta pasando.


La franja horaria es GMT +2. Ahora son las 22:14:21.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi