Database.Guide

Kanske har du stött på T-SQL-funktionerna PARSE(), CAST() och CONVERT() när du arbetar med SQL Server och undrat 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.

Varje jämförelse

Här finns en tabell som beskriver de viktigaste skillnaderna mellan funktionerna CONVERT(), CAST() och PARSE() i SQL Server:

CONVERT() CAST() PARSE()
Official 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. String.
Return Value 2:a argumentet, översatt till den begärda datatypen som tillhandahålls av det första argumentet. 1:a argumentet, översatt till den begärda datatypen enligt det andra argumentet. 1:a argumentet, översatt till den begärda datatypen enligt det andra argumentet.
Stödda konverteringar Mellan två valfria datatyper. Mellan två valfria datatyper. Endast från sträng till datum/tid och taltyper.
Accepterar stilargumentet? Ja. Nej. Nej.
Accepterar argumentet culture? Nej. Nej. Ja.
Kräver .NET Framework? Nej. Nej. Ja.

Några andra punkter utöver tabellen ovan:

  • Microsofts dokumentation påpekar att PARSE() inte kommer att remoted (eftersom det är beroende av att CLR finns). Remoting av en funktion som kräver CLR skulle orsaka ett fel på fjärrservern.
  • Det finns vissa värden som PARSE() kan hantera men som CAST() och CONVERT() inte kan hantera (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 prestandafördyring när strängvärden analyseras. Därför kommer PARSE() vanligtvis att köras långsammare än de andra två.

Nedan följer exempel på situationer där varje funktion skulle vara mest lämplig.

När man ska använda CAST()

Det går att argumentera för att använda CAST() för alla scenarier som inte är listade nedan. Som nämnts har CAST() varit en del av ANSI SQL-standarden sedan SQL-92, så den borde vara mer portabel mellan olika DBMS (om det är ett krav).

Det finns också en del som hävdar att CAST() har bättre prestanda än de andra två (här finns en intressant artikel som jämför prestandan mellan alla tre funktionerna).

Det finns dock också giltiga skäl som gör att du kanske föredrar (eller behöver) använda CONVERT() framför CAST().

När du ska använda CONVERT()

Funktionen CONVERT() kan komma väl till pass när du behöver använda style-argumentet för att specificera hur datumet ska formateras vid konverteringen 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() har inte stöd för argumentet style; och
  • PARSE() konverterar inte från datum/tid till ett strängvärde (den har inte heller stöd för argumentet style)

När du ska använda PARSE()

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 den kan vara ditt enda val. Till exempel när du tillhandahåller ett datum som innehåller veckodagsnamnet, som fredag 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 kasta ett fel.

I de här exemplen försöker vi konvertera olika strängvärden till en datatyp för datum. De strängvärden som 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 |+------------+------------+------------+

PARSE() har inga problem med datumformatet som vi tillhandahåller.

CONVERT()

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.

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 upptäcker att du får fel med de andra två funktionerna kan du prova PARSE() istället.

Specificering av kultur

Ett annat scenario där du kanske föredrar att använda funktionen PARSE() är när du specificerar den kultur/det språk som strängen tillhandahålls på. PARSE() har ett valfritt argument som gör att du kan ange vilken kultur som ska användas. Om det utelämnas används språket för den aktuella sessionen.

Exempel på att inkludera culture-argumentet:

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() har du möjlighet att ändra språkinställningarna, vilket innebär att du skulle kunna uppnå samma effekt när du använder CAST() eller CONVERT().

Till exempel: om du använder SET LANGUAGE us_english före frågan ändras de aktuella språkinställningarna till us_english. Även om detta inte gör det möjligt 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 datumformatet på samma sätt. Till exempel SET DATEFORMAT mdy.

Här är ett exempel på att ändra 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 |+------------+

Håll i minnet att när du gör detta ändrar du språket/datumformatmiljön för sessionen. Glöm inte att ändra det igen!

Lämna ett svar

Din e-postadress kommer inte publiceras.