[Lazarus] Storing currency or real types in a database

Zaher Dirkey parmaja at gmail.com
Sat May 30 13:23:42 CEST 2009


I used Firebird SQL 2.x and use numeric(18,4) for Currency, i have no
problem because Firebird work on numeric(18,4) as INT64 with special
convert to try to get and put at the client, in fact Delphi/FPC and
Firebird both internally take the Currency as Int64 but when convert
it to print or to assign to another kind of variable, it divided to 10
or multiply with 10.

This is  a peace of my code
------
procedure TFBCSQLVAR.SetAsCurrency(Value: Currency);
begin
    if IsNullable then
      IsNull := False;
    FSQLVAR.sqltype := SQL_INT64 or (FSQLVAR.sqltype and 1);
    FSQLVAR.sqlscale := -4;
    FSQLVAR.sqllen := SizeOf(Int64);
    FSQLVAR.SetDataSize(0, FSQLVAR.sqllen);
    PCurrency(FSQLVAR.sqldata)^ := Value;
    Modified := True;
end;

function TFBCSQLVAR.GetAsCurrency: Currency;
...
case FSQLVAR.SqlDef of
    SQL_INT64:
       Result := FBScaleCurrency(PInt64(FSQLVAR.sqldata)^, FSQLVAR.sqlscale);


function FBScaleCurrency(Value: Int64; Scale: Integer): Currency;
var
  i: Integer;
begin
//Here we know 10000 in Int64 = 1 in Currency so
//if we have scale -4 that mean not need to * or / just tupe casting
//or make bias of -4 to correct the problem, this code must fast than
FBScaleDouble
  Scale := Scale + 4;
  if Scale > 0 then
  begin
    for i := 1 to Scale do
      Value := Value * 10;
  end
  else if Scale < 0 then
  begin
    for i := 1 to -Scale do
      Value := Value div 10;
  end;
  Result := PCurrency(@Value)^;
end;
---------------------

-- 
Zaher Dirkey




More information about the Lazarus mailing list