sql >> Database >  >> RDS >> Sqlserver

Voorrang van gegevenstype in SQL Server

Hieronder vindt u een lijst met de SQL Server-gegevenstypen, in volgorde van prioriteit.

  1. door de gebruiker gedefinieerde gegevenstypen (hoogste)
  2. sql_variant
  3. xml
  4. datetimeoffset
  5. datetime2
  6. datetime
  7. smalldatetime
  8. date
  9. time
  10. float
  11. real
  12. decimal
  13. money
  14. smallmoney
  15. bigint
  16. int
  17. smallint
  18. tinyint
  19. bit
  20. ntext
  21. text
  22. image
  23. timestamp
  24. uniqueidentifier
  25. nvarchar (inclusief nvarchar(max) )
  26. nchar
  27. varchar (inclusief varchar(max) )
  28. char
  29. varbinary (inclusief varbinary(max) )
  30. 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.


  1. Hoe de RTRIM()-functie werkt in MySQL

  2. Foutcode:2013. Verbinding met MySQL-server verbroken tijdens zoekopdracht

  3. Prioriteiten implementeren in SQL (postgres)

  4. Hoe de WEIGHT_STRING()-functie werkt in MySQL