Bottom Line: Since you have to "support" multiple DBMS (are you using TSQLConnector?), you'll probably have to write individual code for each connection-type
Kind of like (Pseudo-Code)
If ConnType='SQLite' And FieldType='Float' Then ReadAsFloat
Down-Side: You'd have to know if the Field you want to read is a "real" Float-Value (Say, Money-Balance) or a DateTime-Value
To support different RDBMS I simply create the right (subclass of) TSQLConnection object according database type (SQLITE -> TSQLite3Connection, MSSQL -> TMSSQLConnection, ...). Once this is done TSQLTransation and TSQLQuery are always the same. And from my persective also TParam and TField are always the same, despite actual ones could be subclasses to adapt to actual connection type.
And for queries: given the SQL query, each parameter/field has a fixed and known datatype. So not need to do "If ConnType='SQLite' And FieldType='Float' Then ReadAsFloat".
For example, with this update query:
query.SQL := 'update T0003_ConfMachines'
+ ' set'
+ ' name = :name'
+ ' , deleted = :deleted'
+ ' , machineType = :machineType'
+ ' , machineCode = :machineCode'
+ ' , machineAcquisitionType = :machineAcquisitionType'
+ ' , machineAcquisitionDirectory = :machineAcquisitionDirectory'
+ ' , machineImportAtStartup = :machineImportAtStartup'
+ ' , machineAcquisitionFileName = :machineAcquisitionFileName'
+ ' , machineAcquisitionSerialIdentifier = :machineAcquisitionSerialIdentifier'
+ ' , machineHasEnergyMeasuringDevice = :machineHasEnergyMeasuringDevice'
+ ' , listeningMode = :listeningMode'
+ ' , listeningPort = :listeningPort'
+ ' where id = :id';
for each parameter I know what is going to be the datatype (regardless of RDBMS), so I'll write
query.ParamByName('name').AsString := 'value';
query.ParamByName('listeningMode').AsInteger := 4;
...
Same applies to select. For each field I know pascal datatype so I will simple ask for it.
query.SQL := 'select eventDate from T0041_MachineLog where (refMachine = :refMachine) and (id = :id)';
query.ParamByName('refMachine').AsInteger = 4;
query.ParamByName('id').AsLargeInt= 214;
query.Open();
eventDate := query.FieldByName('eventDate').AsDateTime;
Basically my perspective is: in code each field has its own fixed data type, then in each RDBMS it has to be choosen the "datatype" capable of storing/suppyling the correspondent correct datatype. Always very easy and working, except with SQLite that sees datatypes as something less strict than other RDBMS.