SQL Server усекает десятичные точки вновь созданного поля в представлении - PullRequest
9 голосов
/ 22 марта 2011

У меня есть представление в SQL-сервере, что-то вроде этого:

select 6.71/3.41 as NewNumber

Результат 1.967741 (обратите внимание на 6 десятичных знаков) -> decimal (38,6)

Я пытаюсьто же самое в калькуляторе, но результат равен 1.967741935483871xxxx

Я хочу заставить SQL Server возвращать более точный результат, например decimal(38,16) Я пробовал очевидные вещи, такие как приведение, но SQL Server не улучшаетсяна выходе я просто получаю несколько конечных нулей в конце, как 1.9677410000

Есть ли способ заставить SQL Server не усекать результат или давать более точный?

Ответы [ 3 ]

17 голосов
/ 22 марта 2011

Если вы хотите что-то вроде decimal(38,16), тогда вам нужно привести данные, а не вывод после того, как усечение уже произошло!

SELECT CAST(6.71 AS DECIMAL(38,18))/3.41 AS NewNumber

Возвращает

1.9677419354838709

Проверьте тип данных

SELECT 
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'BaseType'),
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'Precision'),
SQL_VARIANT_PROPERTY(CAST(6.71 AS DECIMAL(38,18))/3.41, 'Scale')

Возвращает

numeric 38  16

Редактировать

Это просто, чтобы добавить дополнительную ссылку, следуя за комментариями. Правила преобразования decimal в decimal описаны в BOL . Эта ссылка включает следующую фразу

* Точность и масштаб результата имеют абсолютный максимум 38. Когда Точность результата больше 38, соответствующая шкала сводится к предотвратить неотъемлемую часть результата от усечения.

, но не уточняется, как именно выполняется такое усечение. Это задокументировано здесь .

3 голосов
/ 22 марта 2011

Литерал 6.71 обрабатывается как numeric, который имеет фиксированную точность. Поскольку вы выполняете деление, вы меняете количество десятичных разрядов, которое вы не хотите использовать, когда точность имеет первостепенное значение. Если вы хотите, чтобы ваши числа были точными, вам нужно привести знаменатель в вашем запросе к типу данных decimal с большей точностью. Это должно работать для вас:

select 6.71 / cast(3.41 as decimal(18, 8)) as NewNumber
3 голосов
/ 22 марта 2011

Это немного обходной путь, но я думаю, что стоит обратить внимание.

select ((6.71*10000)/(3.41*10000)) as NewNumber

Этот запрос:

SELECT 6.71/3.41, ((6.71*1000000)/(3.41*1000000)) as NewNumber

возвращает:

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