Database
 sql >> Baza danych >  >> RDS >> Database

4 gotowe metody konwersji danych SQL i przypadki użycia

Przede wszystkim nie możesz się bez nich obejść, prawda?

Konwersje danych SQL, a dokładniej konwersje typów danych, są istotną częścią regularnej pracy programistycznej programisty baz danych lub DBA.

A co, jeśli twój szef podpisał umowę z inną firmą, aby dostarczyć mu plik w formacie tekstowym pochodzący z bazy danych SQL Server?

To brzmi jak ekscytujące wyzwanie!

Ale dowiedziałeś się, że będziesz musiał mieć do czynienia z datą na łańcuch, liczbą na łańcuch i wieloma innymi konwersjami danych SQL. Czy nadal jesteś gotowy na wyzwanie?

Nie bez twojego arsenału sztuczek konwersji danych!

Co jest dostępne zaraz po wyjęciu z pudełka?

Kiedy po raz pierwszy zacząłem programować w T-SQL, pierwszą rzeczą, która pasowała do celu konwersji, była CONVERT () funkcja.

Poza tym słowo „konwertuj” jest tam, prawda?

Chociaż może to być prawdą, to tylko jeden z 4 sposobów wykonywania tej pracy. I używałem go do prawie WSZYSTKICH moich konwersji danych SQL. Cieszę się, że już to przekroczyłem. Ponieważ nauczyłem się, że te 4 metody mają swoje własne miejsce w Twoim kodzie.

Zanim przejdziemy do tematu postu, przedstawię 4 gotowe metody konwersji danych SQL:

  • PRZESYŁANIE ()
  • KONWERSJA ()
  • PRZEGLĄDAJ ()
  • TRY_CAST (), TRY_CONVERT (), TRY_PARSE ()

Każda z poniższych sekcji:

  • Wyjaśnij, co to jest
  • Powiedz, kiedy go użyć (przypadki użycia)
  • Przedstaw swoje ograniczenia
  • Podaj przykłady i wyjaśnij to

Wszystko, co przedstawiono w tym artykule, jest w miarę możliwości prostym, prostym językiem angielskim. Zanim skończysz czytać cały post, będziesz wiedział, która metoda jest odpowiednia w danej sytuacji.

Więc bez zbędnych ceregieli zanurkujmy.

1. Konwersja danych SQL za pomocą CAST()

Chociaż wszystkie metody, które zobaczysz, mogą konwertować typy danych, Twoim pierwszym wyborem podczas konwersji powinno być zdecydowanie CAST ().

Oto powody, dla których:

  • To najszybciej działająca funkcja konwersji ze wszystkich. Postaramy się to udowodnić w dalszej części tego postu.
  • Jest zawarty w standardach specyfikacji języka SQL-92. Jeśli więc potrzebujesz przenieść swój kod do innych produktów SQL, takich jak MySQL, ta funkcja jest również dostępna.

Oto bardzo prosta składnia CAST ():

CAST( <expression> AS <data_type>[(length)] )

Najpierw przyjrzyjmy się składni:

  • <wyrażenie> jest dowolnym poprawnym wyrażeniem, którego wynikiem jest wartość, którą można przekonwertować na docelowy typ danych.
  • <rodzaj_danych> to docelowy typ danych.
  • długość jest opcjonalne i dotyczy rozmiaru danych.

Kiedy go używać

Jeśli jedyne, czego potrzebujesz, to przekonwertować wartość na inny typ danych, to CAST () jest właśnie tym, czego potrzebujesz.

Ograniczenia

Z drugiej strony CAST () nie może dać sformatowanych danych wyjściowych od razu po wyjęciu z pudełka, takich jak sformatowana wartość daty i godziny.

Przykłady

A. Konwertuj ciąg na datę:

SELECT CAST('09/11/2004 4:30PM' as datetime2)

A uruchomienie powyższej instrukcji spowoduje:

B. Konwertuj liczbę na ciąg:

SELECT CAST(10.003458802 as varchar(max))

A wynik powyższej konwersji to:

Teraz, jeśli potrzebujesz czegoś innego, jak formatowanie przekonwertowanych danych, kolejna metoda może ci pomóc.

2. Konwersja danych SQL przy użyciu funkcji CONVERT()

Następną opcją konwersji danych jest użycie CONVERT (). Jak powiedziałem wcześniej, jest to ten, którego najczęściej używałem we wcześniejszych dniach.

Oto składnia:

CONVERT( <data_type>[(length)], <expression> [, <style>])

