上次在一个客户那发现一个问题。
SQL2000 的Money13500.0000乘以 10000后转换成 c# Float 再转换成 SQL2005 的money类型时
发现得到的值是135009021.0000. float转换money的精度缺失应该出现在小数位啊。现在整数位置多出9021是怎么回事?
具体情况记录:
首先我在SQL2000中通过存储过程获取Table1的数据(Table1字段FAmt是Money类型的)。
然后通过WebService保存到另一个SQL2005的数据库表Table2中。(WebServices我不能修改)
WebServices中将Table1中的数据用Float类型作为参数传递给SQL2005上的存储过程逐条保存记录的.
调用的存储过程保存到表Table2中.表Table2的FAmt字段也是Money类型的。
现在有个问题:
1.我发现传递过去保存到SQL2005中的数据,小数位基本上都不精确了。
例如:13500.0000 传过去转换两次(money-float-money)后 就变成13499.9998
123.1200 传过去转换两次(money-float-money)后 就变成123.0000
于是我认为是float不是精确类型导致的。于是我将Table1中的数据先乘与10000,将小数数据变成整数。
(我认为这样传递过去的数应该就是1231199.9998,这样我先取整数位取整后再除以10000就得到原值了)
可是事实并不是想象那样.我乘完10000后发现135000000.0000传递过去的值就变成135009021了.这然我觉得很奇怪.
float是不精确的理论上应该只影响小数位,得到的应该是134999999.9998现在事实上却不是.为何现在却出现整数出入这么大.而有些数据.比如20000.0000传递过去后仍然是20000.0000.看到这个现象然我百思不得其解.现在尚未找到问题根源。记录于此。
string str = "";
SqlConnection connection = new SqlConnection(ConfigurationSettings.AppSettings["ConnectionString"]);
SqlCommand command = new SqlCommand("sp_Insert_InfoTable", connection);
command.CommandType = CommandType.StoredProcedure;
command.CommandTimeout = 7200;
SqlParameterCollection parameters = command.Parameters;
parameters.Add(new SqlParameter("@ID", SqlDbType.Int));
parameters.Add(new SqlParameter("@ID1", SqlDbType.Int));
parameters.Add(new SqlParameter("@FDCStr", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FAccountNumber2", SqlDbType.NVarChar, 40));
parameters.Add(new SqlParameter("@FAccountName2", SqlDbType.NVarChar, 60));
parameters.Add(new SqlParameter("@FPaySettNo", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FPaySettDate", SqlDbType.DateTime));
parameters.Add(new SqlParameter("@FRecClientNo", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FRecClient", SqlDbType.NVarChar, 500));
parameters.Add(new SqlParameter("@FRecName1", SqlDbType.NVarChar, 100));
parameters.Add(new SqlParameter("@FRecClassID1", SqlDbType.Int));
parameters.Add(new SqlParameter("@FRecItemeID1", SqlDbType.Int));
parameters.Add(new SqlParameter("@FRecName2", SqlDbType.NVarChar, 100));
parameters.Add(new SqlParameter("@FRecClassID2", SqlDbType.Int));
parameters.Add(new SqlParameter("@FRecItemeID2", SqlDbType.Int));
parameters.Add(new SqlParameter("@FcpCalssID", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FAmt", SqlDbType.Float));
parameters.Add(new SqlParameter("@FFcyAmt", SqlDbType.Float));
parameters.Add(new SqlParameter("@FExplanation", SqlDbType.NVarChar, 0x3e8));
parameters.Add(new SqlParameter("@FVoucherID", SqlDbType.NVarChar, 200));
parameters.Add(new SqlParameter("@FPA1", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FPA2", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FPA3", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FPA4", SqlDbType.NVarChar, 50));
parameters.Add(new SqlParameter("@FPA5", SqlDbType.NVarChar, 50));
parameters["@ID"].Value = int.Parse(row["ID"].ToString());
parameters["@ID1"].Value = int.Parse(row["ID1"].ToString());
parameters["@FDCStr"].Value = row["FDCStr"].ToString();
parameters["@FAccountNumber2"].Value = row["FAccountNumber2"].ToString();
parameters["@FAccountName2"].Value = row["FAccountName2"].ToString();
parameters["@FPaySettNo"].Value = row["FPaySettNo"].ToString();
parameters["@FPaySettDate"].Value = row["FPaySettDate"].ToString();
parameters["@FRecClientNo"].Value = row["FRecClientNo"].ToString();
parameters["@FRecClient"].Value = row["FRecClient"].ToString();
parameters["@FRecName1"].Value = row["FRecName1"].ToString();
parameters["@FRecClassID1"].Value = int.Parse(row["FRecClassID1"].ToString());
parameters["@FRecItemeID1"].Value = int.Parse(row["FRecItemeID1"].ToString());
parameters["@FRecName2"].Value = row["FRecName2"].ToString();
parameters["@FRecClassID2"].Value = int.Parse(row["FRecClassID2"].ToString());
parameters["@FRecItemeID2"].Value = int.Parse(row["FRecItemeID2"].ToString());
parameters["@FcpCalssID"].Value = row["FcpCalssID"].ToString();
parameters["@FAmt"].Value = float.Parse(row["FAmt"].ToString());
parameters["@FFcyAmt"].Value = float.Parse(row["FFcyAmt"].ToString());
parameters["@FExplanation"].Value = row["FExplanation"].ToString();
parameters["@FVoucherID"].Value = row["FVoucherID"].ToString();
parameters["@FPA1"].Value = row["FPA1"].ToString();
parameters["@FPA2"].Value = row["FPA2"].ToString();
parameters["@FPA3"].Value = row["FPA3"].ToString();
parameters["@FPA4"].Value = row["FPA4"].ToString();
parameters["@FPA5"].Value = row["FPA5"].ToString();
try
{
connection.Open();
command.ExecuteNonQuery();
str = "OK";
}
catch
{
str = "ERROR";
}
finally
{
connection.Close();
}
return str;
问题跟进:问题解决但乘以10000小数也会变大的问题仍未想出是为什么。
修改cs中money对应的类型,改Float为Decimal设置4位小数。
//设置小数位
SqlParameter oSqlParameter_FAmt = new SqlParameter("@FAmt", SqlDbType.Decimal);
SqlParameter oSqlParameter_FFcyAmt = new SqlParameter("@FFcyAmt", SqlDbType.Decimal);
oSqlParameter_FAmt.Precision = 18;
oSqlParameter_FAmt.Scale = 4;
oSqlParameter_FFcyAmt.Precision = 18;
oSqlParameter_FFcyAmt.Scale = 4;
sqlParams.Add(oSqlParameter_FAmt);
sqlParams.Add(oSqlParameter_FFcyAmt);
sqlParams["@FAmt"].Value = decimal.Parse(row["FAmt"].ToString());
sqlParams["@FFcyAmt"].Value = decimal.Parse(row["FFcyAmt"].ToString());