tcmdvm,
I guess if you want more precision it is best to use a NUMERIC field.
annoying isn't it? We've no clue how to fix that! Only idea/feeling i have: We've to know the count of decimal digits of the value we want update. Than we can overwrite the scale for each update. Any idea how to extract that?
For me the whole story is nightmare. I can't find a FB document or a "known issues" list which points me to the DECIMAL vs. NUMERIC diffs, even if the german suggest theire is one (years ago).
EDIT!!!!:
I found the reason! Not firebird was the trouble-maker, nope function Trunc(): Int64;
I've implemented a workaround:
Code: Select all
procedure TZParamsSQLDA.UpdateBigDecimal(const Index: Integer; Value: Extended);
var
SQLCode: SmallInt;
TempStr: string;
TempFloat: Extended;
begin
CheckRange(Index);
{$R-}
with FXSQLDA.sqlvar[Index] do
begin
if (sqlind <> nil) and (sqlind^ = -1) then
Exit;
SQLCode := (sqltype and not(1));
if (sqlscale < 0) then
begin //http://code.google.com/p/fbclient/wiki/DatatypeMapping
case SQLCode of
SQL_SHORT : PSmallInt(sqldata)^ := Trunc(Value * IBScaleDivisor[sqlscale]);
SQL_LONG : PInteger(sqldata)^ := Trunc(Value * IBScaleDivisor[sqlscale]);
SQL_INT64,
SQL_QUAD : //PInt64(sqldata)^ := Trunc(Value * GetIBScaleDivisor(sqlscale)); EgonHugeist: Trunc seems to have rounding issues!
begin
if sqlscale > 0 then
TempFloat := RoundTo(Value, sqlscale*-1)
else
TempFloat := RoundTo(Value, sqlscale);
TempStr := FloatToStrF(TempFloat * GetIBScaleDivisor(sqlscale), ffFixed, 18, 0);
//remain issues if decimal digits > scale than we've school learned rounding success randomly only
//each aproach did fail: RoundTo(Value, sqlscale*-1), Round etc.
//so the developer has to take care for this case
PInt64(sqldata)^ := StrToInt64(TempStr);
end;
...
But read my comments toooooo (:
Patch done R2282 \testing7.1 (SVN)