Page 1 of 1
FMTBcd round issue
Posted: Tue 16 Aug 2011 10:11
by alexer
Delphi7+dbexpsda(ver 4.80)
Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
begin
SQLConnection1.Open;
SQLStoredProc1.SQLConnection:=SQLConnection1;
SQLStoredProc1.StoredProcName:='FU_TEST';
SQLStoredProc1.ExecProc;
ShowMessage(SQLStoredProc1.Params[1].AsString);
end;
SQL Server 2008R2
Code: Select all
ALTER procedure [dbo].[FU_TEST](
@REST_AMOUNT numeric(22,7) output
) as begin
set @REST_AMOUNT = 4.95904
end
Returns 4.959
Code: Select all
ALTER procedure [dbo].[FU_TEST](
@REST_AMOUNT double precision output
) as begin
set @REST_AMOUNT = 4.95904
end
Returns 4.95904
Posted: Wed 17 Aug 2011 10:23
by Dimon
To solve the problem set the EnableBCD option to False like this:
Code: Select all
SQLConnection.Params.Values['EnableBCD'] := 'False';
Posted: Wed 17 Aug 2011 17:28
by alexer
Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
begin
SQLConnection1.Params.Values['EnableBCD'] := 'False';
SQLConnection1.Open;
SQLStoredProc1.SQLConnection:=SQLConnection1;
SQLStoredProc1.StoredProcName:='FU_TEST';
SQLStoredProc1.ExecProc;
ShowMessage(SQLStoredProc1.Params[1].AsString);
end;
Result still 4.959
Please check it.
P.S. If i disable BCD how Delphi will work with numeric(22,7)? Float doesnt have enough scale for it.
Posted: Thu 18 Aug 2011 07:09
by Dimon
The problem is that the EnabledBCD option is an extended option of DbxSda. Delphi 7 has restriction of dbExpress for setting such options.
In order to overcome restrictions of dbExpress, DbxSda provides the TCRSQLConnection component. Extended options are available with TSQLConnection only at run time. To convert quickly from TSQLConnection to TCRSQLConnection you can use the "Convert to TCRSQLConnection" item of component's pop-up menu.
If you need to use TSQLConnection, then you should use the following code at run time:
Code: Select all
const
coEnableBCD = TSQLConnectionOption(102);
. . .
SQLConnection1.SQLConnection.SetOption(coEnableBCD, Integer(False));
You can find more detailed information about it in Readme.html.
Posted: Thu 18 Aug 2011 07:47
by alexer
Whats about my P.S?
As i say:
MSSQL
Code: Select all
ALTER procedure [dbo].[FU_TEST](
@REST_AMOUNT numeric(22,7) output
) as begin
set @REST_AMOUNT = 12345678901234.1234567
end
Delphi7
Code: Select all
SQLConnection1.Open;
SQLConnection1.SQLConnection.SetOption(coEnableBCD, Integer(False));
SQLStoredProc1.SQLConnection:=SQLConnection1;
SQLStoredProc1.StoredProcName:='FU_TEST';
SQLStoredProc1.ExecProc;
ShowMessage(SQLStoredProc1.Params[1].AsString);
Returns 12345678901234.1
We really need normal FMTBcd!
Same problem was with your Oracle driver, it was fixed.
Posted: Thu 18 Aug 2011 08:26
by Dimon
The point is that TSQLStoredProc passes the fldBCD data type for the REST_AMOUNT parameter instead of fldFMTBCD to our driver. You can see this processing in the SetProcedureParams procedure of the SqlExpr unit. Therefore SQL Server returns the parameter value as Currency and truncates the data.
We cannot influence this behaviour of TSQLStoredProc.
Posted: Thu 18 Aug 2011 10:37
by alexer
But you can force field change from Bcd to FMTBcd on prepare, it will be more correct
Posted: Mon 22 Aug 2011 09:29
by alexer
Why you fix this bug in Oracle driver, but dont want to fix it in MS?
Posted: Mon 22 Aug 2011 14:23
by Dimon
We have fixed this problem. This fix will be included in the next DbxSda build.
Posted: Mon 22 Aug 2011 17:17
by alexer
Thanks