sql >> Base de Datos >  >> RDS >> Sqlserver

Precedencia del tipo de datos en SQL Server

A continuación se muestra una lista que contiene los tipos de datos de SQL Server, en orden de prioridad.

  1. tipos de datos definidos por el usuario (más alto)
  2. sql_variant
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (incluyendo nvarchar(max) )
  26. nchar
  27. varchar (incluyendo varchar(max) )
  28. char
  29. varbinary (incluyendo varbinary(max) )
  30. binary (más bajo)

Cuando usa un operador para combinar operandos de diferentes tipos de datos, el tipo de datos con la prioridad más baja se convierte primero al tipo de datos con la prioridad más alta.

Si la conversión no es una conversión implícita admitida, se devuelve un error.

Si ambos operandos son del mismo tipo, entonces no se realiza (ni se necesita) ninguna conversión y el resultado de la operación utiliza el tipo de datos de los operandos.

Ejemplo

Aquí hay un ejemplo de una conversión implícita que tiene éxito:

SELECT 1 * 1.00;

Resultado:

1.00

Aquí, el operando izquierdo se convirtió al tipo de datos del operando derecho.

Esta es una forma más explícita de hacerlo:

DECLARE 
    @n1 INT, 
    @n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;

Resultado:

1.00

En este caso, declaré explícitamente el operando izquierdo como INT y el operando derecho como DECIMAL(5, 2) .

Podemos examinar más a fondo los resultados con sys.dm_exec_describe_first_result_set función de gestión dinámica del sistema.

Esta función nos permite verificar el tipo de datos de cada columna devuelta en una 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       |
+--------------------+--------------+-------------+---------+

Aquí, podemos ver que cada fila representa cada columna devuelta por la consulta. Por lo tanto, la primera columna era un INT , la segunda columna era DECIMAL(5,2) , y la tercera columna un DECIMAL(16,2) .

Entonces SQL Server en realidad devolvió un DECIMAL(16,2) , aunque el valor decimal original era un DECIMAL(5,2) .

Ejemplo de un error de conversión

Como se mencionó, si la conversión no es una conversión implícita admitida, se devuelve un error:

SELECT 'Age: ' + 10;

Resultado:

Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'Age: ' to data type int.

En este caso, estaba tratando de concatenar una cadena (VARCHAR ) y un número (INT ). Ver como INT tiene una precedencia mayor que VARCHAR , SQL Server intentó convertir implícitamente la cadena en un INT .

Esto falló porque esta cadena no se puede convertir en un número entero.

Para superar esto, primero podemos convertir el INT a VARCHAR :

SELECT 'Age: ' + CAST(10 AS VARCHAR(2));

Resultado:

Age: 10

Ahora ambos operandos tienen el mismo tipo de datos, por lo que SQL Server realiza la operación correctamente sin necesidad de realizar conversiones implícitas.

Otra forma de hacer esta operación en particular es con CONCAT() función:

SELECT CONCAT('Age: ', 10);

Resultado:

Age: 10

El CONCAT() function es una función de cadena y, por lo tanto, convierte implícitamente todos los argumentos en tipos de cadena antes de la concatenación. Por lo tanto, no era necesario que realizáramos una conversión explícita.

Sin embargo, si el operando de cadena se puede convertir implícitamente en un número, entonces no causará un error al usar el + operador:

SELECT '10' + 10;

Resultado:

20

Pero en este caso, el + El operador se convierte en un operador matemático de suma, en lugar de un operador de concatenación de cadenas.