sql >> Databáze >  >> RDS >> Database

4 Předdefinované metody konverze dat SQL a případy použití

Za prvé, bez nich se neobejdete, že?

Konverze dat SQL nebo konkrétněji konverze datových typů jsou nezbytnou součástí běžné programátorské práce vývojáře databází nebo DBA.

Co když váš šéf podepsal smlouvu s jinou společností, že jim poskytne soubor v textovém formátu z vaší databáze SQL Server?

To zní jako vzrušující výzva!

Zjistili jste ale, že budete muset řešit datum na řetězec, číslo na řetězec a spoustu dalších převodů dat SQL. Jste stále připraveni na tuto výzvu?

Ne bez vašeho arzenálu triků pro konverzi dat!

Co je k dispozici ihned po vybalení?

Když jsem poprvé začal s programováním T-SQL, první věc, kterou jsem viděl, že odpovídá účelu konverze, byla CONVERT () funkce.

Kromě toho je tam slovo „konvertovat“, že?

I když to může být pravda, je to jen jeden ze 4 způsobů, jak tuto práci vykonávat. A používal jsem to téměř pro VŠECHNY své konverze dat SQL. Jsem rád, že to mám daleko za sebou. Protože jsem se dozvěděl, že tyto 4 metody mají ve vašem kódu své vlastní místo.

Než se dostaneme k předmětu příspěvku, dovolte mi představit 4 předem připravené metody pro převod dat SQL:

  • ODSÍLÁNÍ ()
  • KONVERT ()
  • PARSE ()
  • TRY_CAST (), TRY_CONVERT (), TRY_PARSE ()

Každá z níže uvedených sekcí:

  • Vysvětlete, co to je
  • Řekněte vám, kdy jej použít (případy použití)
  • Uveďte jeho omezení
  • Uveďte příklady a vysvětlete to

Vše, co je uvedeno v tomto článku, je co nejvíce v jednoduché a jednoduché angličtině. Až dočtete celý příspěvek, budete vědět, která metoda je pro danou situaci vhodná.

Takže, bez dalších řečí, pojďme se ponořit.

1. Konverze dat SQL pomocí CAST()

Přestože všechny metody, které uvidíte, mohou převádět datové typy, vaše první volba při převodu by rozhodně měla být CAST ().

Zde jsou důvody proč:

  • Je to nejrychleji běžící konverzní funkce ze všech. Pokusíme se to dokázat později v tomto příspěvku.
  • Je součástí standardů jazykových specifikací SQL-92. Když tedy potřebujete přenést svůj kód do jiných produktů SQL, jako je MySQL, funkce je také k dispozici.

Zde je velmi jednoduchá syntaxe pro CAST ():

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

Nejprve se podívejme na syntaxi:

  • <výraz> je jakýkoli platný výraz, jehož výsledkem je hodnota, kterou lze převést na cílový datový typ.
  • <typ_dat> je cílový datový typ.
  • délka je volitelný a týká se velikosti dat.

Kdy jej použít

Pokud jediná věc, kterou potřebujete, je převést hodnotu na jiný datový typ, pak CAST () je přesně to, co potřebujete.

Omezení

Na druhé straně ODSÍLÁNÍ () vám nemůže poskytnout předem naformátovaný výstup, jako je formátovaná hodnota data a času.

Příklady

A. Převést řetězec na datum:

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

A spuštění výše uvedeného příkazu bude mít za následek:

B. Převeďte číslo na řetězec:

SELECT CAST(10.003458802 as varchar(max))

A výsledek výše uvedené konverze je:

Nyní, pokud potřebujete něco jiného, ​​jako je formátování převedených dat, může vám pomoci další metoda.

2. Konverze dat SQL pomocí CONVERT()

Další možností převodu dat je použití CONVERT (). Jak jsem řekl dříve, toto je ten, který jsem v dřívějších dnech používal nejvíce.

Zde je syntaxe:

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

Z výše uvedené syntaxe si všimněte, že <styl> parametr je volitelný. A pokud jej nezadáte, funkce bude podobná funkci CAST ().

Tady začal můj zmatek, když jsem byl nováčkem v SQL.

Kdy jej použít

