Måske har du stødt på T-SQL PARSE()
, CAST()
, og CONVERT()
fungerer, når du arbejder med SQL Server og spekulerede på, hvad forskellen er. Alle tre funktioner ser ud til at gøre det samme, men der er subtile forskelle mellem dem.
I denne artikel sigter jeg mod at skitsere de vigtigste forskelle mellem disse funktioner.
Sammenligning
Her er en tabel, der skitserer de vigtigste forskelle mellem CONVERT()
, CAST()
, og PARSE()
funktioner i SQL Server:
KONVERT() | CAST() | PARSE() | |
---|---|---|---|
Officiel definition | Konverterer et udtryk for én datatype til en anden. | Konverterer et udtryk for én datatype til en anden. | Returnerer resultatet af et udtryk, oversat til den anmodede datatype i SQL Server. |
Accepteret værdi | Ethvert gyldigt udtryk. | Ethvert gyldigt udtryk. | String. |
Returværdi | 2. argument, oversat til den anmodede datatype som angivet af det 1. argument. | 1. argument, oversat til den anmodede datatype som angivet af det 2. argument. | 1. argument, oversat til den anmodede datatype som angivet af det 2. argument. |
Understøttede konverteringer | Mellem to vilkårlige datatyper. | Mellem to vilkårlige datatyper. | Kun fra streng til dato/tid og taltyper. |
Accepterer stilen Argument? | Ja. | Nej. | Nej. |
Accepterer kulturen Argument? | Nej. | Nej. | Ja. |
Kræver .NET Framework? | Nej. | Nej. | Ja. |
Nogle andre punkter ud over ovenstående tabel:
- Microsoft-dokumentationen påpeger, at
PARSE()
vil ikke blive fjernstyret (da det afhænger af tilstedeværelsen af CLR). Fjernelse af en funktion, der kræver CLR, vil forårsage en fejl på fjernserveren. - Der er nogle værdier, der
PARSE()
kan håndtere menCAST()
ogCONVERT()
kan ikke (f.eks. strenge, der bruger bestemte datoformater). CAST()
er inkluderet i ANSI SQL-92-standarden.- Nogle hævder, at
CAST()
har bedre ydeevne end de to andre. - Der er en vis præstationsoverhead ved parsing af strengværdier. Derfor
PARSE()
vil typisk køre langsommere end de to andre.
Nedenfor er eksempler på situationer, hvor hver funktion ville være den bedst egnede.
Hvornår skal CAST() bruges
Et godt argument kunne fremføres for at bruge CAST()
for ethvert scenarie, der ikke er angivet nedenfor. Som nævnt, CAST()
har været en del af ANSI SQL-standarden siden SQL-92, så den burde være mere portabel mellem forskellige DBMS'er (hvis det er et krav).
Nogle hævder også, at CAST()
har bedre ydeevne end de to andre (her er en interessant artikel, der sammenligner ydeevnen mellem alle tre funktioner).
Der er dog også gyldige grunde til, at du måske foretrækker (eller har brug for) at bruge CONVERT()
over CAST()
.
Hvornår skal CONVERT() bruges
CONVERT()
funktionen kan være praktisk, når du skal bruge style
argument for at angive, hvordan datoen skal formateres ved konvertering mellem en dato og en streng. Her er nogle eksempler:
DECLARE @date datetime2 = '2018-06-07 02:35:52.8537677'; SELECT CONVERT(nvarchar(30), @date, 100) AS '100', CONVERT(nvarchar(30), @date, 101) AS '101', CONVERT(nvarchar(30), @date, 102) AS '102', CONVERT(nvarchar(30), @date, 103) AS '103';
Resultat:
+---------------------+------------+------------+------------+ | 100 | 101 | 102 | 103 | |---------------------+------------+------------+------------| | Jun 7 2018 2:35AM | 06/07/2018 | 2018.06.07 | 07/06/2018 | +---------------------+------------+------------+------------+
Du kan kun gøre dette med CONVERT()
fordi:
CAST()
understøtter ikkestyle
argument; ogPARSE()
konverterer ikke fra en dato/tid til en strengværdi (det understøtter heller ikkestyle
argument)
Hvornår skal PARSE() bruges
På trods af de forskellige ulemper ved denne funktion (ydeevne, afhængighed af .NET, begrænsede datatypekonverteringer), har den også nogle fordele, og der er nogle scenarier, hvor det kan være dit eneste valg. For eksempel, når du angiver en dato, der inkluderer ugedagsnavnet, f.eks. fredag den 20. juli 2018 .
Når de andre returnerer en fejl
Her er eksempler hvor PARSE()
er den eneste funktion af de tre, der med succes kan konvertere værdien uden at afgive en fejl.
I disse eksempler forsøger vi at konvertere forskellige strengværdier til en dato datatype. De strengværdier, vi angiver, inkluderer dog ugedagsnavnet. Dette forårsager problemer for CAST()
og CONVERT()
, men PARSE()
har intet problem.
PARSE()
SELECT PARSE('Friday, 20 July 2018' AS date) AS 'Result 1', PARSE('Fri, 20 July 2018' AS date) AS 'Result 2', PARSE('Friday 20 July 2018' AS date) AS 'Result 3';
Resultat:
+------------+------------+------------+ | Result 1 | Result 2 | Result 3 | |------------+------------+------------| | 2018-07-20 | 2018-07-20 | 2018-07-20 | +------------+------------+------------+
Så PARSE()
har intet problem med formatet på den dato, som vi oplyser.
KONVERT()
SELECT CONVERT(date, 'Friday, 20 July 2018') AS 'Result 1', CONVERT(date, 'Fri, 20 July 2018') AS 'Result 2', CONVERT(date, 'Friday 20 July 2018') AS 'Result 3';
Resultat:
Conversion failed when converting date and/or time from character string.
Så CONVERT()
er ikke i stand til at konvertere strengen, når den er i et sådant format.
CAST()
SELECT CAST('Friday, 20 July 2018' AS date) AS 'Result 1', CAST('Fri, 20 July 2018' AS date)AS 'Result 2', CAST('Friday 20 July 2018' AS date) AS 'Result 3';
Resultat:
Conversion failed when converting date and/or time from character string.
Og CAST()
returnerer den samme fejl.
Så hvis du oplever, at du får fejl med de to andre funktioner, så prøv PARSE()
i stedet.
Specificering af kulturen
Et andet scenarie, hvor du måske foretrækker at bruge PARSE()
funktion er, når man angiver kulturen/sproget, som strengen er leveret i. PARSE()
har et valgfrit argument, der giver dig mulighed for at angive, hvilken kultur du skal bruge. Hvis det udelades, bruges sproget for den aktuelle session.
Eksempel på at inkludere culture
argument:
SELECT PARSE('07/01/2018' AS date USING 'en-US') AS 'Result 1', PARSE('07/01/2018' AS date USING 'de-DE') AS 'Result 2';
Resultat:
+------------+------------+ | Result 1 | Result 2 | |------------+------------| | 2018-07-01 | 2018-01-07 | +------------+------------+
Et kulturelt alternativ
På trods af fordelen ved at kunne specificere kulturen med PARSE()
, du har mulighed for at ændre sprogindstillingerne, hvilket betyder, at du kan opnå den samme effekt, når du bruger CAST()
eller CONVERT()
.
For eksempel ved at bruge SET LANGUAGE us_english
før forespørgslen vil ændre de nuværende sprogindstillinger til us_english . Selvom dette ikke tillader dig at angive forskellige kulturer i forespørgslen (som i eksemplet ovenfor), påvirker det hele forespørgslen (og eventuelle efterfølgende forespørgsler).
Du kan også ændre datoformatindstillingerne på samme måde. For eksempel SET DATEFORMAT mdy
.
Her er et eksempel på ændring af sprogindstillingen, før du kører en forespørgsel med CAST()
og CONVERT()
:
Tysk:
SET LANGUAGE German; SELECT CONVERT(date, '07/01/2018') AS 'Convert'; SELECT CAST('07/01/2018' AS date) AS 'Cast';
Resultat:
+------------+ | Convert | |------------| | 2018-01-07 | +------------+ Die Spracheneinstellung wurde in Deutsch geändert. +------------+ | Cast | |------------| | 2018-01-07 | +------------+
us_engelsk:
SET LANGUAGE us_english; SELECT CONVERT(date, '07/01/2018') AS 'Convert'; SELECT CAST('07/01/2018' AS date) AS 'Cast';
Resultat:
+------------+ | Convert | |------------| | 2018-07-01 | +------------+ Changed language setting to us_english. +------------+ | Cast | |------------| | 2018-07-01 | +------------+
Husk, at når du gør dette, ændrer du sprog-/datoformatmiljøet for sessionen. Glem ikke at ændre det tilbage!