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)
-   -   Registro desaparecen en Firebird con Trigers (https://www.clubdelphi.com/foros/showthread.php?t=48690)

rogeriobeltran 02-10-2007 05:10:56

Registro desaparecen en Firebird con Trigers
 
Buenas:

Ante todo gracias por la colaboración, desde hace un año diseñe un programa para la venta, tenia una tabla en donde guardo la ultima factura por caja y la iba actualizando por caja cada vez que realizaba una factura. Desde hace unos dos meses el cliente me solicito que necesitaba trabajar dos equipos con la facturación de una caja, para ello cree un valor consecutivo utilizando un generador y un triger cada vez que inserta un archivo. Pero desde hace unos dias me crean el registro imprimen la factura y en ese instante en el otro equipo estan creando otra factura y alguna de ellas no me la guarde y realmente no se que cambios realizar o que estoy realizando mal. Elimine las transacciones pensando que fueran ella y tampoco. Un equipo tiene la base y el otro se conecta a ella por red local. Lenguaje de programación Delphi 5, firebird 2.0 y componentes dataaccess. La estructura de datos es la siguiente:

crea el generador:
Código SQL [-]
 CREATE GENERATOR CODIGO_VENTA;

este es el triger

Código SQL [-]
 set sql dialect 3;

set names none;

create generator codigo_venta;

set term ^ ;


create or alter trigger venta_clave for venta
active before insert position 0
as
begin
new.numero = gen_id(codigo_venta,1);
  /* Trigger text */
end
^


set term ; ^

y esta es la tabla que trabajo

Código SQL [-]
 
set sql dialect 3;

set names none;



/******************************************************************************/
/****                                Tables                                ****/
/******************************************************************************/


create generator codigo_venta;

create table venta (
    numero                     integer not null,
    fecha                      timestamp not null,
    cliente                    varchar(15) not null,
    vendedor                   varchar(15) not null,
    factura                    float,
    total                      double precision,
    descuento                  double precision,
    iva                        double precision,
    concepto                   integer,
    observacion                varchar(200),
    estado                     char(1),
    codigousuariocreacion      integer,
    fechacreacion              timestamp,
    codigousuariomodificacion  integer,
    fechamodificacion          timestamp,
    prefijo                    varchar(10)
);




/******************************************************************************/
/****                             Primary Keys                             ****/
/******************************************************************************/

alter table venta add constraint pk_venta primary key (numero);


/******************************************************************************/
/****                             Foreign Keys                             ****/
/******************************************************************************/

alter table venta add constraint fk_venta_cliente foreign key (cliente) references cliente (identificacion);
alter table venta add constraint fk_venta_concepto foreign key (concepto) references concepto_venta (codigo);
alter table venta add constraint fk_venta_vendedor foreign key (vendedor) references vendedor (identificacion);


/******************************************************************************/
/****                               Triggers                               ****/
/******************************************************************************/


set term ^ ;


/******************************************************************************/
/****                         Triggers for tables                          ****/
/******************************************************************************/



/* Trigger: VENTA_CLAVE */
create trigger venta_clave for venta
active before insert position 0
as
begin
new.numero = gen_id(codigo_venta,1);
  /* Trigger text */
end
^


set term ; ^


gracias por su colaboración

Rogerio Beltrán.

pvizcay 03-10-2007 05:12:41

hola..

la base de datos parece bien.. yo buscaría en el código de la aplicación, más que nada con las transacciónes..

salu2

rogeriobeltran 03-10-2007 14:30:52

Gracias por responder:

El problemas es eliminelas transacciones pensado que ese es el problema y no siguen desapareciendo los registros, el programa apenas ingresan a realizar una factura la guarda con datos genericos, modificando la secuendia que es la llave primaria. Realizan la venta e imprimen la tirilla y siguen trabajando normalmente pero cuando consultan la factura no aparece, reviso la base de datos y el registro que esta atado a la secuencia no aprece, es decir si iba en la factura 100 , crea la 101 y sigue trabajando y llegan hasta la 110, reviso la base y la 101 no existe datos.Lei en un correo que existia problemas con la versión de firebird 2.0.1 y decidi desinstalarla e instalarla 2.0.0, no se si se solucionara el problema, para el mes de septiembre tengo perdidas 26 facturas de 938 aunque algunas son facturas anuladas por que ingresan y no realizan la venta. Es la primera vez que me sucede esto y estoy muy preocupado.:confused:

maeyanes 03-10-2007 15:23:40

Hola...

Tu problema podría ser que usas generadores para obtener el número de la factura...

Los generadores son atransaccionales, esto es, no entran dentro del contexto de las transacciones, así que si pides un número y no guardas, ese número se pierde...

Deberías probar con una tabla donde llevar el contador de facturas...



Saludos...

jhonny 03-10-2007 15:25:06

El problema no debe ser la BD, en nuestra empresa usamos la versión 2.0.1 de FireBird y creeme que ya hubiera tenido un gran problema si me hubiera sucedido eso ;), como dice pvizcay, la estructura de la base de datos se ve bien, el problema debe estar en la aplicación, seguramente al momento de guardar las facturas esta eliminando alguna de las anteriores, dices que el problema no es en las transacciones, entonces revisa el algoritmo de grabado con un "paso a paso" para que analices lo que esta haciendo dicha aplicación, no vaya a ser que algun evento que se dispara este haciendo algun estrago ;).