Z powyższej składni zwróć uwagę, że <styl> parametr jest opcjonalny. A jeśli go nie podasz, funkcja będzie podobna do CAST ().

To tam zaczęło się moje zamieszanie, gdy byłem nowy w SQL.

Kiedy go używać

Jeśli konwertujesz dane w formacie błyskawicznym, KONWERTUJ () jest twoim przyjacielem. Co oznacza, że ​​traktujesz <styl> parametr poprawnie.

Ograniczenia

  • PRZESYŁANIE () jest szybszy niż CONVERT (), więc jeśli potrzebujesz tylko przekonwertować dane, użyj CAST (). Jeśli dane wyjściowe powinny być sformatowane, użyj KONWERSJ ().
  • KONWERSJA () nie jest standardem SQL-92, więc jeśli chcesz przenieść go do innego RDBMS, unikaj go.

Przykłady

A. Konwertuj datę na format ciągu rrrrmmdd

W poniższym przykładzie użyję przykładowej bazy danych AdventureWorks i przekształć [Data rozpoczęcia ] kolumna do rrrrmmdd :

USE AdventureWorks
GO
SELECT
[BillOfMaterialsID]
,CONVERT(varchar(10), [StartDate],112) as StartDate
FROM [Production].BillOfMaterials]
GO

Pamiętaj, że styl 112 jest używany do formatowania dat na rrrrmmdd .

B. Konwertuj liczbę na ciąg znaków z przecinkami co 3 cyfry po lewej stronie przecinka dziesiętnego.

Podobnie poniższy przykład ilustruje AdventureWorks przykładowa baza danych, a my sformatujemy liczbę z przecinkami i 2 miejscami po przecinku.

USE AdventureWorks
GO
SELECT
[TransactionID]
,[ProductID]
,CONVERT(varchar(10),[TransactionDate] ,112) as StartDate
,[Quantity]
,CONVERT(varchar(10),[ActualCost],1) as ActualCost
FROM [Production].TransactionHistory
GO

Pamiętaj, że format 1 jest używany dla [Koszt rzeczywisty ]. I dzięki CONVERT (), możemy natychmiast sformatować te kolumny.

Co jednak zrobić, jeśli musisz przekonwertować wyrażenie z dłuższą datą? Czy KONWERTOWAĆ () działać w takim przypadku? Czytaj dalej, aby dowiedzieć się o następnej metodzie.

3. Konwersja danych SQL za pomocą PARSE()

Następną metodą, którą rozważymy, jest PARSE ().

Sprawdź składnię:

PARSE( <string value> AS <datatype> [USING <culture>])

Kiedy go używać

  • Aby przekonwertować ciągi znaków na daty lub liczby przy użyciu określonej kultury.
  • Kiedy ciągu nie można przekonwertować na datę lub liczbę za pomocą CAST () lub KONWERTUJ (). Zobacz przykłady, aby uzyskać więcej informacji.

Ograniczenia

  • Konwersja jest możliwa tylko dla ciągu znaków na daty i ciągu na liczby
  • Opiera się na obecności .Net Framework Common Language Runtime (CLR) na serwerze.
  • Nie jest zawarty w standardowych specyfikacjach SQL-92, więc przeniesienie na inne RDBMS jest problemem.
  • Ma narzut wydajności, jeśli chodzi o analizowanie ciągu.

Przykłady

A. Konwersja długiego ciągu daty

SELECT PARSE('Monday, June 8, 2020' as datetime USING 'en-US')

Powyższy przykład to długi ciąg daty do przekonwertowania na data-godzina wartość przy użyciu amerykańskiej kultury angielskiej. I tu właśnie PRZEGLĄDAJ () zrobi wszystko, co w jego mocy.

Dzieje się tak, ponieważ powyższy kod nie powiedzie się, jeśli użyjesz CAST () lub KONWERTUJ ().

B. Zamiana wartości pieniężnej na symbol waluty

SELECT PARSE('€1024,01' as money using 'de-DE')

Teraz spróbuj wykonać konwersję za pomocą CAST () i KONWERSJA ()

SELECT CONVERT(money,'€1024,01')
SELECT CAST('€1024,01' as money)

Oświadczenie nie spowoduje błędów, ale spójrz na ten nieoczekiwany wynik:

W rezultacie wartość została przekonwertowana na 102401.00 zamiast 1024.01.

Jak dotąd odkryliśmy, że pierwsze 3 metody są podatne na błędy, chyba że je sprawdzisz. Niemniej jednak czwarta metoda może być Twoim rozwiązaniem błędnego wyniku.