Pokud data převedete do okamžitého formátu, pak KONVERT () je tvůj přítel. Což znamená, že zacházíte se <stylem> parametr správně.

Omezení

  • ODSÍLÁNÍ () je rychlejší než CONVERT (), takže pokud potřebujete pouze převést data, použijte CAST (). Pokud má být výstup naformátován, použijte CONVERT ().
  • KONVERT () není standard SQL-92, takže pokud jej potřebujete portovat na jiné RDBMS, nepoužívejte jej.

Příklady

A. Převeďte datum na formát řetězce rrrrmmdd

V následujícím příkladu použiji ukázkovou databázi AdventureWorks a transformovat [Datum zahájení ] na rrrrmmdd :

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

Všimněte si, že styl 112 se používá pro formátování dat na rrrrmmdd .

B. Převeďte číslo na řetězec s čárkami na každé 3 číslici vlevo od desetinné čárky.

Podobně bude následující příklad ilustrovat AdventureWorks ukázkovou databázi a číslo naformátujeme čárkami a na 2 desetinná místa.

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

Všimněte si, že formát 1 se používá pro [skutečné náklady ]. A to díky CONVERT (), můžeme tyto sloupce okamžitě naformátovat.

Co když však potřebujete převést výraz delšího data? KONVERZE () práce v tom případě? Čtěte dále a dozvíte se o další metodě.

3. Konverze dat SQL pomocí PARSE()

Další metodou, kterou budeme uvažovat, je PARSE ().

Podívejte se na syntaxi:

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

Kdy jej použít

  • Převod řetězců na data nebo čísla pomocí specifické kultury.
  • Pokud řetězec nelze převést na datum nebo číslo pomocí CAST () nebo CONVERT (). Další informace naleznete v příkladech.

Omezení

  • Převod je možný pouze pro řetězec na data a řetězec na čísla
  • Spoléhá na přítomnost .Net Framework Common Language Runtime (CLR) na serveru.
  • Není zahrnuto ve standardních specifikacích SQL-92, takže portování na jiné RDBMS je problém.
  • Má režii výkonu, pokud jde o analýzu řetězce.

Příklady

A. Převod dlouhého datového řetězce

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

Výše uvedený příklad je dlouhý řetězec data, který má být převeden na datetime hodnotu využívající kulturu americké angličtiny. A tady je PARSE () udělá to nejlepší.

Je to proto, že výše uvedený kód selže, pokud použijete CAST () nebo CONVERT ().

B. Převod peněžní hodnoty se symbolem měny

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

Nyní zkuste provést převod pomocí CAST () a CONVERT ()

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

Příkaz nevyvolá chyby, přesto se podívejte na tento neočekávaný výsledek:

V důsledku toho byla hodnota převedena na 102401,00 namísto 1024,01.

Zatím jsme zjistili, že první 3 metody jsou náchylné k chybám, pokud je nezkontrolujete. Nicméně 4. metoda může být vaším řešením chybného výsledku.

4. Konverze dat SQL pomocí TRY_CAST(), TRY_CONVERT() nebo TRY_PARSE()

Konečně poslední metodou pro konverzi dat SQL je použití varianty prvních 3, ale s předponou TRY_.

Ale i tak, jaký je v tom rozdíl?

Mají stejné parametry jako předchozí 3 bez předpony TRY_. Rozdíl je ale v tom, že vrátí NULL pokud hodnotu nelze převést. Nyní, pokud nelze hodnotu převést žádnou ze 3 explicitně, dojde k chybě. Pro lepší pochopení se podívejte na příklady níže.

Kdy jej použít

Můžete použít kterýkoli ze 3 s podmíněnými příkazy jako CASE KDY nebo IIF otestovat chyby.

Omezení

Tři z nich mají stejná omezení jako ty bez předpony TRY_, s výjimkou hodnot, které nelze převést.

Příklady

A. Pomocí TRY_CAST() otestujte, zda bude převod úspěšný pomocí IIF:

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

Výše uvedený kód vrátí „Cast Failed“, protože „111b“ nelze převést na skutečné . Odeberte z hodnoty „b“ a vrátí se „Cast failed“.

