Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-06-2003
mosorio mosorio is offline
Miembro
 
Registrado: may 2003
Posts: 159
Poder: 22
mosorio Va por buen camino
Question 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
Responder Con Cita
  #2  
Antiguo 14-06-2003
mosorio mosorio is offline
Miembro
 
Registrado: may 2003
Posts: 159
Poder: 22
mosorio Va por buen camino
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.
Responder Con Cita
  #3  
Antiguo 17-06-2003
AbcXxx AbcXxx is offline
Miembro
 
Registrado: jun 2003
Posts: 50
Poder: 21
AbcXxx Va por buen camino
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,lacas,: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???
Responder Con Cita
  #4  
Antiguo 17-06-2003
Avatar de kinobi
kinobi kinobi is offline
Miembro
 
Registrado: may 2003
Posts: 2.621
Poder: 24
kinobi Va por buen camino
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.
Responder Con Cita
  #5  
Antiguo 17-06-2003
AbcXxx AbcXxx is offline
Miembro
 
Registrado: jun 2003
Posts: 50
Poder: 21
AbcXxx Va por buen camino
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???
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 07:02:40.


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