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)
-   -   Generadores   (https://www.clubdelphi.com/foros/showthread.php?t=1448)

mosorio 14-06-2003 12:05:41

Generadores  
 
Hola compa�eros,

Tengo un inconveniente con los generadores, bueno extactamente con ellos no sino con la obtenci�n del valor. Cuando ejecuto la sentencia sql para obtener el �ltimo, y asignarlo en el campo, tarda casi un segundo o mas en mostrarse y se nota la tardanza, el c�dogo que utilizo es:

Cita:

sqlGenId.Close;
sqlGenId.CommandText := '';
sqlGenId.CommandText := 'Select gen_id('+ NombreGen +', 0) Id '+ 'from RDB$DATABASE';
sqlGenId.Open;

result := sqlGenId.FieldValues['ID'] + 1;
sqlGenId.Close;
Este es el ejemplo que he encontrado en la webde Ian, tambi�n se de las consecuencias que pueden haber al restringir las tablas del sistema en las nuevas versiones de Firebird.

Lo que necesito es saber si hay alg�n procedimiento m�s optimo, se que este lo es, pero alguno donde no se note el refresco, he intentado desactivar los controles pero no me asigna el valor en el campo o no lo muestra.
Como pueden ver estoy utilizando dbexpress.
Si hago un procedimiento almacenado donde pueda obtener el dato, no se si sea m�s veloz u optimo, si es as�, tendr�a que hacer uno por cada tabla que necesite incrementar.

Agradezco la ayuda de antemano.

PD: Disculpen si no he contstado o dado consejo alguno de los dif. hilos, pero estoy contra el reloj con este proyecto. Prometo colaborar cuando vaya finalizando, espero sea pronto.

Gracias :rolleyes:

mosorio 14-06-2003 14:12:41

Hola delphoros!

Creo que esta vez me contestar� a mi duda, y espero le sirva a todos los que han tenido y tendr�n esta misma.
He utilizado un procedimiento almacenado en la BD sencillo que ejecuta un generador:

Cita:

create procedure Gen_Codigo
returns (Id Integer) as
begin
Id = Gen_Id(<NombreGenerador>, 1);
end^

:. NombreGeberador es el generador creado para cada una de las tablas o id que necesitan incremento.
Ahora en el programa Delphi, en el datam�dulo se inserta un componente SP sin asignarle el procedimiento almacenado, esto para reutilizarlo con los otros.

Se crea una function para ejecutar el SP y retornar el valor:

Cita:

function TdmPrg.EjecutarGenerador(NombreGen: String): Integer;
begin
spGenerador.Close;
spGenerador.StoredProcName := NombreGen;
spGenerador.ExecProc;

Result := spGenerador.Params[0].AsInteger;
end;

procedure TdmPrg.cdsTipoIVAAfterInsert(DataSet: TDataSet);
begin
cdsTipoIVA.FieldByName('IDTIPOIVA').AsInteger := EjecutarGenerador('GEN_IDTIPOIVA');
end;

Y en CDS en el evento despues de insertar capturamos el valor para ser asignado al componente dbe que ha sido enlazado con el datasource.
Ahora la respuesta es mucho m�s r�pida y no se nota la asignaci�n.
Yo estoy trabajando en el mismo pc y tengo instalado un SO de servidor, esta tardanza era bastante preocupante ya que en el mismo pc daba el retardo, no quer�a imaginar cuando se hicieran las pruebas en red a otros pc.
L�gico esta que al cancelar una inserci�n se perder� el consecutivo, pero esto lo controlar� m�s adelante en la misma BD realizando los controles de actualiaci�n en cascada y otras cositas que he estado viendo en el motor FireBird, IB y el libro de La cara Oculta de Delphi 4

Gracias y espero les sirva.

AbcXxx 17-06-2003 17:45:41

Para no perder el consecutivo yo hago lo siguiente:
Hice un "trigger before insert" y es ahi donde ejecuto el

Id = Gen_Id(<NombreGenerador>, 1);

y tengo entendido que solo se va a ejecutar cuando realmente se este insertando en la tabla

el codigo me queda asi (aunque no lo se poner entre "quote:")

CREATE TRIGGER SETFOLIO FOR ORDENGAS
ACTIVE BEFORE INSERT POSITION 0
as
begin
new.folio = gen_id(folio_gen,1);
end

y como usualmente nesecitamos saber cual es la clave para regresarla a la pantalla o imprimirlo, yo lo soluciono con un procedimiento que es el encargado de insertar los datos a la tabla:


ALTER PROCEDURE APPENDORDEN (CARRO SMALLINT,
PLACAS VARCHAR(10),
KILOMETROS INTEGER,
SUCURSAL INTEGER,
CHOFER VARCHAR(30),
AUTORIZO VARCHAR(30),
TIPO VARCHAR(10))
RETURNS (FOLIO INTEGER)
AS
begin
insert into ordengas(carro, placas,kilometros,sucursal,chofer,autorizo,tipo)
values (:carro,:placas,:kilometros,:sucursal,:chofer,:autorizo,:tipo);
folio=gen_id(folio_gen,0);
end

como veran, este es el procedimiento que llamo cuando inserto un nuevo registro; le paso los valores validados previamente para que halla menos posibilidades de error y el procedimiento al tratar de insertar los datos en la tabla se dispara el trigger SETFOLIO el cual aumenta el generador y me asigna el valor en el campo folio, para despues retornar el valor de el numero de folio desde el mismo procedimiento...

...Como se pone el codigo entre rayitas??? :D

kinobi 17-06-2003 18:05:49

Hola,

Cita:

Posteado originalmente por AbcXxx
y tengo entendido que solo se va a ejecutar cuando realmente se este insertando en la tabla
cierto, pero si haces un rollback el registro no queder� insertado (cosa l�gica), pero el generador no volver� a su antiguo valor, por tanto s� es posible que queden huecos en la secuencia. Recuerda que los generadores no est�n bajo el control transaccional.

Regla a no olvidar con generadores: un generador tocado (incrementado o disminuido su valor) no es posible deshacer el cambio con rollback.

Otra regla: Los generadores pueden garantizar valores enteros �nicos, pero no necesariamente en secuencia (sin huecos).

En cierta forma son conceptos excluyentes, puedes crear un mecanismo que genere valores unicos, pero sin la garant�a de secuencia (los generadores), y al contrario: puedes crear un mecanismo que garantice la secuencia, pero entonces no garantizar�s la unicidad (este mecanismo no lo tiene implementado InterBase). Vamos, que los dos a la vez no es posible.

Saludos.

AbcXxx 17-06-2003 18:34:45

Cita:

cierto, pero si haces un rollback el registro no queder� insertado (cosa l�gica), pero el generador no volver� a su antiguo valor, por tanto s� es posible que queden huecos en la secuencia. Recuerda que los generadores no est�n bajo el control transaccional.
Tienes toda la razon (como de costumbre), y si, lo que hago inmediatamente despues de ejecutar el procedimiento que inserta, hago un commit, aunque tambien se que esto no me garantiza que se realize con exito...

Cita:

En cierta forma son conceptos excluyentes, puedes crear un mecanismo que genere valores unicos, pero sin la garant�a de secuencia (los generadores), y al contrario: puedes crear un mecanismo que garantice la secuencia, pero entonces no garantizar�s la unicidad (este mecanismo no lo tiene implementado InterBase). Vamos, que los dos a la vez no es posible.
definitivamente me quedo con el primer metodo

Hasta pronto...

p.d. se nota que ya se usar las citas???:D


La franja horaria es GMT +2. Ahora son las 13:22:31.

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