B. Použití TRY_CONVERT() pro data v konkrétním formátu

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

Tím se vrátí NULL protože formát používá dmy nebo den-měsíc-rok. A vstupní výraz pro TRY_CONVERT () je ve formátu mdy nebo měsíc-den-rok. Chyba byla spuštěna, protože hodnota měsíce je 31.

C. Pomocí TRY_PARSE(), která vygeneruje runtime error

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

Tento kód vygeneruje chybu běhu, jak je vidět níže:

To je vše pro 4 předem připravené metody konverze dat SQL. Ale je toho víc.

Jak je to s konverzí dat SQL pomocí implicitní konverze?


Nyní uvažujme o implicitní konverzi. Toto je tichá metoda.

Proč mlčet?

Protože to možná už děláte, ale nevíte o tom. Nebo alespoň víte, že se to děje, ale ignorujete to.

Jinými slovy, toto je typ konverze, kterou SQL automaticky provádí bez jakýchkoli funkcí.

Dovolte mi uvést příklad:

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]

Výše uvedený kód bude úspěšně proveden. Vyzkoušejte to sami a budete mít podobný výsledek jako níže:

Zkusme to s daty:

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]

Podle očekávání to přinese úspěšný výsledek:

Zkusme to tentokrát s čísly:

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]

Stále úspěch, že?

Dosud jsme používali jednoduché hodnoty, které se budou hodit pro spíše podobný typ dat. Pojďme na další úroveň:čísla k řetězcům.

DECLARE @number int
DECLARE @string varchar(5)

SET @number = 1701
SET @string = @number

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

To bude úspěšně převedeno, jak můžete vidět z výsledku níže:

Existuje mnoho dalších případů, kdy se SQL Server pokusí „uhodnout“, jak převést data. Jak můžete vidět z tohoto odkazu, existuje mnoho případů ve srovnání s těmi, které vyžadují explicitní konverzi.

Protože to SQL Server umožňuje, znamená to, že to můžete volně povolit v celém kódu?

Výstrahy při implicitní konverzi

Jednak to může být pohodlné. Jakmile však dosáhnete limitů každého datového typu, uvědomíte si, že implicitní konverze je trochu nebezpečná, pokud ji ponecháte nezaškrtnutou.

Zvažte příklad níže:

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]

Viděli jste hodnotu emodži? To se bude počítat jako hodnota unicode.

Zatímco všechny výše uvedené příkazy poběží úspěšně, proměnné s typy bez Unicode, jako je varchar a char bude mít neočekávané výsledky. Podívejte se na výsledek níže:

Nicméně to není jediný problém. Když se hodnota dostane mimo rozsah, objeví se chyby. Zvažte příklad s daty:

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]

Přiřazení datetime hodnotu na smalldatetime proměnná spustí chybu, jak můžete vidět níže:

Ale je tu ještě jedno upozornění, kterého byste si měli být vědomi, když se zabýváte implicitní konverzí:výkonová režie. Vzhledem k tomu, že se jedná o aktuální téma, zaslouží si samostatnou sekci.

Dopady na výkon různých metod konverze dat SQL

Věřte tomu nebo ne, různé metody konverze dat SQL budou mít ve skutečných situacích různý výkon. A měli byste si toho být alespoň vědomi, abyste se vyhnuli výkonnostním nástrahám.

Jak fungují CAST(), CONVERT() a PARSE()

Nejprve se podívejme, jak ODSÍLAT (), KONVERT () a PARSE () fungovat za přirozených podmínek porovnáním, co je rychlejší. Přizpůsobujeme a dokazujeme koncept našeho příkladu převzatého odtud. Zvažte kód níže:

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

Nyní se podívejme na kód, který používá AdventureWorks databáze od společnosti Microsoft:

  • NASTAVTE ČAS STATISTIKY ZAPNUTÝ vypíše čas CPU a uplynulý čas v každém z SELECT prohlášení
  • Potom sloupec, který se rozhodneme převést pro demonstrační účely, je [NationalIDNumber ], který má typ nvarchar(15) .
  • Převod je také z řetězce na celé číslo:nvarchar(15) na int .
  • A nakonec obnovíme SET STATISTICS TIME na předchozí hodnotu

