Hieronder vindt u een lijst met de SQL Server-gegevenstypen, in volgorde van prioriteit.
- door de gebruiker gedefinieerde gegevenstypen (hoogste)
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
(inclusiefnvarchar(max)
)nchar
varchar
(inclusiefvarchar(max)
)char
varbinary
(inclusiefvarbinary(max)
)binary
(laagste)
Wanneer u een operator gebruikt om operanden van verschillende gegevenstypen te combineren, wordt het gegevenstype met de lagere prioriteit eerst geconverteerd naar het gegevenstype met de hogere prioriteit.
Als de conversie geen ondersteunde impliciete conversie is, wordt een fout geretourneerd.
Als beide operanden van hetzelfde type zijn, wordt er geen conversie uitgevoerd (of nodig) en gebruikt het resultaat van de bewerking het gegevenstype van de operanden.
Voorbeeld
Hier is een voorbeeld van een impliciete conversie die slaagt:
SELECT 1 * 1.00;
Resultaat:
1.00
Hier werd de linker operand geconverteerd naar het gegevenstype van de rechter operand.
Hier is een meer expliciete manier om het te doen:
DECLARE
@n1 INT,
@n2 DECIMAL(5, 2);
SET @n1 = 1;
SET @n2 = 1;
SELECT @n1 * @n2;
Resultaat:
1.00
In dit geval heb ik de linker operand expliciet gedeclareerd als een INT
en de rechter operand als DECIMAL(5, 2)
.
We kunnen de resultaten verder onderzoeken met de sys.dm_exec_describe_first_result_set
systeem dynamische beheerfunctie.
Met deze functie kunnen we het gegevenstype van elke kolom controleren die in een zoekopdracht wordt geretourneerd:
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);
Resultaat:
+--------------------+--------------+-------------+---------+ | system_type_name | max_length | precision | scale | |--------------------+--------------+-------------+---------| | int | 4 | 10 | 0 | | decimal(5,2) | 5 | 5 | 2 | | decimal(16,2) | 9 | 16 | 2 | +--------------------+--------------+-------------+---------+
Hier kunnen we zien dat elke rij elke kolom vertegenwoordigt die door de query wordt geretourneerd. Daarom was de eerste kolom een INT
, de tweede kolom was DECIMAL(5,2)
, en de derde kolom a DECIMAL(16,2)
.
Dus SQL Server retourneerde feitelijk een DECIMAL(16,2)
, ook al was de oorspronkelijke decimale waarde a DECIMAL(5,2)
.
Voorbeeld van een conversiefout
Zoals vermeld, wordt er een fout geretourneerd als de conversie geen ondersteunde impliciete conversie is:
SELECT 'Age: ' + 10;
Resultaat:
Msg 245, Level 16, State 1, Line 1 Conversion failed when converting the varchar value 'Age: ' to data type int.
In dit geval probeerde ik een string samen te voegen (VARCHAR
) en een nummer (INT
). Zien als INT
heeft een hogere prioriteit dan VARCHAR
, SQL Server probeerde de tekenreeks impliciet te converteren naar een INT
.
Dit is mislukt, omdat deze string niet kan worden geconverteerd naar een geheel getal.
Om dit te verhelpen, kunnen we eerst de INT
. converteren naar VARCHAR
:
SELECT 'Age: ' + CAST(10 AS VARCHAR(2));
Resultaat:
Age: 10
Nu hebben beide operanden hetzelfde gegevenstype, en dus voert SQL Server de bewerking met succes uit zonder de noodzaak om impliciete conversies uit te voeren.
Een andere manier om deze specifieke bewerking uit te voeren is met de CONCAT()
functie:
SELECT CONCAT('Age: ', 10);
Resultaat:
Age: 10
De CONCAT()
functie is een tekenreeksfunctie en converteert daarom impliciet alle argumenten naar tekenreekstypes vóór aaneenschakeling. Daarom was het voor ons niet nodig om een expliciete conversie uit te voeren.
Als de tekenreeksoperand echter impliciet kan worden geconverteerd naar een getal, zal het geen fout veroorzaken bij het gebruik van de +
operator:
SELECT '10' + 10;
Resultaat:
20
Maar in dit geval, de +
operator verandert in een wiskundige operator voor optellen, in plaats van een operator voor het samenvoegen van tekenreeksen.