4. Konwersja danych SQL przy użyciu TRY_CAST(), TRY_CONVERT() lub TRY_PARSE()

Wreszcie ostatnią metodą konwersji danych SQL jest użycie wariantu pierwszych 3, ale z przedrostkiem TRY_.

Ale mimo to, jaka jest różnica?

Mają takie same parametry jak poprzednie 3 bez przedrostka TRY_. Różnica polega na tym, że zwracają NULL jeśli wartość nie może zostać przekonwertowana. Teraz, jeśli wartość nie może być jawnie przekonwertowana przez żaden z 3, wystąpi błąd. Zobacz przykłady poniżej, aby lepiej zrozumieć.

Kiedy go używać

Możesz użyć dowolnego z 3 z wyrażeniami warunkowymi, takimi jak CASE KIEDY lub IIF do testowania błędów.

Ograniczenia

Trzy z nich mają takie same ograniczenia jak te bez przedrostka TRY_, z wyjątkiem wartości, których nie można przekonwertować.

Przykłady

A. Użyj TRY_CAST(), aby sprawdzić, czy konwersja powiodła się przy użyciu IIF:

SELECT IIF(TRY_CAST('111b' AS real) IS NULL, 'Cast failed', 'Cast succeeded') AS Result

Powyższy kod zwróci „Przesyłanie nie powiodło się”, ponieważ „111b” nie może zostać przekonwertowane na prawdziwe . Usuń „b” z wartości, a zwróci „Rzutowanie powiodło się”.

B. Używanie TRY_CONVERT() w datach o określonym formacie

SET DATEFORMAT dmy;
SELECT TRY_CONVERT(datetime2, '12/31/2010') AS Result

To zwróci NULL ponieważ format używa dmy lub dzień-miesiąc-rok. A wyrażenie wejściowe dla TRY_CONVERT () ma format mdy lub miesiąc-dzień-rok. Błąd został wywołany, ponieważ wartość miesiąca to 31.

C. Używanie TRY_PARSE(), które wygeneruje błąd w czasie wykonywania

SELECT
CASE WHEN TRY_PARSE('10/21/2133' AS smalldatetime USING 'en-US') IS NULL
    THEN 'True'
    ELSE 'False'
END AS Result

Ten kod wygeneruje błąd w czasie wykonywania, jak pokazano poniżej:

To tyle, jeśli chodzi o 4 gotowe metody w konwersji danych SQL. Ale jest jeszcze więcej.

A co z konwersją danych SQL przy użyciu konwersji niejawnej?


Rozważmy teraz konwersję niejawną. To jest cicha metoda.

Dlaczego cicho?

Ponieważ może już to robisz, ale nie jesteś tego świadomy. A przynajmniej wiesz, że to się dzieje, ale ignorujesz to.

Innymi słowy, jest to typ konwersji, który SQL wykonuje automatycznie bez żadnych funkcji.

Podam przykład:

DECLARE @char CHAR(25)
DECLARE @varchar VARCHAR(25)
DECLARE @nvarchar NVARCHAR(25)
DECLARE @nchar NCHAR(25)
 
SET @char = 'Live long and prosper'
SET @varchar = @char
SET @nvarchar = @varchar
SET @nchar = @nvarchar
 
SELECT @char AS [char], @varchar AS [varchar], @nvarchar AS [nvarchar], @nchar AS [nchar]

Powyższy kod zostanie wykonany pomyślnie. Wypróbuj sam, a uzyskasz podobny wynik do poniższego:

Spróbujmy tego z datami:

DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2

SET @datetime = '12/31/2050 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime

SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]

Zgodnie z oczekiwaniami przyniesie to pomyślny wynik:

Spróbujmy tym razem z liczbami:

DECLARE @int int
DECLARE @real real
DECLARE @decimal decimal
DECLARE @float float

SET @int = 1701
SET @real = @int
SET @decimal = @real
SET @float = @decimal

SELECT @int as [int], @real as [real], @decimal as [decimal], @float as [float]

Nadal sukces, prawda?

Do tej pory używaliśmy prostych wartości, które będą odpowiednie dla dość podobnego typu danych. Przejdźmy do następnego poziomu:liczby do łańcuchów.

DECLARE @number int
DECLARE @string varchar(5)

SET @number = 1701
SET @string = @number

SELECT @number as [number], @string as [string]

Zostanie to pomyślnie przekonwertowane, jak widać z poniższego wyniku:

