Delphi + Firebird (using DBExpress): aggregate issue with TFMTBCDField - delphi

I have a table with a NUMERIC(15,2) field in my database. In Delphi, I use the trio TSQLDataset + TDataSetProvider + TClientDataSet. This field is created as TFMTBCDField. The problem is that I need to use an Aggregate field in my ClientDataSet in order to sum the values and for some reason it's not calculated correctly (see image below). However, if I set my field type as DOUBLE PRECISION in my database (Delphi creates the field as TFloatField in dataset) the aggregate works as expected.
PS: I've read somewhere that is better using NUMERIC than DOUBLE PRECISION in Firebird.
I'm using Delphi XE7 and Firebird 2.5
How do you deal with this issue?
Thanks.

Related

get fieldtype of DBF File

I am reading field type of DBF file. I am also creating DBF file. I am using oledb reader to get filedtype. Reader always return decimal type weather i set Numeric,Float or double. Why is it so? Why reader is not returning same type as stored in DBF?
Different providers may map the physical field types of a DBF to different OLEDB field types.
Another issue is the SQL result type guessomatic that kicks in if you select expressions (select amt * 0.01 from foo) instead of naked fields and do not cast the result to some type explicitly (select cast(amt * 0.01 as currency) from foo). Again, different providers/engines may give different results in such a situation; some - like the VFP9 provider - allow explicit casts, some do not.
You may get better results if you switch to a different provider. For example, the Visual FoxPro 9.0 OLEDB provider - which is freely available for download - maps the Fox DBF field types 'I' (integer), 'B' (double), 'Y' (currency) and 'N' (numeric) faithfully to the corresponding OLEDB/ADO field types adInteger, adDouble, adCurrency and adNumeric. On the other hand, the Fox provider understands only the Fox field types and legacy DBF types corresponding to Clipper and dBASE 3 or thereabouts. It cannot read tables produced by newer dBASE versions.
Several of the freely available OLEDB providers understand some DBF dialect or other; which one is most suitable would depend on the type of your DBF files.
The DBF file structure is fairly simple; depending on your application it might make sense to pull the meta data directly from the field definitions in the DBF header.

Delphi XE7 - Field FTBcd - Number is out of Range

I am migrating an application from Delphi 2010 to Delphi XE7 that it uses some old Paradox Table with BDE. I have some fields formed BCD (#) Size 4 that in Delphi 2010 were managed as.asfloat
example
TABELLA1.Fieldbyname('FIELDBCD').AsFloat: = TABELLA2.Fieldbyname('Number').AsFloat;
without any problem.
In the converted program any type of assignment goes to error signalling EDBEngineError Number is out of range.... this even if I simply digit the value from a DBGrid.
Do you know of BUG in the management of the fields BCD in Delphi XE7 or must they have managed in different way?
Thanks
Mirko
The ask is old, but I was still facing this problemn these days. I suggest confirm three properties.
precision - (It need to be the significative part and the fractionary part). For example, in data base the field is numeric(8,4), so here the correct value is 12
size - (Just the faccionary part of the number). In our example, the correct value is 4
DisplayWidth - Here we uses the value of the precision + 1, for the comma.

Delphi BCD Field incorrectly displayed if DisplayFormat contains the dot

I'm having a weird problem with an old project that's still being maintained with Delphi 7.
I have a TFMTBCDField component, representing Firebird Numeric Field (called GROSSPRICE).
It's value gets calculated on the server side (by the Firebird SQL server).
Due to a 27% tax rate the values are often like 4999.9999 that I'd like to display values rounded.
The strange thing is that if I set the DisplayFormat on that field to a value that has the dot inside (eg: '0.##') then 4999.9999 gets displayed as "5" (Should be either "5000" or "4999.99"). The same thing works with Currency fields as expected.
I have attached some images with examples as well. Do you know why is that happening, and (if possible) how to resolve it?

Using decimal data type to work with monetary values with db2 and delphi 2010

I'm using delphi 2010 with db2 9.7 Express-C and I have a database that has several fields of decimal type to work with monetary values. Now I see that there are some problems using it, like the 9.20 value displays the value 9.19999980926514 in my front-end. I need to change all the fields in my database to DECFLOAT or is there a function, property in tfield or other alternative to solve it ?
Thanks.
Davis
working directly with monetary decimals is almost always a problem. due to different conversions made from the database to your front-end application, it is possible to lose or to gain(this applies to most of the financial systems also - see bankers rounding).
I suggest you to use the RoundTo function before making operations/display/etc. A very good article about rounding http://docwiki.embarcadero.com/RADStudio/XE2/en/Floating-Point_Rounding_Issues
Another suggestion will be using of the Currency type. Here is a question on SO with good explanation about this type How to avoid rounding problems when comparing currency values in Delphi?

Sybase 12.5-BDE-ADO "where myColumn=null" failure

We have an old application that reads in SQL text files and sends them to Sybase ASE 12.51. Our legacy app was written in Delphi 5 and is using the BDE TQuery component for this process and accessing Sybase with the BDE SQLinks for Sybase.
Pseudo code:
SQLText=readSQLFile;
aTQuery.SQL.add(SQLText);
aTQuery.ExecSQL;
Recently we moved our DB access layer to the Delphi XE ADO implementation - TADOQuery, using the Sybase supplied ADO provider, still using same model:
SQLText=readSQLFile;
aTADOQuery.SQL.add(SQLText)
aTADOQuery.ExecSQL;
After migrating to ADO, we discovered that certain data was missing. We traced the failure to this SQL construct:
Select myColumn from myTable
Where tranID = null
Knowing that this construct is sematically questionable at best, I did a 'double take' when I saw this code, but Sybase 12.5 accepts it - however using ADO, this segment fails.
We decided to change:
Where tranID = null
to
Where tranID is null
Then the missing data was loaded - problem solved, for this segment and several others as well.
Does anyone have an explanation for this behavior? Where/why did ADO apparently intercept and reject this seqment whereas the BDE passed it thru?
TIA
"NULL" has a very special meaning, and SQL needs a special handling. You can't compare a value to "NULL", that's why there is the special operator IS (NOT) NULL to check for it. An exhaustive explanation would take some space, here a simple explanation.
From a "mathematical" point of view, NULL can be thought as "infinity". You can't compare two infinite values easily, for example think about the set of integer numbers and even numbers. Both are infinite, but it seems logical the former is larger than the latter. All you can say IS both sets are infinite.
That's also helps to explain for example why 1 + NULL returns NULL and so on (usually only aggregate functions like SUM() ecc. may ignore NULL values - ignore, not turn NULLs into zeroes).
This metaphor may not hold true in sorting, because some databases choose to consider NULL less than any value (some kind of -infinity and thereby returning them first in ascending order), other the other way round. Some have an option to set where to return NULLs.
Check your database documentation about NULL arithmetics and NULL comparisons. field = NULL should have never been used, don't know if Sybase accepts it, but most SQL implementations don't, and I guess it is not SQL standards compliant. It is far better to get used to the IS (NOT) NULL syntax.
Update: Sybase has a "set ansinull" option, from the documentation (always RTFM!), in 12.5.1 it was expanded to disallow the '= NULL' syntax (when set to ON to make it compliant with SQL standards). When set to OFF '= NULL' works as 'IS NULL'.
Maybe the SQL Links or the ADO provider set it to one value or the other.

Resources