Несмотря на прекрасные ответы, уже добавленные к этому вопросу, существует явно определенный порядок приоритета для преобразования типов данных в SQL Server.
Когда оператор объединяет два выражения разных типов данных, правила для приоритета типа данных указывают, что тип данных с более низким приоритетом преобразуется в тип данных с более высоким приоритетом. Если преобразование не поддерживается неявным преобразованием, возвращается ошибка. Если оба выражения операнда имеют один и тот же тип данных, результат операции имеет этот тип данных.
SQL Server использует следующий порядок приоритета для типов данных:
user-defined data types (highest)
sql_variant
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar (including nvarchar(max) )
nchar
varchar (including varchar(max) )
char
varbinary (including varbinary(max) )
binary (lowest)
Так, например, если вы SELECT 0.5 * 1
(умножая десятичное число на целое число) вы получите результат, который преобразуется в десятичное значение, так decimal
как приоритет выше, чем у int
типа данных.
См. Http://msdn.microsoft.com/en-us/library/ms190309.aspx для получения дополнительной информации.
Сказав все это, вероятно , SELECT @C * (@I * POWER(1 + @I, @N) / (POWER(1 + @I, @N) - 1 ));
должно вернуть десятичное значение, так как практически все входные данные являются десятичными. Интересно, что вы можете принудительно изменить результат, изменив его SELECT
на:
DECLARE @N INT = 360;
DECLARE @I DECIMAL(38,26) = 0.15 * 30 / 360;
DECLARE @C DECIMAL(38,26) = 1000000;
SELECT @C * @I * POWER(1 + @I, @N) / (POWER(1 + @I, @N) - 1);
SELECT @C * (@I * POWER(1 + @I, @N) / (POWER(1E0 + @I, @N) - 1));
Это возвращает:
Я затрудняюсь объяснить, как это имеет какое-то значение, хотя, очевидно, это имеет значение . Я предполагаю , что 1E0
(явное значение с плавающей точкой) в POWER(
функции заставляет SQL Server сделать другой выбор типов вывода для POWER
функции. Если мое предположение верно, это указывало бы на возможную ошибку в POWER
функции, поскольку в документации указано, что первым вводом POWER()
является число с плавающей точкой или число, которое можно неявно преобразовать в число с плавающей точкой.