Hello,

The following patches fixes the lack of sqlscale var when writing decimal and numeric fields to ib/fb databases. I've used the same approach used to read such fields, ie, intpower.

Patch 1 has also a small improvement regarding the read of the XSQLVAR record, patch 2 only fixes the sqlscale.

Both patches are against fixes_2_2. Let me know if it's still useful, otherwise I will checkout trunk and create another patch.

--
Joao Morais
Index: fcl-db/src/sqldb/interbase/ibconnection.pp
===================================================================
--- fcl-db/src/sqldb/interbase/ibconnection.pp  (revision 11044)
+++ fcl-db/src/sqldb/interbase/ibconnection.pp  (working copy)
@@ -693,6 +693,7 @@
 var ParNr,SQLVarNr : integer;
     s               : string;
     i               : integer;
+    si              : smallint;
     li              : LargeInt;
     currbuff        : pchar;
     w               : word;
@@ -736,30 +737,40 @@
 {$R+}
   end;
 
+var
+  VSQLVar: XSQLVAR;
 begin
 {$R-}
   with cursor as TIBCursor do for SQLVarNr := 0 to 
High(ParamBinding){AParams.count-1} do
     begin
     ParNr := ParamBinding[SQLVarNr];
+    VSQLVar := in_sqlda^.SQLvar[SQLVarNr];
     if AParams[ParNr].IsNull then
       begin
-      If Assigned(in_sqlda^.SQLvar[SQLVarNr].SQLInd) then
-        in_sqlda^.SQLvar[SQLVarNr].SQLInd^ := -1;
+      If Assigned(VSQLVar.SQLInd) then
+        VSQLVar.SQLInd^ := -1;
       end
     else
       begin
-      if assigned(in_sqlda^.SQLvar[SQLVarNr].SQLInd) then 
in_sqlda^.SQLvar[SQLVarNr].SQLInd^ := 0;
+      if assigned(VSQLVar.SQLInd) then VSQLVar.SQLInd^ := 0;
 
-      case (in_sqlda^.SQLvar[SQLVarNr].sqltype and not 1) of
+      case (VSQLVar.sqltype and not 1) of
         SQL_LONG :
           begin
-          i := AParams[ParNr].AsInteger;
-          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if VSQLVar.sqlscale = 0 then
+              i := AParams[ParNr].AsInteger
+            else
+              i := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-VSQLVar.sqlscale));
+            Move(i, VSQLVar.SQLData^, VSQLVar.SQLLen);
           end;
         SQL_SHORT :
           begin
-          i := AParams[ParNr].AsSmallInt;
-          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if VSQLVar.sqlscale = 0 then
+              si := AParams[ParNr].AsSmallint
+            else
+              si := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-VSQLVar.sqlscale));
+            i := si;
+            Move(i, VSQLVar.SQLData^, VSQLVar.SQLLen);
           end;
         SQL_BLOB :
           SetBlobParam;
@@ -767,27 +778,30 @@
           begin
           s := AParams[ParNr].AsString;
           w := length(s); // a word is enough, since the max-length of a 
string in interbase is 32k
-          if ((in_sqlda^.SQLvar[SQLVarNr].SQLType and not 1) = SQL_VARYING) 
then
+          if ((VSQLVar.SQLType and not 1) = SQL_VARYING) then
             begin
-            in_sqlda^.SQLvar[SQLVarNr].SQLLen := w;
-            
ReAllocMem(in_sqlda^.SQLvar[SQLVarNr].SQLData,in_SQLDA^.SQLVar[SQLVarNr].SQLLen+2);
-            CurrBuff := in_sqlda^.SQLvar[SQLVarNr].SQLData;
+            VSQLVar.SQLLen := w;
+            ReAllocMem(VSQLVar.SQLData, VSQLVar.SQLLen+2);
+            CurrBuff := VSQLVar.SQLData;
             move(w,CurrBuff^,sizeof(w));
             inc(CurrBuff,2);
             end
           else
