Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   Algo curioso con las tablas en firebird (https://www.clubdelphi.com/foros/showthread.php?t=75766)

novato_erick 17-09-2011 20:21:32

Algo curioso con las tablas en firebird
 
Hola como están todos?

Mi caso es el siguiente:

Tengo un formulario llamado frmProveedores el cual Agrego los atributos correspondientes como su respectivo ID, NIF, contacto, etc.

bueno aplico el siguiente código simple para guardarlo en el btnGuardar:

Código Delphi [-]
procedure TFrmProveedores.btnGuardarClick(Sender: TObject);

begin
  if Application.MessageBox('¿Desea Agregar Otro?', 'Confirmación',
    MB_ICONQUESTION OR MB_YESNO) = ID_NO then
  begin
    dmacceso.cdsProveedores.Applyupdates(0);
    Close;
  end
  else
  Begin
    dmacceso.cdsProveedores.Active := False;
    dmacceso.cdsProveedores.Active := True;
    dmacceso.cdsProveedores.Last;
    dmacceso.cdsProveedores.Insert;
  end;

end;

Reviso mi aplicación lo busco en mi lista de proveedores y ahí esta no hay problema para ir mas aya en la verificación abro el Firebird ISQL Tool para ver los datos y si están.

Bueno el problema esta en que al abrir otro formulario para agregar cuentas a un proveedor me aparece.

Pero al darle el post al data set dice que el id_proveedor esta vacio.

pero si cierro la aplicación y vuelvo abrirla abriendo el formulario de agregar cuenta ahi si no hay problema.

Alguien ha pasado por esto?

Saludos

novato_erick

duilioisola 18-09-2011 09:47:07

Veo que uno de los datos que agregas es el ID.
Puede que agregues ID=0 y luego los triggers se encarguen de darle el siguiente número al campo.
En ese caso el Dataset habrá dado la instrucción a FB de que guarde el registro y ha guardado una copia en memoria, para no tener que releerlo.
Mientras no cierres esa tabla/trasnaccion/conexión, el Dataset no se enterará de que en la base de datos se han modificado los datos insertados.

Tienes dos opciones si ese es el problema:
1. Generas el ID antes de insertar y lo asignas al campo.
2. Insertas ID=0 y luego refrescas los datos. No recuerdo la instrucción, pero se que existe.

Si es un generador, puedes tener un SQL que ejecute algo como lo siguiente:

Código SQL [-]
SELECT gen_id(NOMBRE_GENERADOR) from RDB$DATABASE
RDB$DATABASE tiene siempre un solo registro.
Con esto y un trigger que haga más o menos esto:
Código SQL [-]
TRIGGER BEFORE INSERT
begin
  if (new.ID is null) or (new.ID =0) then
     new.ID = gen_id(NOMBRE_GENERADOR);
  ... 
end

Delphius 18-09-2011 20:16:37

Para mi que el problema está en el manejo de las transacciones y/o en el nivel de aislamiento de las mísmas.
¿Por casualidad, haces commit o commitretaing después del post? ¿Qué nivel de aislamiento tienes configurados para las transacciones?

Saludos,

novato_erick 01-10-2011 19:23:36

Este es mi procedimiento en el boton de guardar corrijanme ya que no he logrado refrescar los datos sin tener que cerrar toda la aplicación.

Código Delphi [-]
procedure TFrmProveedores.Button1Click(Sender: TObject);

begin
  if Application.MessageBox('¿Desea Agregar Otro?', 'Confirmación',
    MB_ICONQUESTION OR MB_YESNO) = ID_NO then
        begin
          dmacceso.cdsProveedores.Applyupdates(0);
          Main.FrmPrincipal.iCloseClick(FrmProveedores);
          Close;
        end
         else
            Begin
              dmacceso.cdsProveedores.Active := False;
              dmacceso.cdsProveedores.Active := True;
              dmacceso.cdsProveedores.ApplyUpdates(0);
              dmacceso.cdsProveedores.Last;
              dmacceso.cdsProveedores.Insert;
            end;

end;

utilizo directamente dbEdit mi conexion es dbexpress. y mi base da datos firebird.

Saludos

José Luis Garcí 02-10-2011 09:16:47

hola novato_erick, te pongo el código de como lo hago yo

Código Delphi [-]
procedure TFDominios.SpeedButton2Click(Sender: TObject);
//------------------------------------------------------------------------------
//************************************************************[  Grabar  ]******
//------------------------------------------------------------------------------
begin
      try  //1
       //Aquí validamos y hacemos todo lo que sea necesario antes de Grabar, como por ejemplo confirmar el agregar otro registro, etc
       FCreadorTablas.post;   //Graba los Datos
       FCreadorTablas.IBTransaction1.CommitRetaining; //Confirma la Transición, haciendo visible el dato para todos, ojo si tienes un querry, es mejor reactivarlo
       //Aquí debes hacer, lo posterior a grabar, como borrar datos de componentes no conectado a la B.D., poner visible/enable o no botones, paneles, etc

     except //1
       on E: Exception do  //Captura el Mensaje de error
       begin
         //Mostramos el mensaje (DOM G-2) es mi identificador de error, lo que hago es DOM son las tres primeras letras del Form (Dominios) en este caso G, el modulo grabar y 2,
         //  por que en este caso dentro de grabar seria el segundo control de excepciones (he eliminado el otro para no complicar las cosas, ya que grababa en dos módulos diferentes)
         ShowMessage('DOM G-2 Se ha producido un error, y no se ha creado el Dominio,'+#13+#10+
                     'Error: ['+E.Message+']');  //E.Message sería el mensaje de error original
         FCreadorTablas.IBTransaction1.RollbackRetaining;  // Si se ha producido un error, desbloqueamos los valores introducidos para que no siga los datos activos, ya que nos
                                                                             // podría dar problemas e incluso bloquearnos la aplicación
       end;
     end;//1
end;
//1 Es muy importante una cadena Try Except end para controlar cuando se te produzca un error, no quede el sistema con fallos e incluso bloqueado

novato_erick 09-10-2011 21:27:55

hola he estado trabajando con transacciones como me lo han recomendado primero que nada les quiero agradecer a los que me han contestado en este foro Gracias Sres...

Leyendo un poco más sobre las transacciones en delphi el cual el libro Delphi 7 del autor Marco Cantú he realizado el siguiente procedimiento:
Código Delphi [-]
procedure TFrmProveedores.Button1Click(Sender: TObject);
var
  TB : TTransactionDesc;
begin
  if Application.MessageBox('¿Desea Agregar Otro?', 'Confirmación',
    MB_ICONQUESTION OR MB_YESNO) = ID_NO then
        begin
        TB.TransactionID := 1;
        TB.IsolationLevel := xilREADCOMMITTED;
        dmconexion.sqlDB.StartTransaction(TB);
        end;
            try
               dmacceso.cdsProveedores.Applyupdates(0);
               dmconexion.sqlDB.Commit(TB);
               Main.FrmPrincipal.iCloseClick(FrmProveedores);
               Close;
            except
               dmconexion.sqlDB.Rollback(TB);
end;
 
end;

veo y reviso en la base de datos y ok esta bien pero aun asi sigo con el problema que si deseo por ejemplo agregar otros atributos al registro desde otro formulario por ejemplo llamado cuenta de proveedor no puedo seleccionarlo pero si aparece en el registro.

Que sucederá alguna idea?

Saludos

novato_erick


La franja horaria es GMT +2. Ahora son las 04:58:36.

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