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