Poniżej znajduje się lista zawierająca typy danych SQL Server, w porządku pierwszeństwa.
- typy danych zdefiniowane przez użytkownika (najwyższy)
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
(w tymnvarchar(max)
)nchar
varchar
(w tymvarchar(max)
)char
varbinary
(w tymvarbinary(max)
)binary
(najniższy)
Kiedy używasz operatora do łączenia operandów różnych typów danych, typ danych o niższym priorytecie jest najpierw konwertowany na typ danych o wyższym priorytecie.
Jeśli konwersja nie jest obsługiwaną konwersją niejawną, zwracany jest błąd.
Jeśli oba operandy są tego samego typu, konwersja nie jest wykonywana (ani nie jest potrzebna), a wynik operacji wykorzystuje typ danych operandów.
Przykład
Oto przykład udanej konwersji niejawnej:
SELECT 1 * 1.00;
Wynik:
1.00
Tutaj lewy operand został przekonwertowany na typ danych prawego operandu.
Oto bardziej wyraźny sposób na zrobienie tego:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;
Wynik:
1.00
W tym przypadku jawnie zadeklarowałem lewy operand jako INT
a prawy operand to DECIMAL(5, 2)
.
Możemy dokładniej zbadać wyniki za pomocą sys.dm_exec_describe_first_result_set
funkcja dynamicznego zarządzania systemem.
Ta funkcja pozwala nam sprawdzić typ danych każdej kolumny zwróconej w zapytaniu:
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);
Wynik:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Tutaj widzimy, że każdy wiersz reprezentuje każdą kolumnę zwróconą przez zapytanie. Dlatego pierwsza kolumna to INT
, druga kolumna to DECIMAL(5,2)
, a trzecia kolumna DECIMAL(16,2)
.
Więc SQL Server faktycznie zwrócił DECIMAL(16,2)
, mimo że oryginalna wartość dziesiętna była a DECIMAL(5,2)
.
Przykład błędu konwersji
Jak wspomniano, jeśli konwersja nie jest obsługiwaną konwersją niejawną, zwracany jest błąd:
SELECT 'Age: ' + 10;
Wynik:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
W tym przypadku próbowałem połączyć ciąg (VARCHAR
) i liczbę (INT
). Widząc jako INT
ma wyższy priorytet niż VARCHAR
, SQL Server próbował niejawnie przekonwertować ciąg na INT
.
To się nie powiodło, ponieważ tego ciągu nie można przekonwertować na liczbę całkowitą.
Aby rozwiązać ten problem, możemy najpierw przekonwertować INT
do VARCHAR
:
SELECT 'Age: ' + CAST(10 AS VARCHAR(2));
Wynik:
Age: 10
Teraz oba operandy mają ten sam typ danych, więc SQL Server pomyślnie wykonuje operację bez konieczności wykonywania jakichkolwiek niejawnych konwersji.
Innym sposobem wykonania tej konkretnej operacji jest użycie CONCAT()
funkcja:
SELECT CONCAT('Age: ', 10);
Wynik:
Age: 10
CONCAT()
function jest funkcją ciągu i dlatego niejawnie konwertuje wszystkie argumenty na typy ciągów przed połączeniem. Dlatego nie było potrzeby, abyśmy przeprowadzali jawną konwersję.
Jeśli jednak operand ciągu może być niejawnie przekonwertowany na liczbę, nie spowoduje to błędu przy użyciu +
operator:
SELECT '10' + 10;
Wynik:
20
Ale w tym przypadku +
operator zamienia się w operator matematyczny dodawania, a nie w operator konkatenacji.