#sql #sql-server #casting #rounding
#sql #sql-сервер #Кастинг #округление
Вопрос:
странный.
При устранении неполадок, почему представление возвращает разные результаты при запуске из разных баз данных в SQLMS, я вернул его к следующему:
select cast((cast(0.31 as numeric(18,2)) - cast(0.31 as numeric(18,2)) * cast(50 as float) / 100) as numeric(18,2))
union
select cast((cast(0.31 as numeric(18,2)) - cast(0.31 as numeric(18,2)) * cast(50 as numeric(18,2)) / 100) as numeric(18,2))
Если я выбираю одну базу данных, она возвращает 0,15 и 0,16, если я выбираю другую базу данных, она возвращает 0,16 и 0,16.
Оператор приведения округляется в меньшую сторону, когда 50 приводится как число с плавающей запятой, и в большую сторону при приведении как числовое в одной базе данных, но округляется в большую сторону для обоих операторов в другой.
Идеи !?
Комментарии:
1. Что такое SQLMS? Отметьте используемую базу данных.
2. SQL Management Studio. Я попытался пометить t-sql, но это не позволило мне, поскольку я новичок.
3. Какие версии и уровни совместимости используют две базы данных?
Ответ №1:
Источником проблемы, вероятно, являются два следующих термина из двух половин в запросе объединения:
cast(50 as float) / 100
cast(50 as numeric(18,2)) / 100
Количество сверху использует точность с плавающей запятой, что не является точным, в то время как количество внизу использует числовой тип, который является точным. Я не знаю подробностей ваших версий SQL Server, но варианты, которые вы видите, являются честной игрой, в зависимости от того, как конкретная версия SQL Server и подчиненный процессор обрабатывают вышеуказанное вычисление с плавающей запятой.
Чтобы избежать этой неопределенности, вы должны везде использовать числовой или десятичный тип. То есть вы должны склоняться к нижней версии вычисления.
Комментарии:
1. Да, я согласен и сделал бы, если бы это было мое программное обеспечение. Обе базы данных находятся на одном сервере и имеют одну и ту же версию.
2. MS SQL Server — это программа, как и любая другая программа. Хотя математика, которую вы нам показали, выглядит одинаково, это не обязательно означает, что вычисления будут выполняться в той же части кода SQL Server. Итак, я не вижу особых причин менять свой ответ. Просто придерживайтесь точных типов, чтобы избежать этой проблемы.
Ответ №2:
Оказывается, это была совместимость базы данных. Что-то изменилось между SQL Server 2014 и SQL Server 2016.
Уменьшение совместимости с проблемной базой данных до 2014 с 2016 устраняет проблему.
Очевидно, что не смешивать типы данных или, по крайней мере, приводить все поля к одному типу — это путь вперед.