博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SQL类型转换问题,

Posted on 2009-04-19 22:08  郭子  阅读(2947)  评论(0编辑  收藏  举报

上次在一个客户那发现一个问题。

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());