Foros Club Delphi

Foros Club Delphi (http://www.clubdelphi.com/foros/index.php)
-   Trucos (http://www.clubdelphi.com/foros/forumdisplay.php?f=52)
-   -   Verificar si hay cambios en Datasets (http://www.clubdelphi.com/foros/showthread.php?t=90372)

Arsenio 25-05-2016 19:19:43

Verificar si hay cambios en Datasets
 
En muchas ocasiones uso tablas de memoria (sobre todo las KbmMemTable) en conjunto con SQLDirect para trabajar con datos en memoria y en algún momento grabar los cambios generados en la base de datos, esa parte es facil, ambos son TDataSet, pero ¿que ocurre si la tabla tiene miles de registros y realmente no hubo ningún cambio en los datos? Con un "changed" no es suficiente porque eso cambia cuando uno entra a editar un registro, aunque realmente no cambie nada.

Para eso hice un método, que por más que recorre todos los Fields de la tabla y podría parecer lento, siempre es más rápido que ejecutar updates en la base, sobre todo si la base de datos es remota.

En el uses hay que agregar variants y DB.

Código Delphi [-]
class function TFunciones.HayCambiosQueRegistrar(qryOrigen, qryDestino: TDataSet; Modificar: boolean): Boolean;
var
  i: Integer;
  NombreCampo: String;
  rescmp: TVariantRelationship;
begin
  Result := False;
  for i := 0 to qryOrigen.FieldCount - 1 do
  begin
    NombreCampo := qryOrigen.Fields[i].FieldName;
    if (qryDestino.FindField(NombreCampo) <> nil) then
    begin
      rescmp := VarCompareValue(qryOrigen[NombreCampo], qryDestino[NombreCampo]);
      if (rescmp = vrNotEqual) or (not (rescmp = vrEqual)) then
      begin
        Result := True;
        //Si no hay que modificar directamente devuelvo true y sale del loop
        if not Modificar then
        begin
          Break;
        end
        else begin
          if not (qryDestino.State in [dsEdit, dsInsert]) then
            qryDestino.Edit;
          qryDestino[NombreCampo] := qryOrigen[NombreCampo];
        end;
      end;
    end;
  end;
end;

Para usarlo lo que hago es recorrer los registros de la tabla orígen y buscar si existe el registro en el destino, si existe chequea si hay cambios, si hay alguno edita el destino. Si no existe agrega el registro.

Código Delphi [-]
  TablaDetalle.First;
  while not TablaDetalle.EOF do
  begin
    if qryDetalle.Locate('ID', TablaDetalle.FieldByName('ID').AsInteger, []) then
    begin
      if TFunciones.HayCambiosQueRegistrar(TablaDetalle, qryDetalleRecepcion, False) then
      begin
        qryDetalle.Edit;
        TFunciones.CopiarRegistroActual(TablaDetalle, qryDetalleRecepcion);
        qryDetalle.Post;
      end;
    end
    else
    begin
      qryDetalle.Append;
      TFunciones.CopiarRegistroActual(TablaDetalle, qryDetalleRecepcion);
      qryDetalle.Post;
    end;    

    TablaDetalle.Next;
  end;
  
  //Y llamo al método que graba dentro de una transacción y usando ApplyUpdates
  ModuloDatos.GrabarEnTransaccion(qryDetalle);

En realidad, el código anterior no lo tengo igual, ya que el último parámetro realmente lo tengo en True, para que modifique la query si hay cambios, por lo que lo llamo así:

Código Delphi [-]
  if TFunciones.HayCambiosQueRegistrar(TablaDetalle, qryDetalleRecepcion, True) then
  begin
    qryDetalle.Post;
  end;

Espero que les sirva, cualquier duda me pueden consultar...

Casimiro Notevi 25-05-2016 23:27:18

^\||/^\||/^\||/

Neftali [Germán.Estévez] 26-05-2016 08:44:15

Gracias por el aporte.

^\||/^\||/^\||/


La franja horaria es GMT +2. Ahora son las 08:29:21.

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