2

Why does

        scIns.Parameters.Add(new SqlParameter("@v30", 0.00m));

lead to a "@v30 undefined" error, but

        decimal dZero = 0.00m;
        scIns.Parameters.Add(new SqlParameter("@v30", dZero));

works OK?

5
  • 3
    Are you sure it's the only difference? It shouldn't matter whether or not you use an intermediate variable... Commented Jun 30, 2011 at 20:02
  • 2
    Can you show us the entire piece of code? Commented Jun 30, 2011 at 20:04
  • Yes, the mentioned error is not in the posted code but must be somewhere else Commented Jun 30, 2011 at 20:05
  • Actually, that is the only change in the code. Commented Jun 30, 2011 at 20:36
  • @SeaDive, what are you using to Execute the command? Please show a bit more code. Commented Jun 30, 2011 at 21:02

2 Answers 2

3

SqlParamter has two different overloads with two parameters, first being string and second being SqlDbType or object.

In the first case when 0.00m gets passed in it gets converted to Int64, and in the second case because the value passed in is of type decimal it then used the SqlDbType.Decimal.

Check out this Link

Update :
Found another stackoverflow Question that talks about this and has a detailed answer. :)

Sign up to request clarification or add additional context in comments.

2 Comments

It seems there's a quirk in C#'s overload resolution that I was not aware of. A literal zero of any numeric type matches and gets implicitly converted into any enum type (whether the enum even contains a zero value or not). Other values, however, don't get converted.
I thought there was something funny like that, I was busy going through System.Data with reflector trying to see if the SqlParameter class does any conversions. Thanks for the update Matti!
1

If you look in the debugger, you will see that in the first case, the parameter's DbType is Int64, and in the second case it's Decimal.

Try using one of the other SqlParameter ctor overloads where you explicitly specify the SqlDbType.

Hope that helps,

John

5 Comments

How could this even happen? The constructors are passed the exact same value in both cases.
Thanks. I guess I see what's going on, and how to fix it, but it seems more trouble than the original workaround. I also had trouble with a object value of "".
As I understand it, what JohnD is pointing out is that the constructor that takes the arguments of (string, object) basically guesses at the type of the object. Somehow, the decimal 0.00m was changed to an int (by C# or by SqlServer?), so the SqlCommand expected an int, and rejected a decimal. Apparently, using the typed variable obviates the problem. One can also use other constructors that pass the SqlDBType as a separate argument.
@SeaDrive: No, no. The compiler doesn't just go and randomly change the types of values without a reason. See pastebin.com/dX8iat06
@Matti Virkkunen, please see my answer below and look at the link to get a better exp of why this happens.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.