Pewnie spotkałeś się z funkcjami T-SQL PARSE()
, CAST()
i CONVERT()
podczas pracy z SQL Server i zastanawiałeś się, jaka jest różnica. Wszystkie trzy funkcje wydają się robić to samo, ale istnieją między nimi subtelne różnice.
W tym artykule staram się nakreślić główne różnice między tymi funkcjami.
Porównanie
Tutaj znajduje się tabela, która przedstawia główne różnice między funkcjami CONVERT()
, CAST()
i PARSE()
w SQL Server:
CONVERT() | CAST() | PARSE() | |
---|---|---|---|
Official Definition | Konwertuje wyrażenie jednego typu danych na inny. | Konwertuje wyrażenie jednego typu danych na inny. | Zwraca wynik wyrażenia, przetłumaczony na żądany typ danych w SQL Server. |
Accepted Value | Dowolne prawidłowe wyrażenie. | Dowolne prawidłowe wyrażenie. | String. |
Wartość zwrotna | Drugi argument, przetłumaczony na żądany typ danych podany przez pierwszy argument. | 1. argument, przetłumaczony na żądany typ danych podany przez 2. argument. | 1. argument, przetłumaczony na żądany typ danych podany przez 2. argument. |
Obsługiwane konwersje | Pomiędzy dwoma dowolnymi typami danych. | Pomiędzy dwoma dowolnymi typami danych. | Tylko z łańcuchów do typów daty/czasu i liczb. |
Akceptuje argument stylu? | Tak. | Nie. | Nie. |
Accepts the culture Argument? | Nie. | Nie. | Yes. |
Requires .NET Framework? | No. | No. | Yes. |
Kilka innych punktów oprócz powyższej tabeli:
- Dokumentacja Microsoft wskazuje, że
PARSE()
nie będzie remotowana (ponieważ zależy od obecności CLR). Remotowanie funkcji, która wymaga CLR, spowodowałoby błąd na zdalnym serwerze. - Istnieją pewne wartości, z którymi
PARSE()
może sobie poradzić, aleCAST()
iCONVERT()
nie (na przykład ciągi używające pewnych formatów daty). -
CAST()
jest zawarte w standardzie ANSI SQL-92. - Niektórzy twierdzą, że
CAST()
ma lepszą wydajność niż pozostałe dwa. - Podczas parsowania wartości łańcuchowych istnieje pewien narzut wydajności. Dlatego
PARSE()
zazwyczaj działa wolniej niż dwie pozostałe.
Poniżej znajdują się przykłady sytuacji, w których każda z funkcji byłaby najbardziej odpowiednia.
Kiedy używać CAST()
Dobry argument można by przedstawić za używaniem CAST()
dla każdego scenariusza, który nie jest wymieniony poniżej. Jak wspomniano, CAST()
jest częścią standardu ANSI SQL od SQL-92, więc powinien być bardziej przenośny między różnymi DBMS (jeśli jest to wymóg).
Również, niektórzy twierdzą, że CAST()
ma lepszą wydajność niż pozostałe dwie (tutaj jest ciekawy artykuł, który porównuje wydajność między wszystkimi trzema funkcjami).
Jednakże istnieją również ważne powody, dla których możesz preferować (lub potrzebować) używać CONVERT()
zamiast CAST()
.
Kiedy używać CONVERT()
Funkcja CONVERT()
może się przydać, gdy musisz użyć argumentu style
, aby określić, jak data powinna być sformatowana podczas konwersji między datą a łańcuchem. Oto kilka przykładów:
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';
Result:
+---------------------+------------+------------+------------+| 100 | 101 | 102 | 103 ||---------------------+------------+------------+------------|| Jun 7 2018 2:35AM | 06/07/2018 | 2018.06.07 | 07/06/2018 |+---------------------+------------+------------+------------+
Możesz to zrobić tylko za pomocą CONVERT()
, ponieważ:
-
CAST()
nie obsługuje argumentustyle
; oraz -
PARSE()
nie konwertuje z daty/czasu na wartość łańcuchową (również nie obsługuje argumentustyle
)
Kiedy używać PARSE()
Pomimo różnych wad tej funkcji (wydajność, zależność od .NET, ograniczone konwersje typów danych), ma ona również pewne zalety i są pewne scenariusze, w których może być jedynym wyborem. Na przykład, gdy dostarczamy datę, która zawiera nazwę dnia tygodnia, jak piątek, 20 lipca 2018 r.
Gdy inne zwracają błąd
Oto przykłady, w których PARSE()
jest jedyną funkcją z trzech, która może pomyślnie przekonwertować wartość bez rzucania błędu.
W tych przykładach próbujemy przekonwertować różne wartości łańcuchowe na typ danych daty. Jednak wartości łańcuchowe, które podajemy, zawierają nazwę dnia tygodnia. Powoduje to problemy dla CAST()
i CONVERT()
, ale PARSE()
nie ma z tym problemu.
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';
Result:
+------------+------------+------------+| Result 1 | Result 2 | Result 3 ||------------+------------+------------|| 2018-07-20 | 2018-07-20 | 2018-07-20 |+------------+------------+------------+
Więc PARSE()
nie ma problemu z formatem daty, którą podajemy.
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';
Result:
Conversion failed when converting date and/or time from character string.
Więc CONVERT()
nie jest w stanie przekonwertować ciągu znaków, gdy jest on w takim formacie.
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';
Result:
Conversion failed when converting date and/or time from character string.
And CAST()
returns the same error.
So if you find yourself getting errors with the other two functions, try PARSE()
instead.
Określenie kultury
Innym scenariuszem, w którym możesz preferować użycie funkcji PARSE()
jest określenie kultury/języka, w którym podany jest ciąg znaków. PARSE()
posiada opcjonalny argument, który pozwala określić, jakiej kultury użyć. Jeśli zostanie pominięty, używany jest język bieżącej sesji.
Przykład uwzględnienia 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';
Wynik:
+------------+------------+| Result 1 | Result 2 ||------------+------------|| 2018-07-01 | 2018-01-07 |+------------+------------+
A Culture Alternative
Pomimo korzyści płynących z możliwości określenia kultury za pomocą PARSE()
, masz możliwość zmiany ustawień językowych, co oznacza, że możesz osiągnąć ten sam efekt, używając CAST()
lub CONVERT()
.
Na przykład, użycie SET LANGUAGE us_english
przed zapytaniem zmieni bieżące ustawienia języka na us_english. Chociaż nie pozwala to na określenie różnych kultur w zapytaniu (jak w powyższym przykładzie), ma to wpływ na całe zapytanie (i wszystkie kolejne zapytania).
Możesz również zmienić ustawienia formatu daty w ten sam sposób. Na przykład, SET DATEFORMAT mdy
.
Oto przykład zmiany ustawień języka przed uruchomieniem zapytania z CAST()
i CONVERT()
:
Niemiecki:
SET LANGUAGE German;SELECT CONVERT(date, '07/01/2018') AS 'Convert';SELECT CAST('07/01/2018' AS date) AS 'Cast';
Wynik:
+------------+| 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';
Result:
+------------+| Convert ||------------|| 2018-07-01 |+------------+Changed language setting to us_english.+------------+| Cast ||------------|| 2018-07-01 |+------------+
Pamiętaj, że kiedy to robisz, zmieniasz środowisko języka/formatu daty dla sesji. Nie zapomnij zmienić go z powrotem!
.