0

I have a database table with two float type columns, and I am trying to insert two numbers via c# code.

This is my code for sql parameters:

sqlCommand.Parameters.Add(new SqlParameter("@Number1", SqlDbType.Decimal) {​​​​ Precision = 17, SqlValue = Number1FloatValue ?? (object)DBNull.Value }​​​​);
sqlCommand.Parameters.Add(new SqlParameter("@Number2", SqlDbType.Decimal) {​​​​ Precision = 17, SqlValue = Number2FloatValue ?? (object)DBNull.Value }​​​​);

First number is -102272.125 and the second is 256.245

In the debugger when I take a look at the values, from some reason SqlValue of the first number becomes -102272.1 - last two digits are missing, and Value property is fine -102272.125, and the second number is ok and gets inserted correctly as 256.245. I thought that it is some problem with the default precision, so I set it to 17, but it didn't helped. And also, firstly I was setting Value instead of SqlValue and later changed to SqlValue assuming that that could be a problem but it didn't helped.

More strangely: when I change SqlDbType.Decimal to SqlDbType.Float (as I tried initially), then first number gets inserted correctly as -102272.125, but the second number gets some unwanted additional decimals: 256.244996832...

I now that float type is not the best way to store decimal numbers in database, but I cannot change the types of table columns.

So, how to get this code insert both values correctly?

This is my code:

static void Main(string[] args)
{
    float? number1 = -102272.125f;
    float? number2 = 256.245f;

    using (SqlConnection openCon = new SqlConnection("Data source=.; Initial Catalog=MyDatabase; Persist Security Info=True; Integrated Security=true;"))
    {
        string saveStaff = "INSERT into test_float (Number1,Number2) VALUES (@Number1,@Number2)";

        using (SqlCommand querySaveStaff = new SqlCommand(saveStaff))
        {
            querySaveStaff.Connection = openCon;
            querySaveStaff.Parameters.Add("@Number1", SqlDbType.Float).Value = number1 ?? (object)DBNull.Value;
            querySaveStaff.Parameters.Add("@Number2", SqlDbType.Float).Value = number2 ?? (object)DBNull.Value;
            openCon.Open();

            querySaveStaff.ExecuteNonQuery();
        }
    }
}

And this is databse table and result of an insert. This was my initial problem - Number2 has much more decimals than expected, after which I tried to change SqlDbType to decimal, but running into problem that the first number got rounded to -102272.1, and second number was fine: 256.245. So I am not sure how to get it work in all cases.

And I cannot change the sql table.

enter image description here

When I try something like this:

static void Main(string[] args)
        {
            float? number1 = -102272.125f;
            float? number2 = 256.245f;

            using (SqlConnection openCon = new SqlConnection("Data source=.; Initial Catalog=MyDatabase; Persist Security Info=True; Integrated Security=true;"))
            {
                string saveStaff = "INSERT into test_float (Number1,Number2) VALUES (@Number1,@Number2)";

                using (SqlCommand querySaveStaff = new SqlCommand(saveStaff))
                {
                    querySaveStaff.Connection = openCon;
                    //querySaveStaff.Parameters.Add("@Number1", SqlDbType.Float).Value = number1 ?? (object)DBNull.Value;
                    //querySaveStaff.Parameters.Add("@Number2", SqlDbType.Decimal).Value = number2 ?? (object)DBNull.Value;
                    querySaveStaff.Parameters.Add(new SqlParameter("@Number1", SqlDbType.Decimal){Precision = 17, Scale=6, Value = number1, SqlValue = number1});
                    querySaveStaff.Parameters.Add(new SqlParameter("@Number2", SqlDbType.Decimal) { Precision = 17, Scale = 6, Value = number2, SqlValue = number2 });

                    openCon.Open();

                    querySaveStaff.ExecuteNonQuery();
                }
            }
        }

Then, second number is somehow fine, but the first isn't:

enter image description here

Edit 2:

I have just found that using double type in c# for numbers I am trying to insert MAYBE will help:

    double? number1 = -102272.125;
    double? number2 = 256.245;

    using (SqlConnection openCon = new SqlConnection("Data source=.; Initial Catalog=MyDatabase; Persist Security Info=True; Integrated Security=true;"))
    {
        string saveStaff = "INSERT into test_float (Number1,Number2) VALUES (@Number1,@Number2)";

        using (SqlCommand querySaveStaff = new SqlCommand(saveStaff))
        {
            querySaveStaff.Connection = openCon;
            
            querySaveStaff.Parameters.AddWithValue("@Number1", number1 ?? (object)DBNull.Value);
            querySaveStaff.Parameters.AddWithValue("@Number2", number2 ?? (object)DBNull.Value);

            openCon.Open();

            querySaveStaff.ExecuteNonQuery();
        }
    }

Now it looks fine at least for this two numbers:

enter image description here

vldmrrdjcc
  • 2,082
  • 5
  • 22
  • 41
  • 2
    If the columns are a `float`, why are you passing a `decimal` in your C#? – Thom A Jan 22 '21 at 10:38
  • 1
    I suspect you actually have a `real` for your database data type: `CONVERT(real,-102272.125)` returns `-102272.1`. This is just one of the dangers of using floating point values; they aren't accurate. – Thom A Jan 22 '21 at 10:40
  • the second number as float just seems to be regular floating point behavior to me. don't forget that floats are not _precise_. – Franz Gleichmann Jan 22 '21 at 10:40
  • 1
    Please show us the `CREATE TABLE` for the table and a [mcve] for the C#. – mjwills Jan 22 '21 at 10:42
  • @mjwills edited with example – vldmrrdjcc Jan 22 '21 at 13:41
  • @Larnu I edited the question so you can see, I was using Float initially, but after that I just tried something in order to get it right but without success. – vldmrrdjcc Jan 22 '21 at 13:59
  • @Franz Gleichmann but is it possible to somehow make it work even if it is float in the database? – vldmrrdjcc Jan 22 '21 at 14:00
  • if it's float, it's float, with all its limitations. the best bet by far would be to talk whoever's in charge and tell them to use the right datatype. – Franz Gleichmann Jan 22 '21 at 14:08
  • @Franz Gleichmann Thanks, it looks like this is expected behavior, and I am just curious: what is the difference between those two numbers so for 256.245 number 256.24499 is inserted, and for the other number -102272.125 - exactly this number is inserted and not some approximation like -102272.12499.. when using SqlDbType.Float? – vldmrrdjcc Jan 22 '21 at 14:38
  • 1
    the https://floating-point-gui.de/ will answer that better than anyone could in a comment. the TLDR: some decimal numbers can be represented exactly in binary, most can't. `.125` as "one eighth" or "1/(2^3)" can be. – Franz Gleichmann Jan 22 '21 at 14:42
  • @Franz Gleichmann I have just found that using double in c# could help - at least now it is ok for those two numbers from example. Could this work in general case maybe (I have just edited question for the second time). – vldmrrdjcc Jan 22 '21 at 14:56
  • 1
    Use decimal - float and double are not what you need. But yes, `double` in C# will be better since double in C# is equivalent to float in SQL Server. – mjwills Jan 22 '21 at 21:35

0 Answers0