Delphi – Change field to calculated field at runtime. Is this a good practice?-Collection of common programming errors
Did anyone notice this bit of code?
procedure TSampleForm.btnOpenClick(Sender: TObject);
begin
if dsSample.Active then
dsSample.Close;
dsSample.SQL.text:='select id,state,oldstate,"" as txtState,"" as txtOldState from states where active=1';
dsSample.Open;
end;
He’s not changing a Database Field to a Calculated Field…He’s changing a Non Existent Field to a Calculated Field. He knows the field type…it’s going to be a string…So is it a big deal…No…Is it a hack…Yes…You can do the same thing in SQL with Cast…Matter of fact I’ve never really seen a reason to use Calculated Fields…I can usually do the same thing easier in the SQL.
I added more information after a bit more digging on why not to do either…
sabri.arslan code…to create the Fields…from the FieldList…also has problems as missing setting up keys and handling heirchy fields.
dmp:=DataSet.FieldDefs.Items[i].FieldClass.Create(self);
Then we have Francois…
if you call the none hacked code you get this...
for I := 0 to MyQuery.FieldDefList.Count - 1 do
with MyQuery.FieldDefList[I] do
if (DataType ftUnknown) and not (DataType in ObjectFieldTypes) and
not ((faHiddenCol in Attributes) and not MyQuery.FIeldDefs.HiddenFields) then
CreateField(Self, nil, MyQuery.FieldDefList.Strings[I]);
umm…missing SetKeyFields will this cause unforseen behavior? Also if your ObjectView property is set to True…your Dataset will not behave properly for hierarchiacally fields…It looks to be safer to just call the Hack to CreateFields than to use his code…other than you must be positive that your dataset component never calls this code…
CreateField calls CreateFieldComponent and you get Result := FieldClassType.Create(Owner) for your TField
Taken from the Borland help of TFieldDef “A field definition has a corresponding TField object, but not all TField objects have a corresponding field definition. For example, calculated fields do not have field definition objects.”
So I ask you…are you positive your not introducing unknown behavior by creating the CalculatedField on the fly? Are you positive that the Fields haven’t been created yet or won’t be created later? (There’s a bug in sabri.arslan code because he does the open/after open…He’s overwritting the original TFields…, I don’t see why we need to recreate the TField’s for the already opened dataset)
So what happens when CreateFields is called by the dataset(The BDE and ADO do this on InternalOpen and check to make sure that their are no values in Fields…do all the Dataset components do it this way? They don’t have to). What happens to the Fields that you have already created…are they overwritten? I didn’t see any code in the TDataset or TFieldDef that checked if the TField had already been created for the coorsponding TFieldDef other than a check to DefaultFields(if Fields has a value).