Abaixo está uma lista contendo os tipos de dados do SQL Server, em ordem de precedência.
- tipos de dados definidos pelo usuário (mais altos)
sql_variantxmldatetimeoffsetdatetime2datetimesmalldatetimedatetimefloatrealdecimalmoneysmallmoneybigintintsmallinttinyintbitntexttextimagetimestampuniqueidentifiernvarchar(incluindonvarchar(max))ncharvarchar(incluindovarchar(max))charvarbinary(incluindovarbinary(max))binary(mais baixo)
Quando você usa um operador para combinar operandos de diferentes tipos de dados, o tipo de dados com menor precedência é primeiro convertido no tipo de dados com maior precedência.
Se a conversão não for uma conversão implícita com suporte, um erro será retornado.
Se ambos os operandos forem do mesmo tipo, nenhuma conversão será feita (ou necessária) e o resultado da operação usará o tipo de dados dos operandos.
Exemplo
Aqui está um exemplo de uma conversão implícita bem-sucedida:
SELECT 1 * 1.00; Resultado:
1.00
Aqui, o operando esquerdo foi convertido para o tipo de dados do operando direito.
Aqui está uma maneira mais explícita de fazer isso:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2; Resultado:
1.00
Neste caso eu declarei explicitamente o operando esquerdo como um
INT e o operando direito como DECIMAL(5, 2) . Podemos examinar melhor os resultados com o
sys.dm_exec_describe_first_result_set função de gerenciamento dinâmico do sistema. Esta função nos permite verificar o tipo de dados de cada coluna retornada em uma consulta:
SELECT
system_type_name,
max_length,
[precision],
scale
FROM sys.dm_exec_describe_first_result_set(
'DECLARE @n1 INT, @n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1, @n2, @n1 * @n2;',
null,
0); Resultado:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Aqui, podemos ver que cada linha representa cada coluna retornada pela consulta. Portanto, a primeira coluna era um
INT , a segunda coluna era DECIMAL(5,2) , e a terceira coluna um DECIMAL(16,2) . Então o SQL Server realmente retornou um
DECIMAL(16,2) , mesmo que o valor decimal original fosse um DECIMAL(5,2) . Exemplo de um erro de conversão
Conforme mencionado, se a conversão não for uma conversão implícita com suporte, um erro será retornado:
SELECT 'Age: ' + 10; Resultado:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
Neste caso, eu estava tentando concatenar uma string (
VARCHAR ) e um número (INT ). Vendo como INT tem uma precedência maior que VARCHAR , o SQL Server tentou converter implicitamente a string em um INT . Isso falhou porque essa string não pode ser convertida em um número inteiro.
Para superar isso, podemos primeiro converter o
INT para VARCHAR :SELECT 'Age: ' + CAST(10 AS VARCHAR(2)); Resultado:
Age: 10
Agora, ambos os operandos têm o mesmo tipo de dados e, portanto, o SQL Server executa a operação com êxito sem a necessidade de realizar conversões implícitas.
Outra maneira de fazer esta operação em particular é com o
CONCAT() função:SELECT CONCAT('Age: ', 10); Resultado:
Age: 10
O
CONCAT() function é uma função de string e, portanto, converte implicitamente todos os argumentos em tipos de string antes da concatenação. Portanto, não havia necessidade de realizarmos uma conversão explícita. No entanto, se o operando string puder ser convertido implicitamente em um número, ele não causará um erro ao usar o
+ operador:SELECT '10' + 10; Resultado:
20
Mas neste caso, o
+ O operador se transforma em um operador matemático de adição, em vez de um operador de concatenação de string.