Nedan finns en lista som innehåller SQL Server-datatyperna, i prioritetsordning.
- användardefinierade datatyper (högst)
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
(inklusivenvarchar(max)
)nchar
varchar
(inklusivevarchar(max)
)char
varbinary
(inklusivevarbinary(max)
)binary
(lägst)
När du använder en operator för att kombinera operander av olika datatyper, konverteras datatypen med lägre prioritet först till datatypen med högre prioritet.
Om konverteringen inte är en implicit konvertering som stöds, returneras ett felmeddelande.
Om båda operanderna är av samma typ, görs (eller behövs) ingen konvertering och resultatet av operationen använder operandernas datatyp.
Exempel
Här är ett exempel på en implicit konvertering som lyckas:
SELECT 1 * 1.00;
Resultat:
1.00
Här konverterades den vänstra operanden till datatypen för den högra operanden.
Här är ett mer explicit sätt att göra det:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;
Resultat:
1.00
I det här fallet deklarerade jag uttryckligen den vänstra operanden som en INT
och den högra operanden som DECIMAL(5, 2)
.
Vi kan undersöka resultaten ytterligare med sys.dm_exec_describe_first_result_set
system dynamisk förvaltningsfunktion.
Denna funktion gör det möjligt för oss att kontrollera datatypen för varje kolumn som returneras i en fråga:
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);
Resultat:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Här kan vi se att varje rad representerar varje kolumn som returneras av frågan. Därför var den första kolumnen en INT
, den andra kolumnen var DECIMAL(5,2)
, och den tredje kolumnen en DECIMAL(16,2)
.
Så SQL Server returnerade faktiskt en DECIMAL(16,2)
, även om det ursprungliga decimalvärdet var en DECIMAL(5,2)
.
Exempel på ett konverteringsfel
Som nämnts, om konverteringen inte är en implicit konvertering som stöds, returneras ett felmeddelande:
SELECT 'Age: ' + 10;
Resultat:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
I det här fallet försökte jag sammanfoga en sträng (VARCHAR
) och ett nummer (INT
). Ses som INT
har högre prioritet än VARCHAR
, försökte SQL Server implicit konvertera strängen till en INT
.
Detta misslyckades eftersom den här strängen inte kan konverteras till ett heltal.
För att övervinna detta kan vi först konvertera INT
till VARCHAR
:
SELECT 'Age: ' + CAST(10 AS VARCHAR(2));
Resultat:
Age: 10
Nu har båda operanderna samma datatyp, så SQL Server utför operationen framgångsrikt utan att behöva utföra några implicita konverteringar.
Ett annat sätt att göra just denna operation är med CONCAT()
funktion:
SELECT CONCAT('Age: ', 10);
Resultat:
Age: 10
CONCAT()
funktion är en strängfunktion och konverterar därför implicit alla argument till strängtyper före sammanlänkning. Därför behövde vi inte utföra en explicit konvertering.
Men om strängoperanden implicit kan konverteras till ett tal, kommer det inte att orsaka ett fel när du använder +
operatör:
SELECT '10' + 10;
Resultat:
20
Men i det här fallet, +
operatorn förvandlas till en matematisk additionsoperator, snarare än en strängsammansättningsoperator.