Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert datatype ftFloat to ftBCD

How can I convert a fieldtype from ftFloat to ftBCD;

I tried

for i := 0 to FDataSet.FieldCount - 1 do begin
      if FDataSet.Fields.Fields[i].DataType = ftFloat then begin
           FDataSet.Fields.Fields[i].DataType := ftBCD;
      end;
end;

But I get the error

[DCC Error]  E2129 Cannot assign to a read-only property

Is there a way I can convert all dataset field that ftFloat to ftBCD ?

like image 989
CiucaS Avatar asked Feb 12 '23 01:02

CiucaS


2 Answers

DataType is readonly Property of the Tfield created for a DataType. This is done from Fielddefs using DefaultFieldClasses: array[TFieldType] of TFieldClass from DB. If you need to change the DataType you will have to Free the Field and create anotherone fittinig your needs. Below is shown an exmaple how this could be done.

type
  TMyFieldInfo = Record
    FieldName: String;
    Size: Integer;
    DataType: TFieldType;
    FieldKind: TFieldKind;
  end;

type
  TFA= Array of TMyFieldInfo;

 Procedure GetFields(DS:Tdataset;var FA:TFA);
  var
    I: Integer;
  begin
    SetLength(FA, DS.FieldCount);
    for I := 0 to DS.FieldCount - 1 do
    begin
      FA[I].FieldName := DS.Fields[I].FieldName;
      FA[I].DataType := DS.Fields[I].DataType;
      FA[I].Size := DS.Fields[I].Size;
      FA[I].FieldKind := fkdata;
    end;
  end;

  Procedure SetFields(DS:Tdataset;var FA:TFA);
  var
    I: Integer;
    F:TField;
  begin
    DS.Fields.Clear;
    for I := Low(FA) to High(FA) do
    begin
      F := DefaultFieldClasses[FA[I].DataType].Create(DS);
      With F do
      begin
        FieldName := FA[I].FieldName;
        FieldKind := FA[I].FieldKind;
        Size := FA[I].Size;
        DataSet := DS;
      end;
    end;

  end;


procedure TForm6.Button1Click(Sender: TObject);
var
   L_FA: TFA;
   I:Integer;
begin
    MyDS.Open;  // open to get the Fielddefs.
    GetFields(MyDS,L_FA);
    MyDS.Close;  // close to be able to change the fields
    for I := Low(L_FA) to High(L_FA) do
      begin
         if L_FA[i].DataType = ftFloat then
            L_FA[i].DataType := ftBCD;
      end;
    SetFields(MyDS,L_FA);
    MyDS.Open;
end;
like image 167
bummi Avatar answered Feb 20 '23 04:02

bummi


Here is another way:

First, you need to dump the table into a file like this

ADOQuery.SaveToFile('C:\1.xml');

then find your field description in it, let's say it will be like this:

<s:datatype dt:type='float' dt:maxLength='8' rs:fixedlength='true' rs:maybenull='true'/>

and replace it with the other type description, like this:

<s:datatype dt:type='number' rs:dbtype='currency' dt:maxLength='25' rs:precision='25' rs:fixedlength='true' rs:maybenull='true'/>

now you need to load this file back, like this:

ADOQuery.LoadFromFile('C:\1.xml');
like image 26
Yevgeniy Afanasyev Avatar answered Feb 20 '23 03:02

Yevgeniy Afanasyev