Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Приоритет на типа данни в SQL Server

По-долу е даден списък, съдържащ типовете данни на SQL Server, подредени по приоритет.

  1. Дефинирани от потребителя типове данни (най-високи)
  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 (включително nvarchar(max) )
  26. nchar
  27. varchar (включително varchar(max) )
  28. char
  29. varbinary (включително varbinary(max) )
  30. binary (най-ниско)

Когато използвате оператор за комбиниране на операнди от различни типове данни, типът данни с по-нисък приоритет първо се преобразува в типа данни с по-висок приоритет.

Ако преобразуването не е поддържано имплицитно преобразуване, се връща грешка.

Ако и двата операнда са от един и същи тип, тогава не се извършва преобразуване (или е необходимо) и резултатът от операцията използва типа данни на операндите.

Пример

Ето пример за неявно преобразуване, което е успешно:

SELECT 1 * 1.00;

Резултат:

1.00

Тук левият операнд беше преобразуван в типа данни на десния операнд.

Ето по-ясен начин да го направите:

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

Резултат:

1.00

В този случай изрично декларирах левия операнд като INT и десния операнд като DECIMAL(5, 2) .

Можем допълнително да разгледаме резултатите с sys.dm_exec_describe_first_result_set функция за динамично управление на системата.

Тази функция ни позволява да проверим типа данни на всяка колона, върната в заявка:

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);

Резултат:

+--------------------+--------------+-------------+---------+
| system_type_name   | max_length   | precision   | scale   |
|--------------------+--------------+-------------+---------|
| int                | 4            | 10          | 0       |
| decimal(5,2)       | 5            | 5           | 2       |
| decimal(16,2)      | 9            | 16          | 2       |
+--------------------+--------------+-------------+---------+

Тук можем да видим, че всеки ред представлява всяка колона, върната от заявката. Следователно първата колона беше INT , втората колона беше DECIMAL(5,2) , а третата колона DECIMAL(16,2) .

Така SQL Server всъщност върна DECIMAL(16,2) , въпреки че първоначалната десетична стойност беше DECIMAL(5,2) .

Пример за грешка при преобразуване

Както споменахме, ако преобразуването не е поддържано имплицитно преобразуване, се връща грешка:

SELECT 'Age: ' + 10;

Резултат:

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

В този случай се опитвах да свържа низ (VARCHAR ) и число (INT ). Вижда се като INT има по-висок приоритет от VARCHAR , SQL Server се опита имплицитно да преобразува низа в INT .

Това не бе успешно, защото този низ не може да бъде преобразуван в цяло число.

За да преодолеем това, можем първо да преобразуваме INT към VARCHAR :

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

Резултат:

Age: 10

Сега и двата операнда имат един и същ тип данни и така SQL Server изпълнява операцията успешно, без да е необходимо да извършва неявни преобразувания.

Друг начин за извършване на тази конкретна операция е с CONCAT() функция:

SELECT CONCAT('Age: ', 10);

Резултат:

Age: 10

CONCAT() функцията е низова функция и следователно имплицитно преобразува всички аргументи в низови типове преди конкатенацията. Следователно нямаше нужда да извършваме изрично преобразуване.

Въпреки това, ако низовият операнд може да бъде имплицитно преобразуван в число, тогава той няма да причини грешка при използване на + оператор:

SELECT '10' + 10;

Резултат:

20

Но в този случай + операторът се превръща в математически оператор за събиране, а не в оператор за конкатенация на низове.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да извлека записи за последните 30 минути в MS SQL?

  2. Динамично маскиране на данни в SQL Server за начинаещи

  3. Използване на DMV (изглед за динамично управление) и DMF (функция за динамично управление) | Отстраняване на проблеми с производителността на SQL Server -4

  4. Как да копирате огромни данни от таблица в друга таблица в SQL Server

  5. Как да коригирате грешка Msg 7325 в SQL Server:„Обекти, излагащи колони с типове CLR, не са разрешени в разпределени заявки“