Não obstante as excelentes respostas já adicionadas a esta pergunta, há uma ordem de precedência explicitamente definida para a conversão de tipos de dados no SQL Server.
Quando um operador combina duas expressões de tipos de dados diferentes, as regras para a precedência do tipo de dados especificam que o tipo de dados com a precedência mais baixa é convertido no tipo de dados com a precedência mais alta. Se a conversão não for uma conversão implícita suportada, um erro será retornado. Quando ambas as expressões de operando têm o mesmo tipo de dados, o resultado da operação possui esse tipo de dados.
O SQL Server usa a seguinte ordem de precedência para tipos de dados:
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)
Assim, por exemplo, se você SELECT 0.5 * 1
(multiplicando um decimal por um int), obtém um resultado que é convertido em um valor decimal, pois decimal
é uma precedência mais alta que o int
tipo de dados.
Consulte http://msdn.microsoft.com/en-us/library/ms190309.aspx para obter mais detalhes.
Dito tudo isso, provavelmente SELECT @C * (@I * POWER(1 + @I, @N) / (POWER(1 + @I, @N) - 1 ));
deve retornar um valor decimal, pois praticamente todas as entradas são decimais. Curiosamente, você pode forçar um resultado correto modificando isso SELECT
para:
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));
Isso retorna:
Não consigo explicar como isso faz alguma diferença, embora claramente faça . Meu palpite é que 1E0
(uma flutuação explícita) na POWER(
função força o SQL Server a fazer uma escolha diferente nos tipos de saída para a POWER
função. Se minha suposição estiver correta, isso indicaria um possível bug na POWER
função, uma vez que a documentação indica que a primeira entrada POWER()
é float ou um número que pode ser implicitamente convertido em float.