Observación: Bueno, note en la estructura de tu BD que el campo factura de la tabla venta es de tipo float, ¿Necesitas que sea float?, pregunto porque me parece que trabaja mejor el double precision, pero si definitivamente necesitas el float me interesaria saber el "¿Porque?", gracias ;).

rogeriobeltran 03-10-2007 18:20:00

Gracias por las respuestas estoy revisando el procedimiento para verificar su funcionamiento, lo del dato float en factura, se me paso cambiarlo a double precision. Gracias por sus comentarios.:)

duilioisola 03-10-2007 18:51:30

Yo utilizo este tipo de función para devolver el numero que debería tener la factura.
Lo pongo en el BeforePost del DataSet.

Código Delphi [-]
procedure TDMFacturas.CabeceraBeforePost(DataSet: TDataSet);
begin
   if (DataSet.State = dsInsert) then
   begin
      CabeceraNUMERO.AsInteger := DameContador;
   end;
   (...)

Código Delphi [-]
function DameContador : integer;
var
   Q : TIBQuery ;
   T : TIBTransaction;
begin
   Q := TIBQuery.Create(nil);
   T := TIBTransaction.Create(nil);
   T.DefaultDataBase := BaseDeDatos;
   {Quizas haya que llenar mas propiedades de la Trasaccion}
   with Q do
   begin
      Close;
      DataBase := BaseDeDatos; {Base De Datos}
      Transaction := T;
      {Quizas haya que llenar mas propiedades del Query}
      if (not Transaction.InTransaction) then Transaction.StartTransaction;
      SQL.Text := 'select gen_id(''CODIGO_VENTA'',1) as contador from rdb$database';
      ExecQuery;
      Result := Fields[0].AsInteger;
      Transaction.Commit;
   end;
   Q.Free;
   T.Free;
end;

Se supone que antes de hacer el post (donde se graba el registro)
- abre una transacción,
- pide un numero del generador y lo mete en el ID del Dataset
- cierra la transacción que abrió.

La transacción es creada en el momento y no tiene nada que ver con la transacción que utilizas para el resto de la aplicación.

Obviamente deberías modificar los triggers de BeforeInsert
Código SQL [-]
create trigger venta_clave for venta active before insert position 0
as
begin
   if ((new.numero = 0) or (new.numero is null)) then
      new.numero = gen_id(codigo_venta,1);
  /* Trigger text */
end

pvizcay 04-10-2007 15:52:35

Cita:

Empezado por rogeriobeltran (Mensaje 235811)

El problemas es eliminelas transacciones

pues si es un sistema en red las transacciones son pasajeros de primera clase, no los puedes mandar a la baulera..!!! jaja

creo que el error viene porque hicistes un diseño que cuando lo escalastes a un sistema en red tiene alguna falla..

espero lo puedas solucionar! suerte!

rogeriobeltran 05-10-2007 18:48:13

Gracias a todos,

Realice una revisión del programa, estoy esperando su funcionamiento. Creo que era un error de programación. :rolleyes:


La franja horaria es GMT +2. Ahora son las 10:33:39.

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