Как проверить / проверить значение с плавающей точкой перед сохранением в виде десятичного числа (4,1) в SQL? - PullRequest
1 голос
/ 10 июня 2010

Я определил столбец в SQL как decimal(4,1), null, что означает, что я храню четыре цифры, вплоть до одной из которых может быть справа от десятичной точки.

Исходные данные должны всегда находиться в диапазоне от 0 до 999,9, но из-за ошибки, не зависящей от меня, я получил число -38591844.0. Очевидно, что это не будет храниться в SQL и выдает ошибку «Ошибка арифметического переполнения при преобразовании вещественного числа в тип данных числовой».

Я хочу сохранить ноль, если значение выходит за пределы.

Как лучше всего убедиться, что значение с плавающей запятой в C # не выходит за пределы столбца SQL, определенного выше?

Хотя это кажется самым простым подходом ...

private bool Validate41Float(float f)
{
    if (f >= 0 && f <= 999.9) return true;
    else return false;
}

Я обеспокоен, если по какой-то причине я получу значение: 10.12345. В таком случае я бы просто хотел сохранить 10.1, но вызывает ли дополнительная точность ту же ошибку SQL?

Ответы [ 3 ]

2 голосов
/ 10 июня 2010

Я знаю, что вы можете отправить 10.12345 на SQL Server, и он будет округлен до 10.1 и не будет жаловаться.Я не знаю точно о других поставщиках БД, но я бы предположил, что они работают одинаково.Чтобы было ясно, что вы делаете, вы можете явно округлить и затем проверить свою логику следующим образом:

private bool Validate41Float(float f)
{
    float rounded = (float)Math.Round(f, 1);
    if (rounded > -1000 && rounded < 1000) return true;
    else return false;
}
1 голос
/ 10 июня 2010

--- Отредактировано после комментария, который уточнил вопрос ---

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

Если число слишком велико для хранения в базе данных (например, 123456.7), большинство баз данных выдаст ошибку, что число не может соответствовать точности. поля.

--- Исходный пост следует ---

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

Например, 1,75 будет точно представимо, потому что это 1 + 1/2 + 1/4. Числа, подобные 1 и 1/3, не могут быть точно представлены, потому что никакая сумма дробей в форме 1/2 ^ n не может представлять 1/3.

С учетом этого, если это действительно критическая проблема, вам необходимо выполнить одно из следующих действий:

  1. Округлить (или обрезать) результат до ближайшего значения .1, .2, .3 и т. Д. Это по-прежнему будет иметь проблемы, но это лучше, чем ничего.
  2. Представьте число как целое число, и просто «запомните», что целое число - это число десятых, а не число единиц.

Банковские приложения часто используют вторую технику, чтобы исключить возможность дробного дробления и ошибки округления.

0 голосов
/ 11 июня 2010

Вот метод расширения, который я реализовал, основываясь на ответе Тима Кокера:

    private static float? ValidateDecimal41(this float? f)
    {
        if (!f.HasValue) return f;
        float rounded = (float)Math.Round((float)f, 1);
        if (rounded >= 0 && rounded <= 999.9) return rounded;
        else return null;
    }

Это позволило мне:

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