Istnieje wiele innych przypadków, w których SQL Server będzie próbował „odgadnąć”, jak przekonwertować dane. Jak widać z tego odniesienia, istnieje wiele przypadków w porównaniu z tymi, które wymagają jawnej konwersji.

Skoro SQL Server na to pozwala, czy oznacza to, że możesz swobodnie pozwalać na to w całym kodzie?

Ostrzeżenia w konwersji niejawnej

Po pierwsze, może to być wygodne. Ale kiedy limity każdego typu danych zostaną osiągnięte, zdasz sobie sprawę, że niejawna konwersja jest nieco niebezpieczna, jeśli nie zostanie zaznaczona.

Rozważ poniższy przykład:

DECLARE @char char(25)
DECLARE @varchar varchar(25)
DECLARE @nvarchar nvarchar(25)
DECLARE @nchar nchar(25)

SET @nvarchar = N'I ❤ U!'
SET @nchar = @nvarchar 
SET @char = @nchar
SET @varchar = @nchar

SELECT @char as [char], @varchar as [varchar], @nvarchar as [nvarchar], @nchar as [nchar]

Widziałeś wartość emoji? Będzie to liczone jako wartość Unicode.

Chociaż wszystkie powyższe instrukcje będą działać pomyślnie, zmienne z typami innymi niż Unicode, takimi jak varchar i znak przyniesie nieoczekiwane rezultaty. Zobacz wynik poniżej:

To jednak nie jedyny problem. Błędy pojawią się, gdy wartość znajdzie się poza zakresem. Rozważ przykład z datami:

DECLARE @datetime datetime
DECLARE @smalldatetime smalldatetime
DECLARE @datetime2 datetime2

SET @datetime = '12/31/2374 14:34'
SET @smalldatetime = @datetime
SET @datetime2 = @smalldatetime

SELECT @datetime as [datetime], @smalldatetime as [smalldatetime], @datetime2 as [datetime2]

Przypisanie daty i godziny wartość smalldatetime zmienna wywoła błąd, jak widać poniżej:

Ale jest jeszcze jedno zastrzeżenie, o którym należy również pamiętać, gdy mamy do czynienia z niejawną konwersją:narzut wydajności. Ponieważ jest to gorący temat, zasługuje na osobną sekcję.

Implikacje wydajności różnych metod konwersji danych SQL

Wierzcie lub nie, ale różne metody konwersji danych SQL będą miały różną wydajność w rzeczywistych sytuacjach. Powinieneś przynajmniej być tego świadomy, aby uniknąć pułapek wydajnościowych.

Jak działają CAST(), CONVERT() i PARSE()

Najpierw przyjrzyjmy się, jak CAST (), KONWERSJA () i PRZEGLĄDAJ () działają w warunkach naturalnych, porównując, które jest szybsze. Dopasowujemy i udowadniamy koncepcję naszego przykładu zaczerpniętą stąd. Rozważ poniższy kod:

USE AdventureWorks
GO

