Десятичное значение 1,5 заканчивается как 15 в БД - как, почему? - PullRequest
4 голосов
/ 27 июля 2011

Приветствую добрых людей из интернета:)

У меня есть строковое значение "1,5", которое после Convert.ToDecimal () заканчивается как 1,5M при просмотре в отладчике.Пока все хорошо, я думаю.Десятичное значение затем передается вызову хранимой процедуры внутри набора данных.Тип интересующего меня параметра определяется как NUMBER (7,2) в БД, поэтому он должен учитывать числа, которые имеют цифры после десятичного разделителя.

Проблема в том, что где-то вдоль строки десятичное значение теряетсяего разделитель и соединяет точность с масштабом, образуя совершенно новый номер, как указано в заголовке этого поста.Я даже пытался установить Precision and Scale внутри коллекции параметров в вызове хранимой процедуры, чтобы она соответствовала DB (7,2), но это тоже не помогло.

Есть ли у вас какие-либо идеи о том, что может происходить здесь??

РЕДАКТИРОВАНИЕ:

Вот код, который вызывает хранимый процесс:

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

=> SetCaseAction просто вызывает хранимый процесс в БДиспользуя механику DataSet.«totalhrs» - это параметр, который меня интересует, в данном случае - десятичное число 1,5M.Я также проверил NLS_NUMERIC_CHARACTERS в Oracle, и они установлены в ','

Так что он использует запятую для десятичных дробей и пробел для тысяч.Ничего необычного я не вижу там.Единственной странной вещью может быть то, что «1,5» заканчивается как «1.5M» с точкой внутри после ToDecimal (), что может быть неправильно интерпретировано.Однако это кажется маловероятным, поскольку региональные настройки на моем сервере также используют ',' в качестве десятичного разделителя, если .NET не использует некоторые другие настройки?Действительно смущен.

Ответы [ 5 ]

4 голосов
/ 27 июля 2011

Я подозреваю, что вы в какой-то момент конвертируете его без правильной культуры, например, конкатенируете его (вместо использования параметра) в запрос TSQL через ToString() или просто используете неправильную культуру при вызове ToDecimal.«1,5» является неоднозначным между «1 десятичной точкой 5» и «1 разделителем группы 5»;последний случай разбирается как 15.

2 голосов
/ 27 июля 2011

Я полагаю, что это проблема локализации - запятые используются для разделения тысяч, а не для указания десятичных разрядов во многих системах.Проверьте настройки языка в вашей базе данных.

1 голос
/ 27 июля 2011

Некоторый код о том, как передать значение хранимой процедуре, будет полезен (если вы делаете это самостоятельно).

Некоторые люди все еще используют String.Format для генерации строк запроса. Помимо появления ошибок, подобных той, которую вы описываете, это открыто для SQL-инъекций.

Вы должны использовать параметризованные запросы. Обычно, что-то подобное работает:

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

EDIT
Конечно, это должно быть сделано не только для некоторых параметров, но и для всех параметров для хранимой процедуры! Выше приведен пример того, как в первую очередь передать параметры хранимой процедуре.

1 голос
/ 27 июля 2011

Десятичный разделитель в SQL: ., а не ,.Таким образом, 1,5 интерпретируется как 15 , а не 1,5 .Чтобы избежать такого рода проблем, всегда используйте параметризованные запросы, а не кодируйте значения непосредственно в текст запроса.

0 голосов
/ 27 июля 2011

Как сказал Томас, в SQL десятичный разделитель в SQL - это "."

В этом случае вы можете просто использовать:

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

А затем передать параметр в функцию, которая выполняет транзакцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...