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)
-   -   Firebird Suma 2 valores en un campo autoincrementado en insercion de registro (https://www.clubdelphi.com/foros/showthread.php?t=43070)

Adrian Murua 01-05-2007 03:57:11

Firebird Suma 2 valores en un campo autoincrementado en insercion de registro
 
Estimados Amigos:

Estoy desarrollando un modulo para Agregar, Modificar y Consultar datos de articulos para un kiosco.
Trabajo con Delphi 2005 y Firebird 2.0 y IBX

Tengo 2 tablas Articulos y Marcas( de Articulos ) ej: A: Chocolate - M: Pepito.
la estructura es la sig:

Articulos.

Articulo_ID, Integer, Autoincrem.(clave primaria)
Descripcion, char 50,
Precio Double,
Marca_ID, integer (Foreign Key)
...

Marcas.
Marca_ID, Integer, Autoincrem. (clave primaria)
Nombre char 50
...

Tengo estos formularios:

1. un datamodule que contiene un control IBDatabase, otro IBTransaction configurado:
"
read_committed
rec_version
nowait
"
y en defaultaction: "TACommitRetaining"., Ademas 2 IBDataset : Articulos y Marcas, donde Marcas tiene las siguientes definiciones en :
InsertSQL : "insert into Marcas( Nombre ) Values ( :Nombre )"
SelectSQL: "Select * from Marcas"
RefreshSQL: "Select * from Marcas"
GeneratorField :
"
Generator : MARCAS_MARCAID_GEN
field : MARCA_ID
INCREMENT BY : 1
EVENT : ON NEW RECORD;
"

2. Formulario para agregar, modificar articulos , que contiene una grilla en la cual presionando un boton se abre otro formulario para ingresar un articulo nuevo. Este formulario tiene controles del tipo TEdit y un boton para grabar.
En un control TComboBox selecciono la marca del producto o la agrego mediante un boton, donde se abre otro formulario para agregar la Marca (Nombre solamente), cuando termina de agregar la marca, sigo agregando los datos del articulo..

Pues bien, cuando termino de agregar la marca y se cierra el formulario (de Marcas), me graba el nuevo registro( nombre de la marca ) pero el Marca_ID , que es el campo autoincrementado, en vez de sumar 1 al ultimo, suma 2.
el codigo donde grabo los datos en la tabla de Marcas es el siguiente:

Código Delphi [-]
procedure TFrmMarcas.AgregarClick(Sender: TObject);
begin
        if Application.MessageBox('Graba los Datos ????','Información',
           MB_ICONQUESTION+MB_DEFBUTTON1+MB_YESNO)= 6 then
           begin
              with datos.Marcas do
              begin
                  append;
                  fieldbyname('Nombre').AsString := trim(eNombre.text);
                   Post;
              end;
              datos.Transaccion.CommitRetaining;
           end;
  close;

end;

Cuando se ejecuta la linea coloreada ya se observa ( con el IBExpert ) el incremento incorrecto.

Que puede estar sucediendo ?-

Desde ya Muchas Gracias

Lepe 01-05-2007 12:44:53

¿no habrás creado un trigger before Insert/post ?

Suena exactamente a que el propio ibx incrementa en uno (por decirle que lo haga en el OnNewRecord) y después el servidor, en el trigger, lo vuelve a hacer.

PD: podrías usar InsertRecord que sustituye a :
Código Delphi [-]
                  append;
                  fieldbyname('Nombre').AsString := trim(eNombre.text);
                   Post;

Saludos

Adrian Murua 02-05-2007 05:22:08

Muchas gracias por contestar.

El trigger esta creado en el servidor, pero tuve que llenar el campo Generatorfield con .

Código Delphi [-]
Generator : MARCAS_MARCAID_GEN
field : MARCA_ID
INCREMENT BY : 1
EVENT : ON NEW RECORD;

supongo que con este codigo estaria creando un trigger en los IBX, pero me vi obligado pues cuando queria insertar el registro salia un error indicandome que el campo MARCA_ID no podia ser nulo.

Ahora bien, cual seria la mejor opcion: Quitar el trigger del servidor, dejando el del IBX, o al reves, pero en este caso como soluciono el mensaje de error (del valor nulo en MARCA_ID); Hay alguna forma mejor de realizar esto ?.

desde ya muchas gracias.

Lepe 02-05-2007 11:57:16

el cuerpo del trigger debería ser así:
Código SQL [-]
  if new.marca_id is null then
     new.marca_id = gen_id(marcas_marca_id, 1);
El trigger saltará, pero dado que IBX ha llamado internamente a este trigger, el campo marca_id ya tiene un valor, y el trigger no hace nada.

Saludos

Adrian Murua 03-05-2007 02:36:54

Gracias por responder...

El trigger esta creado de la forma que me indicas pues lo he creado con la ayuda del software EMS SQL Manager para IB /fB, te transcribo la declaracion que hace el EMS :

Código SQL [-]
SET TERM ^ ;

CREATE TRIGGER BI_MARCAS_MARCA_ID FOR MARCAS
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
  IF (new.MARCA_ID is null) THEN
      new.MARCA_ID = GEN_ID(MARCAS_MARCA_ID_GEN, 1);
END^

SET TERM ; ^

que puede estar sucediendo ??

Lepe 03-05-2007 12:16:19

Hasta el momento no me ha sucedido nada parecido.

En mi aplicación tengo exactamente lo mismo que tú (salvo que uso los componentes MDOLIB, que provienen de los IBX). No sabría decirte por qué falla, mis incrementos son consecutivos.

Supongo que deshabilitando el Trigger en el servidor, todo funcionará bien, pero si en algún momento usas un sql como este, fallará la inserción:
Código SQL [-]
insert into marcas (marca_id) values (null)

Saludos


La franja horaria es GMT +2. Ahora son las 17:19:00.

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