Search code examples
oracle-databasedelphitclientdataset

ClientDataSet TBCDField rounding


I'm using Delphi 5 + BDE + Oracle. I have the following function:

class function TClientDataSetFactory.GetClientDataSet(
      const qryGen: TDataSet): TClientDataSet;
    var
       dspDados: TDataSetProvider;
    begin
       Result := nil;
       try
          try
             Result := TClientDataSet.Create(nil);
             dspDados := TDataSetProvider.Create(Result);
             dspDados.DataSet := qryGen;
             qryGen.Active := True;
             qryGen.First;

             Result.Data := dspDados.Data;

             Result.First;
          except
             on E: Exception do
             begin
                raise;
             end;
          end;
       finally
       end;
    end;

so, when a run this:

var
   qryGen: TQuery;
   cdsGen: TClientDataSet;
begin
   qryGen := nil;
   try
      try
         qryGen := CriaQuery();
         qryGen.SQL.Text :=
            'SELECT SUM(TOTAL) AS TOTAL FROM MYTABLE';
         cdsGen :=  TClientDataSetFactory.GetClientDataSet(qryGen);
         ShowMessageFmt('Total: %f', [cdsGen.FieldByName('TOTAL').AsFloat]);
      except
         on E: Exception do
         begin
            raise;
         end;
      end;
   finally
      if Assigned(qryGen) then FreeAndNil(qryGen);
   end;
end;

i got "159,00" but, if i run this:

ShowMessageFmt('Total: %f', [qryGen.FieldByName('TOTAL').AsFloat]);

i got "159,25".

can someone help me?


Solution

  • I solved the problem with another solution.

    type
       TInternalQuery = class(TQuery)
       protected
          procedure InternalInitFieldDefs; override;
       public
          constructor Create(AOwner: TComponent; const qryGen: TQuery); reintroduce;
       end;
    
    constructor TInternalQuery.Create(AOwner: TComponent; const qryGen: TQuery);
    var
       intCont: Integer;
    begin
       inherited Create(AOwner);
       Self.DatabaseName := qryGen.DatabaseName;
       Self.UpdateObject := qryGen.UpdateObject;
    
       Self.SQL.Text := qryGen.SQL.Text;
    
       for intCont := 0 to Self.ParamCount - 1 do
       begin
         Self.Params[intCont].Value := qryGen.Params[intCont].Value;
       end;  
    end;
    
    procedure TInternalQuery.InternalInitFieldDefs;
    var
       intCont: Integer;
    begin
       inherited InternalInitFieldDefs;
       for intCont := 0 to FieldDefs.Count - 1 do
       begin
          if (FieldDefs[intCont].Size = 0) and (FieldDefs[intCont].DataType = ftBCD) then
          begin
             FieldDefs[intCont].Precision := 64;
             FieldDefs[intCont].Size := 32;
          end;  
       end;  
    end;
    

    the problem is ((FieldDefs[intCont].Size = 0) and (FieldDefs[intCont].DataType = ftBCD)). when ClientDataSet is created, the field is truncated, because when oracle has a function like "SUM(TOTAL)" the result field is created with size 0, so the clientdataset handle the field as Integer field.