Všimněte si výstupu ve Zprávách na kartě Výsledek dotazu:

S tímto příkladem jsme přišli na toto:

  • Dokazuje to, že ODSÍLÁNÍ () provede nejrychlejší (1 ms.) a PARSE () provádí nejpomaleji (318 ms.).
  • Při rozhodování, kterou funkci použít k převodu dat, dodržujeme toto pravidlo:(1 ) ODESLAT () (2 ) KONVERT () (3 ) PARSE ().
  • Nezapomeňte, kdy je každá funkce relevantní, a při rozhodování, kterou funkci použít, zvažte její omezení.

Jak funguje implicitní konverze

V tomto okamžiku byste měli být schopni vidět, že pro převod dat doporučuji použít funkce jako CAST(). A v této sekci uvidíte proč.

Zvažte tento dotaz pomocí WideWorldImporters databáze od společnosti Microsoft. Před jeho spuštěním prosím povolte Zahrnout skutečný plán provedení v SQL Server Management Studio .

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

Ve výše uvedeném dotazu filtrujeme výsledek prodejních objednávek pomocí [CustomerID ] jako „487 %“. To je jen ukázat, jaký účinek má implicitní konverze int datový typ má na varchar .

Dále prozkoumáme plán provádění níže:

Jak vidíte, v VYBRAT je varování ikona. Proto najeďte myší, abyste viděli popisek. Dále si všimněte varovné zprávy, konkrétně CONVERT_IMPLICIT .

Než budeme pokračovat, toto CONVERT_IMPLICIT varování se objeví, když je nutné provést implicitní převod pro SQL Server. Pojďme se na problém podívat blíže. Jak je popsáno níže, varování má 2 části:

  • CONVERT_IMPLICIT může ovlivnit „CardinalityEstimate“ ve výběru plánu dotazů.
  • CONVERT_IMPLICIT může ovlivnit „SeekPlan“ ve výběru plánu dotazů.

Oba naznačují, že váš dotaz bude probíhat pomaleji. Ale víme proč, samozřejmě. Záměrně vynucujeme implicitní konverzi pomocí LIKE operátor pro celočíselnou hodnotu.

Jaký to má smysl?

  • Implicitní převod dat způsobí, že SQL Server použije CONVERT_IMPLICIT , což zpomaluje provádění vašeho dotazu.
  • Chcete-li tento problém vyřešit, eliminujte použití implicitní konverze. V našem případě jsme použili [CustomerID ] LIKE „487 %“, můžeme to opravit změnou [CustomerID ] =487. Oprava dotazu změní plán provádění dotazu, odstraní předchozí varování a změní operátor skenování indexu na vyhledávání indexu. Nakonec se výkon zlepší.

Šťastný konec? Ano!

Takové věci

Jak je ukázáno, nemůžeme jen nechat SQL Server provést konverzi s implicitní konverzí. Doporučuji, abyste se řídili prioritou, pokud jde o rozhodování, co použít při převodu dat.

  • Za prvé, pokud potřebujete převést tak, jak je, použijte CAST (). Jde o standardizovanější funkci, pokud jde o portování na jiné RDBM.
  • Zadruhé, pokud potřebujete formátovaná data, použijte CONVERT ().
  • Zatřetí, pokud obě ODSÍLAJÍ () a CONVERT () nezvládne úlohu, použijte PARSE ().
  • A konečně, k otestování chyb při převodu použijte TRY_CAST (), TRY_CONVERT () nebo TRY_PARSE ().

No, to je zatím vše. Doufám, že vám to pomůže při vašich dalších programovacích dobrodružstvích. Zlom si nohu!

Chcete-li se dozvědět více o tématu konverze dat SQL od společnosti Microsoft:

  • ODSÍLAT a PŘEVÁDĚT
  • PARSE
  • TRY_CAST, TRY_CONVERT a TRY_PARSE

  1. Group_concat ekvivalent funkce MySQL v Oracle

  2. Co je připojovací řetězec ovladače MySQL JDBC?

  3. Rychlejší způsob vkládání pomocí skriptu v Oracle?

  4. Jak zkontrolovat, zda existuje uložená procedura?