Być może spotkałeś się z T-SQL PARSE()
, CAST()
i CONVERT()
funkcje podczas pracy z SQL Server i zastanawiał się, na czym polega różnica. Wszystkie trzy funkcje wydają się robić to samo, ale istnieją między nimi subtelne różnice.
W tym artykule zamierzam przedstawić główne różnice między tymi funkcjami.
Porównanie
Oto tabela przedstawiająca główne różnice między CONVERT()
, CAST()
i PARSE()
funkcje w SQL Server:
KONWERSJA() | PRZESYŁANIE() | PARSE() | |
---|---|---|---|
Oficjalna definicja | 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. |
Zaakceptowana wartość | Dowolne prawidłowe wyrażenie. | Dowolne prawidłowe wyrażenie. | Ciąg. |
Wartość zwrotu | Drugi argument, przetłumaczony na żądany typ danych zgodnie z pierwszym argumentem. | Pierwszy argument, przetłumaczony na żądany typ danych zgodnie z drugim argumentem. | Pierwszy argument, przetłumaczony na żądany typ danych zgodnie z drugim argumentem. |
Obsługiwane konwersje | Pomiędzy dowolnymi dwoma typami danych. | Pomiędzy dowolnymi dwoma typami danych. | Tylko od ciągu znaków do daty/czasu i liczb. |
Akceptuje styl Argument? | Tak. | Nie. | Nie. |
Akceptuje kulturę Argument? | Nie. | Nie. | Tak. |
Wymaga .NET Framework? | Nie. | Nie. | Tak. |
Kilka innych punktów oprócz powyższej tabeli:
- Dokumentacja Microsoft wskazuje, że
PARSE()
nie będzie zdalny (ponieważ zależy to od obecności CLR). Zdalna funkcja, która wymaga CLR, spowodowałaby błąd na zdalnym serwerze. - Istnieją pewne wartości, które
PARSE()
może sobie poradzić, aleCAST()
iCONVERT()
nie może (na przykład ciągi używające określonych formatów daty). CAST()
jest zawarty w standardzie ANSI SQL-92.- Niektórzy twierdzą, że
CAST()
ma lepszą wydajność niż pozostałe dwa. - Podczas analizowania wartości ciągów występuje pewien narzut wydajności. Dlatego
PARSE()
zwykle będzie działać wolniej niż pozostałe dwa.
Poniżej znajdują się przykłady sytuacji, w których każda funkcja byłaby najbardziej odpowiednia.
Kiedy używać CAST()
Dobrym argumentem może być użycie CAST()
dla dowolnego 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 wymagane).
Niektórzy twierdzą również, że CAST()
ma lepszą wydajność niż pozostałe dwie (tutaj jest interesujący artykuł porównujący wydajność wszystkich trzech funkcji).
Istnieją jednak również uzasadnione powody, dla których możesz preferować (lub potrzebować) korzystanie z CONVERT()
ponad CAST()
.
Kiedy używać CONVERT()
CONVERT()
funkcja może się przydać, gdy musisz użyć style
argument określający sposób formatowania daty podczas konwersji między datą a ciągiem. 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';
Wynik:
+---------------------+------------+------------+------------+ | 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ługujestyle
argument; iPARSE()
nie konwertuje daty/godziny na wartość ciągu (nie obsługuje równieżstyle
argument)
Kiedy używać funkcji PARSE()
Pomimo różnych wad tej funkcji (wydajność, zależność od platformy .NET, ograniczone konwersje typów danych), ma ona również pewne zalety i jest kilka scenariuszy, w których może to być jedyny wybór. Na przykład w przypadku podania daty zawierającej nazwę dnia tygodnia, np. piątek, 20 lipca 2018 r. .
Gdy inni zwracają błąd
Oto przykłady, w których PARSE()
jest jedyną funkcją z tych trzech, która może z powodzeniem przekonwertować wartość bez zgłaszania błędu.
W tych przykładach próbujemy przekonwertować różne wartości ciągu na datę typ danych. Jednak podane przez nas wartości ciągów zawierają nazwę dnia tygodnia. To powoduje problemy dla CAST()
i CONVERT()
, ale PARSE()
nie ma 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';
Wynik:
+------------+------------+------------+ | Result 1 | Result 2 | Result 3 | |------------+------------+------------| | 2018-07-20 | 2018-07-20 | 2018-07-20 | +------------+------------+------------+
Więc PARSE()
nie ma problemu z formatem podanej przez nas daty.
KONWERSJA()
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';
Wynik:
Conversion failed when converting date and/or time from character string.
Więc CONVERT()
nie jest w stanie przekonwertować ciągu, gdy jest w takim formacie.
RZUT()
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';
Wynik:
Conversion failed when converting date and/or time from character string.
I CAST()
zwraca ten sam błąd.
Więc jeśli zauważysz błędy w pozostałych dwóch funkcjach, spróbuj PARSE()
zamiast tego.
Określanie kultury
Inny scenariusz, w którym możesz preferować użycie PARSE()
funkcja jest podczas określania kultury/języka, w którym dostarczany jest ciąg. PARSE()
ma opcjonalny argument, który pozwala określić, której kultury użyć. W przypadku pominięcia używany jest język bieżącej sesji.
Przykład włączenia 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';
Wynik:
+------------+------------+ | Result 1 | Result 2 | |------------+------------| | 2018-07-01 | 2018-01-07 | +------------+------------+
Kultura alternatywna
Pomimo korzyści płynących z możliwości określenia kultury za pomocą PARSE()
, masz możliwość zmiany ustawień języka, co oznacza, że możesz osiągnąć ten sam efekt przy użyciu CAST()
lub CONVERT()
.
Na przykład używając 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 wszelkie kolejne zapytania).
W ten sam sposób możesz również zmienić ustawienia formatu daty. Na przykład SET DATEFORMAT mdy
.
Oto przykład zmiany ustawienia języka przed uruchomieniem zapytania za pomocą 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';
Wynik:
+------------+ | 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 sesji. Nie zapomnij zmienić tego z powrotem!