P
pdxfilter-google
Hello! We're seeing some very odd results from the below code. Under
certain conditions, ADO.NET will create commands that specify a
negative zero amount ("-0.00"). It's easy to reproduce.
This is a major issue in our application as we do lots of decimal math
and rely on SqlDataAdapter and SqlCommandBuilder to do our data
updates. As a result, we have intermittent failure. We compare the
supposedly "zero" value to 0 inside of a trigger. When the value
reaches SQL Server as a "negative zero", some actions are undefined.
This is a potentially serious framework bug. I'd like to see it
verified by someone at Microsoft. Ideas for a workaround are welcome.
If no workaround, a T-Shirt or something would be nice!
Thanks,
Jon
=========================
// Run in Visual Studio 2005 "Console Mode"
using System;
using System.Data;
using System.Data.SqlClient;
namespace BadZero {
class Program {
static bool IsDecimalZero(decimal input) {
SqlConnection Connection = new SqlConnection(
@"Data Source=localhost;Trusted_Connection=True");
Connection.Open();
// Send command to SQL to check the value against zero
SqlCommand Command = new SqlCommand(
"IF @p1 = 0 SELECT 'Equal' ELSE SELECT 'Not Equal'",
Connection);
SqlParameter Param = new SqlParameter("@p1",
SqlDbType.Decimal);
Param.Value = input;
Command.Parameters.Add(Param);
string Result = Command.ExecuteScalar() as string;
// When BadZero is passed in, using SQL Profiler, we see
// @p1 being set to:
// GoodZero: 0.00
// BadZero: -0.00 (yes, MINUS 0.00)
Connection.Close();
return Result == "Equal";
}
static void Main(string[] args) {
decimal GoodZero = 0.00m;
decimal BadZero = 0.00m - 0;
// Look the same, but different internally
Console.WriteLine("GoodZero:{0} BadZero:{1}",
decimal.GetBits(GoodZero)[3], decimal.GetBits(BadZero)[3]);
bool GoodResult = IsDecimalZero(GoodZero); // true
bool BadResult = IsDecimalZero(BadZero); // false
Console.WriteLine("GoodResult:{0} BadResult:{1}",
GoodResult.ToString(), BadResult.ToString());
}
}
}
certain conditions, ADO.NET will create commands that specify a
negative zero amount ("-0.00"). It's easy to reproduce.
This is a major issue in our application as we do lots of decimal math
and rely on SqlDataAdapter and SqlCommandBuilder to do our data
updates. As a result, we have intermittent failure. We compare the
supposedly "zero" value to 0 inside of a trigger. When the value
reaches SQL Server as a "negative zero", some actions are undefined.
This is a potentially serious framework bug. I'd like to see it
verified by someone at Microsoft. Ideas for a workaround are welcome.
If no workaround, a T-Shirt or something would be nice!
Thanks,
Jon
=========================
// Run in Visual Studio 2005 "Console Mode"
using System;
using System.Data;
using System.Data.SqlClient;
namespace BadZero {
class Program {
static bool IsDecimalZero(decimal input) {
SqlConnection Connection = new SqlConnection(
@"Data Source=localhost;Trusted_Connection=True");
Connection.Open();
// Send command to SQL to check the value against zero
SqlCommand Command = new SqlCommand(
"IF @p1 = 0 SELECT 'Equal' ELSE SELECT 'Not Equal'",
Connection);
SqlParameter Param = new SqlParameter("@p1",
SqlDbType.Decimal);
Param.Value = input;
Command.Parameters.Add(Param);
string Result = Command.ExecuteScalar() as string;
// When BadZero is passed in, using SQL Profiler, we see
// @p1 being set to:
// GoodZero: 0.00
// BadZero: -0.00 (yes, MINUS 0.00)
Connection.Close();
return Result == "Equal";
}
static void Main(string[] args) {
decimal GoodZero = 0.00m;
decimal BadZero = 0.00m - 0;
// Look the same, but different internally
Console.WriteLine("GoodZero:{0} BadZero:{1}",
decimal.GetBits(GoodZero)[3], decimal.GetBits(BadZero)[3]);
bool GoodResult = IsDecimalZero(GoodZero); // true
bool BadResult = IsDecimalZero(BadZero); // false
Console.WriteLine("GoodResult:{0} BadResult:{1}",
GoodResult.ToString(), BadResult.ToString());
}
}
}