Почему это неявное преобразование типов происходит в этом выражении COALESCE? - PullRequest
3 голосов
/ 26 апреля 2019

Почему Ceiling () меняет тип данных на (38,0) здесь, теряя точность после десятичной точки?

Это ТОЛЬКО происходит с десятичной дробью (38, X), как показано ниже.

Запуск на Microsoft SQL Server 2016

DECLARE @decimal2 DECIMAL(37,4) = 1.1
SELECT COALESCE(1.1,CEILING(@decimal2)) 

^ это возвращает 1.1

DECLARE @decimal DECIMAL(38,4) = 1.1
SELECT COALESCE(1.1,CEILING(@decimal))

^ это возвращает 1 !!

Ответы [ 3 ]

3 голосов
/ 26 апреля 2019

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

DECLARE @decimal DECIMAL(38,4) = 1.1
SELECT COALESCE(@decimal,CEILING(@decimal)) --RETURNS 1
SELECT COALESCE(@decimal,CAST(CEILING(@decimal) AS DECIMAL(38,4))) --RETURNS 1.1000

Мое правило избегать подобных проблем - всегда приводить разные типы данных к общему.

0 голосов
/ 27 апреля 2019

Это просто из-за того, что числовой тип данных может содержать только 38 цифр и сначала заполнит наиболее значимые значения, поэтому, если вы скажете 37,4, он заполнит 37 позиций слева от десятичной дроби и сохранитоставшийся справаЕсли вы поставите 38 слева от десятичной запятой, там не будет места для десятичной запятой, независимо от того, что вы поставили справа.

0 голосов
/ 26 апреля 2019

Это поведение (ошибочно) объяснено в статье Точность, масштаб и длина (Transact-SQL) от Microsoft Docs. Выдержка из статьи:

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

Теперь запутанной частью будет понимание того, как рассчитывается точность и масштаб. Судя по моему тестированию, похоже, что используются правила сложения. Для точности max(s1, s2) + max(p1-s1, p2-s2) + 1 и для масштаба max(s1, s2). Но поскольку точность превысила бы 38, разница берется из шкалы для сохранения целостности составной части.

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