-            CurrBuff := in_sqlda^.SQLvar[SQLVarNr].SQLData;
+            CurrBuff := VSQLVar.SQLData;
           Move(s[1], CurrBuff^, w);
           end;
         SQL_TYPE_DATE, SQL_TYPE_TIME, SQL_TIMESTAMP :
-          SetDateTime(in_sqlda^.SQLvar[SQLVarNr].SQLData, 
AParams[ParNr].AsDateTime, in_SQLDA^.SQLVar[SQLVarNr].SQLType);
+          SetDateTime(VSQLVar.SQLData, AParams[ParNr].AsDateTime, 
VSQLVar.SQLType);
         SQL_INT64:
           begin
-          li := AParams[ParNr].AsLargeInt;
-          Move(li, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if VSQLVar.sqlscale = 0 then
+              li := AParams[ParNr].AsLargeInt
+            else
+              li := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-VSQLVar.sqlscale));
+            Move(li, VSQLVar.SQLData^, VSQLVar.SQLLen);
           end;
         SQL_DOUBLE, SQL_FLOAT:
-          SetFloat(in_sqlda^.SQLvar[SQLVarNr].SQLData, AParams[ParNr].AsFloat, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+          SetFloat(VSQLVar.SQLData, AParams[ParNr].AsFloat, VSQLVar.SQLLen);
       else
         
DatabaseErrorFmt(SUnsupportedParameter,[Fieldtypenames[AParams[ParNr].DataType]],self);
       end {case}
Index: fcl-db/src/sqldb/interbase/ibconnection.pp
===================================================================
--- fcl-db/src/sqldb/interbase/ibconnection.pp  (revision 11044)
+++ fcl-db/src/sqldb/interbase/ibconnection.pp  (working copy)
@@ -693,6 +693,7 @@
 var ParNr,SQLVarNr : integer;
     s               : string;
     i               : integer;
+    si              : smallint;
     li              : LargeInt;
     currbuff        : pchar;
     w               : word;
@@ -753,13 +754,20 @@
       case (in_sqlda^.SQLvar[SQLVarNr].sqltype and not 1) of
         SQL_LONG :
           begin
-          i := AParams[ParNr].AsInteger;
-          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if in_sqlda^.SQLvar[SQLVarNr].sqlscale = 0 then
+              i := AParams[ParNr].AsInteger
+            else
+              i := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-in_sqlda^.SQLvar[SQLVarNr].sqlscale));
+          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_sqlda^.SQLvar[SQLVarNr].SQLLen);
           end;
         SQL_SHORT :
           begin
-          i := AParams[ParNr].AsSmallInt;
-          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if in_sqlda^.SQLvar[SQLVarNr].sqlscale = 0 then
+              si := AParams[ParNr].AsSmallint
+            else
+              si := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-in_sqlda^.SQLvar[SQLVarNr].sqlscale));
+            i := si;
+          Move(i, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_sqlda^.SQLvar[SQLVarNr].SQLLen);
           end;
         SQL_BLOB :
           SetBlobParam;
@@ -783,8 +791,11 @@
           SetDateTime(in_sqlda^.SQLvar[SQLVarNr].SQLData, 
AParams[ParNr].AsDateTime, in_SQLDA^.SQLVar[SQLVarNr].SQLType);
         SQL_INT64:
           begin
-          li := AParams[ParNr].AsLargeInt;
-          Move(li, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
+            if in_sqlda^.SQLvar[SQLVarNr].sqlscale = 0 then
+              li := AParams[ParNr].AsLargeInt
+            else
+              li := Round(AParams[ParNr].AsCurrency * IntPower(10, 
-in_sqlda^.SQLvar[SQLVarNr].sqlscale));
+          Move(li, in_sqlda^.SQLvar[SQLVarNr].SQLData^, 
in_sqlda^.SQLvar[SQLVarNr].SQLLen);
           end;
         SQL_DOUBLE, SQL_FLOAT:
           SetFloat(in_sqlda^.SQLvar[SQLVarNr].SQLData, AParams[ParNr].AsFloat, 
in_SQLDA^.SQLVar[SQLVarNr].SQLLen);
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to