SET STATISTICS TIME ON
SELECT CAST([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SELECT CONVERT(int,[NationalIDNumber]) FROM [HumanResources].[Employee]
SELECT PARSE([NationalIDNumber] as int) FROM [HumanResources].[Employee]
SET STATISTICS TIME OFF
GO

Przyjrzyjmy się teraz kodowi, który wykorzystuje AdventureWorks baza danych firmy Microsoft:

  • WŁĄCZ CZAS STATYSTYK wyświetli czas procesora i czas, który upłynął w każdym z SELECT oświadczenia
  • W takim razie kolumna, którą wybieramy do przekonwertowania w celach demonstracyjnych, to [NationalIDNumber ], który ma typ nvarchar(15) .
  • Ponadto konwersja odbywa się z ciągu znaków na liczbę całkowitą:nvarchar(15) do int .
  • I na koniec przywracamy USTAW CZAS STATYSTYK do poprzedniej wartości

Zwróć uwagę na wynik w Wiadomościach zakładka wyniku zapytania:

Oto, co wymyśliliśmy na tym przykładzie:

  • Dowodzi, że CAST () wykonuje najszybciej (1 ms.) i PARSE () działa najwolniej (318 ms).
  • Przy podejmowaniu decyzji, której funkcji użyć do konwersji danych, kierujemy się tym pierwszeństwem:(1 ) PRZESYŁANIE () (2 ) KONWERSJA () (3 ) PRZEGLĄDAJ ().
  • Pamiętaj, kiedy każda funkcja jest istotna i weź pod uwagę ograniczenia przy podejmowaniu decyzji, której funkcji użyć.

Jak działa konwersja niejawna

W tym momencie powinieneś być w stanie zobaczyć, że zalecam używanie funkcji takich jak CAST() do konwersji danych. W tej sekcji zobaczysz, dlaczego.

Rozważ to zapytanie za pomocą WideWorldImporters baza danych firmy Microsoft. Przed wykonaniem włącz Uwzględnij rzeczywisty plan wykonania w SQL Server Management Studio .

USE WideWorldImporters
GO
SELECT
[CustomerID]
,[OrderID]
,[OrderDate]
,[ExpectedDeliveryDate]
FROM [Sales].[Orders]
WHERE [CustomerID] like '487%'

W powyższym zapytaniu filtrujemy wyniki zamówień sprzedaży za pomocą [CustomerID ] jak „487%”. To tylko po to, by zademonstrować, jaki wpływ ma niejawna konwersja int typ danych ma na varchar .

Następnie przyjrzymy się poniższemu planowi wykonania:

Jak widać, w SELECT znajduje się ostrzeżenie Ikona. Dlatego najedź myszą, aby zobaczyć podpowiedź. Następnie zwróć uwagę na komunikat ostrzegawczy, a mianowicie CONVERT_IMPLICIT .

Zanim przejdziemy dalej, ten CONVERT_IMPLICIT ostrzeżenie występuje, gdy konieczne jest wykonanie niejawnej konwersji dla programu SQL Server. Przyjrzyjmy się bliżej problemowi. Jak opisano poniżej, ostrzeżenie składa się z 2 części:

  • CONVERT_IMPLICIT może wpływać na „CardinalityEstimate” w wyborze planu zapytania.
  • CONVERT_IMPLICIT może wpływać na „SeekPlan” w wyborze planu zapytań.

Oba z nich wskazują, że Twoje zapytanie będzie działać wolniej. Ale oczywiście wiemy dlaczego. Celowo wymuszamy niejawną konwersję za pomocą LIKE operator dla wartości całkowitej.

Jaki jest w tym sens?

  • Niejawna konwersja danych powoduje, że SQL Server używa CONVERT_IMPLICIT , co spowalnia wykonanie zapytania.
  • Aby rozwiązać ten problem, należy wyeliminować niejawną konwersję. W naszym przypadku użyliśmy [ID klienta ] LUBIĘ „487%”, możemy to naprawić, zmieniając [ID klienta ] =487. Naprawienie zapytania spowoduje zmianę planu wykonania zapytania, usunięcie wcześniejszego ostrzeżenia i zmianę operatora skanowania indeksu na wyszukiwanie indeksu. Ostatecznie poprawia się wydajność.

Szczęśliwe zakończenie? Tak!

Na wynos

Jak pokazano, nie możemy po prostu pozwolić, aby SQL Server wykonał konwersję z niejawną konwersją. Zalecam przestrzeganie pierwszeństwa, jeśli chodzi o decydowanie, czego użyć podczas konwersji danych.

  • Po pierwsze, jeśli potrzebujesz tylko przekonwertować, użyj CAST (). Jest to bardziej ustandaryzowana funkcja, jeśli chodzi o przenoszenie do innych RDBM.
  • Po drugie, jeśli potrzebujesz sformatowanych danych, użyj CONVERT ().
  • Po trzecie, jeśli oba CAST () i KONWERSJA () nie wykona zadania, użyj PARSE ().
  • Na koniec, aby sprawdzić błędy podczas konwersji, użyj TRY_CAST (), TRY_CONVERT () lub TRY_PARSE ().

Coż, to na razie wszystko. Mam nadzieję, że pomoże to w następnych przygodach z kodowaniem. Złam nogę!

Aby dowiedzieć się więcej na temat konwersji danych SQL firmy Microsoft:

  • PRZESYŁANIE i KONWERTOWANIE
  • PRZEGLĄDAJ
  • TRY_CAST, TRY_CONVERT i TRY_PARSE

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zmiany w partycji z możliwością zapisu mogą nieoczekiwanie zakończyć się niepowodzeniem

  2. Podstawy wyrażeń tabelarycznych, część 13 – Wbudowane funkcje o wartościach tabelarycznych, ciąg dalszy

  3. Trendy ScyllaDB – jak użytkownicy wdrażają bazę danych Big Data w czasie rzeczywistym

  4. Pytania do wywiadu z inżynierem danych w Pythonie

  5. Chmura Alibaba