Представление SQL, возвращающее разные результаты при выборе другой базы данных

#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 устраняет проблему.

Очевидно, что не смешивать типы данных или, по крайней мере, приводить все поля к одному типу — это путь вперед.