开发者

Decimal value 1,5 ends up as 15 in DB - how, why?

开发者 https://www.devze.com 2023-03-23 01:16 出处:网络
Greetings good people of the internet:) I have a string value \"1,5\" which after Convert.ToDecimal() ends up as 1.5M when looking at it in debugger. So far so good I guess. The decimal value then ge

Greetings good people of the internet:)

I have a string value "1,5" which after Convert.ToDecimal() ends up as 1.5M when looking at it in debugger. So far so good I guess. The decimal value then gets passed to a stored procedure call inside a dataset. The type of parameter I am interested in is defined as NUMBER (7,2) in DB so it should allow for numbers that have digits after decimal separator.

The problem is that somewhere along the line the decimal value looses its separator and joins the precision with scale making up completely new number as indicated in the title of this post. I even tried setting Precision and Scale inside parameters' collection in that stored procedure call to match with DB (7,2), but it it did not help either.

Do you have any idea what may be happening here?

EDIT:

Here is the code that calls the stored proc:

CaseFactory.UtilsAdapter.SetCaseAction(DefId, action, doneBy, assignedTo, comment, status, searchStatus, priority, access, relStatus, relStatusFixKit, totalhrs, out Common.RETURN_CODE, out Common.RETURN_TEXT);

=> SetCaseAction is just calling stored proc in DB using DataSet mechanics. 'totalhrs' is the param I am interested in is a decimal 1.5M at this point. I have also checked NLS_NUMERIC_CHARACTERS in Oracle and they are set to ', '

So it uses comma for decimals and space for th开发者_如何学运维ousands. Nothing unusual I can see there. Only strange thing may be that '1,5' ends up as '1.5M' with a dot inside after ToDecimal(), which may be interpreted incorrectly. It seems unlikely however, because the regional settings on my server use ',' as decimal separator as well, unless .NET uses some different settings? Really confused.


I suspect you are converting it at some point without the correct culture, for example concatenating it (instead of using a parameter) into a TSQL query via ToString(), or simply using the wrong culture when calling ToDecimal. "1,5" is ambiguous between "1 decimal point 5" and "1 group separator 5"; the latter case is parsed as 15.


I'd imagine it's a localisation problem - commas are used to separate thousands, rather than to indicate decimal places in a lot of systems. Check out the language setting on your database.


The decimal separator in SQL is ., not ,. So 1,5 is interpreted as 15, not 1.5. To avoid this kind of issue, always use parameterized queries rather than encoding the values directly into the query text.


Some code on how you pass the value to the stored procedure would be usedful (if you're doing it yourself).

Some people still use String.Format to generate query strings. Apart from causing errors like the one you're describing, this is open to SQL-injections.

You should use parameterized queries. Usually, doing something like this will work:

SqlCommand cmd = new SqlCommand("...", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@myDecimal", decimalVariable);

EDIT
Of course, this should not be done for just some of the parameters, but for all parameters for the stored procedure! The above is just a sample on how to pass parameters to the stored procedure in the first place.


As Thomas said, in SQL the decimal separator in SQL is a "."

In this case you could just use:

yourVariable.Replace(',','.')

And then, pass the parameter to the function that does the transaction.

0

精彩评论

暂无评论...
验证码 换一张
取 消