Průvodce databází

Možná jste se při práci se serverem SQL Server setkali s funkcemi T-SQL PARSE(), CAST() a CONVERT() a zajímalo vás, jaký je mezi nimi rozdíl. Všechny tři funkce zdánlivě dělají totéž, ale jsou mezi nimi jemné rozdíly.

V tomto článku se snažím nastínit hlavní rozdíly mezi těmito funkcemi.

Srovnání

Tady je tabulka, která uvádí hlavní rozdíly mezi funkcemi CONVERT(), CAST() a PARSE() v SQL Serveru:

CONVERT() CAST() PARSE()
Oficiální definice Převádí výraz jednoho datového typu na jiný. Převádí výraz jednoho datového typu na jiný. Vrací výsledek výrazu převedený na požadovaný datový typ v SQL Serveru.
Přijatelná hodnota Jakýkoli platný výraz. Jakýkoli platný výraz. Řetězec.
Vrácená hodnota Druhý argument, přeložený na požadovaný datový typ podle 1. argumentu. 1. argument, přeložený na požadovaný datový typ, jak jej poskytuje 2. argument. 1. argument, přeložený na požadovaný datový typ, jak jej poskytuje 2. argument.
Podporované převody Mezi libovolnými dvěma datovými typy. Mezi libovolnými dvěma datovými typy. Pouze z řetězce na typ datum/čas a číslo.
Přijímá argument stylu? Ano. Ne. Ne.
Přijímá argument kultura? Ne. Ne. Ano.
Vyžaduje .NET Framework? Ne. Ne. Ano.

Několik dalších bodů k výše uvedené tabulce:

  • Dokumentace Microsoftu upozorňuje, že PARSE() nebude vzdálený (protože závisí na přítomnosti CLR). Remotování funkce, která vyžaduje CLR, by způsobilo chybu na vzdáleném serveru.
  • Existují některé hodnoty, se kterými si PARSE() poradí, ale CAST() a CONVERT() ne (například řetězce používající určité formáty data).
  • CAST() je obsažen ve standardu ANSI SQL-92.
  • Někteří tvrdí, že CAST() má lepší výkon než ostatní dva.
  • Při analýze řetězcových hodnot dochází k určité výkonnostní režii. Proto bude PARSE() obvykle pracovat pomaleji než ostatní dvě.

Níže jsou uvedeny příklady situací, kdy by každá z funkcí byla nejvhodnější.

Kdy použít CAST()

Dobře by se dalo argumentovat pro použití CAST() pro jakýkoli scénář, který není uveden níže. Jak již bylo zmíněno, CAST() je součástí standardu ANSI SQL od SQL-92, takže by měla být lépe přenositelná mezi různými DBMS (pokud je to požadavek).

Někteří také tvrdí, že CAST() má lepší výkon než ostatní dvě (zde je zajímavý článek, který porovnává výkon všech tří funkcí).

Existují však i pádné důvody, proč byste mohli (nebo museli) raději použít CONVERT() než CAST().

Kdy použít funkci CONVERT()

Funkce CONVERT() se může hodit, když potřebujete pomocí argumentu style určit, jak má být datum formátováno při převodu mezi datem a řetězcem. Zde je několik příkladů:

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';

Výsledek:

+---------------------+------------+------------+------------+| 100 | 101 | 102 | 103 ||---------------------+------------+------------+------------|| Jun 7 2018 2:35AM | 06/07/2018 | 2018.06.07 | 07/06/2018 |+---------------------+------------+------------+------------+

To můžete provést pouze pomocí CONVERT(), protože:

  • CAST() nepodporuje argument style; a
  • PARSE() nepřevádí datum/čas na řetězcovou hodnotu (také nepodporuje argument style)

Kdy použít PARSE()

Přes různé nevýhody této funkce (výkon, závislost na .NET, omezené konverze datových typů), má také některé výhody a existují scénáře, kdy by mohla být jedinou volbou. Například při zadávání data, které obsahuje název dne v týdnu, jako je pátek 20. července 2018.

Když ostatní vracejí chybu

Tady jsou příklady, kdy PARSE() je jedinou funkcí ze tří, která dokáže úspěšně převést hodnotu, aniž by vyhodila chybu.

V těchto příkladech se pokusíme převést různé řetězcové hodnoty na datový typ datum. Námi zadané řetězcové hodnoty však obsahují název dne v týdnu. To způsobuje problémy u CAST() a CONVERT(), ale PARSE() nemá žádný problém.

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';

Výsledek:

+------------+------------+------------+| Result 1 | Result 2 | Result 3 ||------------+------------+------------|| 2018-07-20 | 2018-07-20 | 2018-07-20 |+------------+------------+------------+

Takže PARSE() nemá žádný problém s formátem data, který poskytujeme.

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';

Výsledek:

Conversion failed when converting date and/or time from character string.

Takže CONVERT() není schopen převést řetězec, když je v takovém formátu.

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';

Výsledek:

Conversion failed when converting date and/or time from character string.

I CAST() vrací stejnou chybu.

Pokud tedy zjistíte, že se vám u ostatních dvou funkcí objevují chyby, zkuste raději PARSE().

Zadání kultury

Dalším případem, kdy byste mohli raději použít funkci PARSE(), je zadání kultury/jazyka, ve kterém je řetězec zadán. Funkce PARSE() má nepovinný argument, který umožňuje určit, která kultura se má použít. Pokud je vynechána, použije se jazyk aktuální relace.

Příklad zahrnutí argumentu culture:

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';

Výsledek:

+------------+------------+| Result 1 | Result 2 ||------------+------------|| 2018-07-01 | 2018-01-07 |+------------+------------+

Alternativa kultury

Přes výhodu možnosti zadat kulturu pomocí PARSE() máte možnost změnit nastavení jazyka, což znamená, že stejného efektu byste mohli dosáhnout při použití CAST() nebo CONVERT().

Příklad použití SET LANGUAGE us_english před dotazem změní aktuální nastavení jazyka na us_english. To sice neumožňuje zadat různé kultury v rámci dotazu (jako ve výše uvedeném příkladu), ale ovlivní to celý dotaz (a všechny následující dotazy).

Stejným způsobem můžete změnit i nastavení formátu data. Například SET DATEFORMAT mdy.

Tady je příklad změny nastavení jazyka před spuštěním dotazu s CAST() a CONVERT():

Němčina:

SET LANGUAGE German;SELECT CONVERT(date, '07/01/2018') AS 'Convert';SELECT CAST('07/01/2018' AS date) AS 'Cast';

Výsledek:

+------------+| 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';

Výsledek:

+------------+| Convert ||------------|| 2018-07-01 |+------------+Changed language setting to us_english.+------------+| Cast ||------------|| 2018-07-01 |+------------+

Pamatujte, že při tomto postupu měníte prostředí jazyka/formátu data pro danou relaci. Nezapomeňte jej změnit zpět!

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.