Du kanske har stött på T-SQL PARSE()
, CAST()
, och CONVERT()
fungerar när man arbetar med SQL Server och undrade vad skillnaden är. Alla tre funktionerna verkar göra samma sak, men det finns subtila skillnader mellan dem.
I den här artikeln vill jag beskriva de viktigaste skillnaderna mellan dessa funktioner.
Jämförelse
Här är en tabell som beskriver de viktigaste skillnaderna mellan CONVERT()
, CAST()
, och PARSE()
funktioner i SQL Server:
CONVERT() | CAST() | PARSE() | |
---|---|---|---|
Officiell definition | Konverterar ett uttryck av en datatyp till en annan. | Konverterar ett uttryck av en datatyp till en annan. | Returnerar resultatet av ett uttryck, översatt till den begärda datatypen i SQL Server. |
Accepterat värde | Alla giltiga uttryck. | Alla giltiga uttryck. | Sträng. |
Returvärde | 2:a argumentet, översatt till den begärda datatypen som tillhandahålls av det första argumentet. | Första argumentet, översatt till den begärda datatypen som tillhandahålls av det andra argumentet. | Första argumentet, översatt till den begärda datatypen som tillhandahålls av det andra argumentet. |
Omvandlingar som stöds | Mellan två valfria datatyper. | Mellan två valfria datatyper. | Endast från sträng till datum/tid och nummertyper. |
Accepterar stilen Argument? | Ja. | Nej. | Nej. |
Accepterar kulturen Argument? | Nej. | Nej. | Ja. |
Kräver .NET Framework? | Nej. | Nej. | Ja. |
Några andra punkter utöver tabellen ovan:
- Microsoft-dokumentationen påpekar att
PARSE()
kommer inte att fjärrstyras (eftersom det beror på närvaron av CLR). Att fjärrstyra en funktion som kräver CLR skulle orsaka ett fel på fjärrservern. - Det finns några värden som
PARSE()
kan hantera menCAST()
ochCONVERT()
kan inte (till exempel strängar som använder vissa datumformat). CAST()
ingår i ANSI SQL-92-standarden.- Vissa hävdar att
CAST()
har bättre prestanda än de andra två. - Det finns en viss prestandaoverhead vid analys av strängvärden. Därför
PARSE()
kommer vanligtvis att gå långsammare än de andra två.
Nedan finns exempel på situationer där varje funktion skulle vara den mest lämpliga.
När ska CAST() användas
Ett bra argument kan göras för att använda CAST()
för alla scenarion som inte är listade nedan. Som nämnts, CAST()
har varit en del av ANSI SQL-standarden sedan SQL-92, så den borde vara mer portabel mellan olika DBMS (om det är ett krav).
Vissa hävdar också att CAST()
har bättre prestanda än de andra två (här är en intressant artikel som jämför prestandan mellan alla tre funktionerna).
Det finns dock också giltiga skäl till att du kanske föredrar (eller behöver) använda CONVERT()
över CAST()
.
När ska CONVERT() användas
CONVERT()
funktionen kan vara praktisk när du behöver använda style
argument för att ange hur datumet ska formateras vid konvertering mellan ett datum och en sträng. Här är några exempel:
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 bara göra detta med CONVERT()
eftersom:
CAST()
stöder intestyle
argument; ochPARSE()
konverterar inte från ett datum/tid till ett strängvärde (det stöder inte hellerstyle
argument)
När ska PARSE() användas
Trots de olika nackdelarna med denna funktion (prestanda, beroende av .NET, begränsade datatypkonverteringar) har den också vissa fördelar, och det finns vissa scenarier där det kan vara ditt enda val. Till exempel när du anger ett datum som inkluderar veckodagsnamnet, som fredagen den 20 juli 2018 .
När de andra returnerar ett fel
Här är exempel där PARSE()
är den enda funktionen av de tre som framgångsrikt kan konvertera värdet utan att skapa ett fel.
I dessa exempel försöker vi konvertera olika strängvärden till ett datum data typ. Strängvärdena vi tillhandahåller inkluderar dock veckodagsnamnet. Detta orsakar problem för CAST()
och CONVERT()
, men PARSE()
har inga 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 inga problem med formatet på datumet som vi tillhandahåller.
KONVERTERA()
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.
Alltså CONVERT()
kan inte konvertera strängen när den är i ett 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.
Och CAST()
returnerar samma fel.
Så om du märker att du får fel med de andra två funktionerna, försök med PARSE()
istället.
Specificera kulturen
Ett annat scenario där du kanske föredrar att använda PARSE()
funktion är när man anger kulturen/språket som strängen tillhandahålls i. PARSE()
har ett valfritt argument som låter dig specificera vilken kultur du ska använda. Om det utelämnas används språket för den aktuella sessionen.
Exempel på att inkludera 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 | +------------+------------+
Ett kulturalternativ
Trots fördelen med att kunna specificera kulturen med PARSE()
, du har möjlighet att ändra språkinställningarna, vilket innebär att du kan uppnå samma effekt när du använder CAST()
eller CONVERT()
.
Använd till exempel SET LANGUAGE us_english
före frågan ändrar de aktuella språkinställningarna till us_english . Även om detta inte tillåter dig att ange olika kulturer i frågan (som i exemplet ovan), påverkar det hela frågan (och eventuella efterföljande frågor).
Du kan också ändra inställningarna för datumformat på samma sätt. Till exempel, SET DATEFORMAT mdy
.
Här är ett exempel på hur du ändrar språkinställningen innan du kör en fråga med CAST()
och CONVERT()
:
Tyska:
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_english:
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 | +------------+
Kom ihåg att när du gör detta ändrar du språk-/datumformatmiljön för sessionen. Glöm inte att ändra tillbaka!