По-долу е даден списък, съдържащ типовете данни на SQL Server, подредени по приоритет.
- Дефинирани от потребителя типове данни (най-високи)
sql_variantxmldatetimeoffsetdatetime2datetimesmalldatetimedatetimefloatrealdecimalmoneysmallmoneybigintintsmallinttinyintbitntexttextimagetimestampuniqueidentifiernvarchar(включителноnvarchar(max))ncharvarchar(включителноvarchar(max))charvarbinary(включителноvarbinary(max))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
Но в този случай + операторът се превръща в математически оператор за събиране, а не в оператор за конкатенация на низове.