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

Formát data SQL:Jak s ním zacházet chytře

Díky rozmanitosti kultur na Zemi máme různé formáty dat. Pro číselná data máme měsíc-den-rok, den-měsíc-rok a rok-měsíc-den. Máme také krátké a dlouhé formáty. Data lze míchat s časem, což je jiný příběh. Tato realita nás provází při práci. To je důvod, proč formát data SQL není něco, co bychom mohli brát snadno.

Na Filipínách používáme 2 formáty:měsíc-den-rok a den-měsíc-rok. Měsíc-den-rok je obecný formát pro číselná data. Ale u delších formátů data zaměnitelně používáme den-měsíc-rok a měsíc-den-rok.

V práci jsem se nikdy nesetkal s jiným nastavením formátu data serveru SQL Server než měsíc-den-rok. Liší se však v sestavách a souborech pro výměnu dat a projekt Extract-Transform-Load (ETL). Natož uživatele, kteří si to ve svých stanicích mění podle osobních preferencí! Se všemi těmito scénáři je neřešit je správně.

Zabývají se vaše aplikace různými kulturami? To je další úroveň složitosti a problém při práci s těmito různými formáty data SQL. V tomto článku prozkoumáme standard pro řešení všech těchto odrůd a příkladů. Čtěte až do konce! Ale než budeme pokračovat, pojďme si udělat krátkou odbočku k tomu, jak SQL Server ukládá data.

Jak SQL Server ukládá data

Hádej. Ukládá SQL Server 29.03.2021 21:35 jako v databázi? Co třeba 29. 3. 2021? Jsou uloženy jako formátované řetězce? Na základě této dokumentace od společnosti Microsoft tomu tak není.

Vezměme si například datový typ DATE. Je uloženo jako 3bajtové celé číslo.

Jak to víme?

Microsoft říká, že tomu tak je, ale neposkytuje více informací. Neznamená to, že to nemůžeme vědět jistě. Za prvé, minimální hodnota datového typu DATE je 01/01/0001 nebo 1. ledna, 1 CE nebo Common Era. Abychom to převedli na celé číslo, převedeme toto datum nejprve na VARBINARY, takto:

SELECT CAST(CAST('01/01/0001' AS DATE) AS VARBINARY(3))

Výsledek je 0x000000 v hexadecimálním formátu. Z této hodnoty můžeme vidět, že celočíselná hodnota 1. ledna 1 CE je 0. Je to logické, protože je to minimální hodnota DATE.

Nyní postoupíme o 1 den.

SELECT CAST(CAST('01/02/0001' AS DATE) AS VARBINARY(3))  -- January 2, 1 CE

Výsledek je 0x010000 . Je to trochu složité, ale tento příspěvek nám dal nápad. Nemůžeme s tím zacházet tak, jak to vidíme. Bajty jsou obrácené a skutečná hexadecimální hodnota je 0x000001 . Pokud víte trochu o hexadecimálních číslech, víte, že se to rovná 1 – je to 1 den od počátečního bodu, 1. ledna, 1 CE.

Nyní zkusme nedávné datum:29. 3. 2021.

SELECT CAST(CAST('03/29/2021' AS DATE) AS VARBINARY(3))

Výsledek je 0x55420B . Když to obrátíme, stane se z toho 0x0B4255 . Tentokrát nemůžeme znát hodnotu, když se na to podíváme. Takže to vynásobíme 1 jako celé číslo.

SELECT 0x0B4255 * CAST(1 AS INT)

Výsledek je 737 877 . Toto je počet dní od 1. ledna 1 CE. Pojďme to ověřit pomocí DATEDIFF.

SELECT DATEDIFF(DAY,CAST('01/01/0001' AS DATE),CAST('03/29/2021' AS DATE))

Výsledek je stejný:737 877 dní. Velmi cool!

Sečteno a podtrženo:Formátované datum je pouze pro účely prezentace

Takto SQL Server ukládá datové typy DATE. Liší se pro DATETIME, SMALLDATETIME a DATETIME2, ale stále se ukládá jako celá čísla. SQL Server vypočítá dobu trvání od počátečního bodu a zobrazí datum, kterému všichni rozumíme.

Ať už se na to díváte v SQL Server Management Studio, dbForge Studio pro SQL Server nebo ve vaší aplikaci, 29. 3. 2021 je pouze prezentace. Pokud změníte region nebo jazyk, bude uložená hodnota 0x55420B zůstane stejný.

Nyní víme, že data se neukládají jako řetězce. Na ukládání dat ve specifickém formátu můžeme zapomenout . Stejně to tak nefunguje. Místo toho se podívejme na různé způsoby v SQL, jak formátovat data, která vaše aplikace potřebují.

4 snadné způsoby formátování dat

Podívejme se na následující funkce data SQL:

  • Funkce CONVERT
  • NASTAVIT JAZYK
  • NASTAVTE FORMÁT DATA
  • Funkce FORMÁTOVÁNÍ

Můžete také použít formátovač dotazů SQL.

1. Funkce CONVERT

CONVERT je jedna z funkcí převodu dat, která může sloužit i pro formátování data. Obrázek 1 zobrazuje příklad.

První dva argumenty CONVERT jsou cílový datový typ a hodnota data. Třetí možnost je volitelná, ale vztahuje se také na data. Číselné hodnoty představují styly formátu data SQL, které se mají použít při převodu z data na řetězec.

Na obrázku 1 Japonsko používá formát rok-měsíc-den s lomítkem jako oddělovačem. Německo používá jako oddělovače den-měsíc-rok s tečkami. Británie a Francie používají stejnou sekvenci jako Německo, ale s lomítkem jako oddělovačem. Pouze Spojené státy používají jako oddělovač měsíc-den-rok s pomlčkou.

V SQL můžete také převést výraz DATETIME na DATE.

Úplný seznam stylů formátu data CONVERT v SQL naleznete v tomto odkazu od společnosti Microsoft.

2. NASTAVIT JAZYK

Toto nastavení určuje jazyk použitý pro relaci. Ovlivňuje formáty data a systémové zprávy. Když nastavíte jazyk, implicitně použijete také nastavení NASTAVIT FORMÁT DATA (vyřešíme to později).

Prozatím se podívejme na příklady na obrázku 2. Měním nastavení jazyka na litevštinu a poté zpět na angličtinu.

Podívejte se na obrázek 2. Litevský formát data je rok-měsíc-den. Kdykoli zkouším různá data, dlouhé datum vždy obsahuje ‚m.‘ před měsícem a ‚d.‘ po dni. Velké písmeno se také nepíše první písmeno měsíce a název dne v týdnu. U jiných jazykových nastavení je to jiné, ale rozumíte tomu.

Další informace o NASTAVENÍ JAZYKA naleznete v této referenci od společnosti Microsoft.

3. NASTAVIT FORMÁT DATA

Toto nastavení umístí pořadí měsíce, dne a roku pro interpretaci řetězců znaků data. Přepíše implicitní nastavení formátu data provedené funkcí SET LANGUAGE. Zde je příklad na obrázku 3.

Na obrázku 3 kód používá formát DMY nebo den-měsíc-rok. V rámci těchto nastavení by každá hodnota data nastavená na proměnnou data měla následovat tento vzor. 30/03/2021 odpovídá tomuto formátu, ale 31/03/2021 spustí chybu, protože 31 není platný měsíc.

Změny formátu data tedy mohou narušit vaši aplikaci, pokud logika funguje na základě jiného formátu.

Další informace o SET DATEFORMAT naleznete v tomto odkazu od společnosti Microsoft.

4. Funkce FORMAT

Ze všech dostupných možností formátování je tato nejflexibilnější. Je to podobné pro formátování data v .Net, protože FORMAT spoléhá na přítomnost .Net Frameworku na serveru, kde je nainstalován SQL Server. To je však nevýhoda této možnosti.

Stejně jako to děláte v C#, FORMAT přebírá hodnotu data a formátovací řetězec. Uveďme si několik příkladů na obrázku 4.

Stejně jako v .Net můžete na serveru SQL Server formátovat data pomocí různých oddělovačů. Také můžete umístit měsíc, den a rok kamkoli. Poté můžete získat kulturní informace a použít jejich formát data.

Další informace a příklady o formátu FORMAT naleznete v této referenci od společnosti Microsoft.

Nyní jsme identifikovali 4 způsoby formátování dat a různé formáty data. Existuje standardní formát, který vždy funguje při převodu řetězců na data?

ISO 8601 – Nejpřenosnější a bezchybný formát data SQL, který můžete použít pro převod

ISO 8601 existuje od roku 1988. Je to mezinárodní standard pro výměnu dat týkajících se dat a časů .

Je také k dispozici ve funkci CONVERT jako jeden ze stylů formátu data:styly 126 a 127 jsou v souladu s ISO 8601.

Proč je přenosný a bez chyb?

Problém s formáty, které nejsou ISO 8601

Ukažme si problém pro non-ISO 8601 na příkladu:

DECLARE @d VARCHAR(10) = '03/09/2021';

SET LANGUAGE Italian;
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET LANGUAGE English
SELECT FORMAT(CONVERT(DATETIME, @d),'D')

SET DATEFORMAT DMY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')
SET DATEFORMAT MDY
SELECT FORMAT(CONVERT(DATETIME, @d),'D')

V závislosti na národním nastavení data můžete @d interpretovat jako 9. březen 2021 nebo 3. září 2021. Nemůžete si být jisti, které je které. V tom spočívá problém.

Zkontrolujte výsledek na obrázku 5 níže:

Dokonce ani SQL Server to neví jistě!

Nejhorší je, že tento druh scénáře může rozbít vaši aplikaci stejně jako to, co se stalo na obrázku 3 dříve. Tato situace je problematická pro aplikace zabývající se multikulturními uživateli.

Může s tím pomoci ISO 8601?

Používání ISO 8601 k řešení problémů s formátováním

Všimněte si, že formát ISO 8601 yyyyMMdd se používá místo MM/dd/rrrr a zkontrolujte výsledek na obrázku 6:

Vždy to bude 9. března, bez ohledu na použitý jazyk a nastavení formátu data. To je skvělé pro výměnu dat a systémové integrace. Pokud má váš uživatel ve stanici jiný formát data, nebude to také důležité.

Pokud potřebujete transformovat data na řetězce a zpět, použijte ISO 8601.

ISO 8601 v SQL Server přichází ve 2 variantách:

  • RRRRMMDD je pouze pro data.
  • RRRR-MM-DDTHH:MM:SS pro kombinaci data a času, kde T je oddělovač mezi datem a časem.

Další způsoby zpracování datových formátů z aplikací na SQL Server

1. Použijte v aplikaci ovládací prvky Date-Aware

Když požádáte uživatele, aby zadal data do formuláře, nedovolte mu použít libovolný text. Používejte ovládací prvky data, které umožňují výběr pouze z platných hodnot.

2. Převést do jiného formátu pouze v případě potřeby

Nepřeměňujte data na řetězce a naopak. Použijte nativní datové typy Date nebo DateTime volající aplikace. Pokud je z jakéhokoli důvodu potřebujete transformovat, použijte ISO 8601.

3. Nastavte datum/čas, časové pásmo a kulturu ve spuštění aplikace, pokud je to možné

Pokud vaše aplikace používá pevný formát data a vaši uživatelé rádi upravují formáty data, můžete oba opravit při spuštění aplikace. Explicitně nastavte, co vaše aplikace potřebuje. Bude mnohem lepší, když váš správce sítě může tato nastavení uzamknout.

Takové věci

Je tedy manipulace s různými formáty data SQL ohromující? Nemohu vás vinit, pokud vám to stále tak připadá, ale zjistili jsme, že to není nemožné.

Zde je to, co jsme probrali:

  • Data SQL jsou uložena jako celá čísla . To, co vidíme očima, je již naformátováno na základě nastavení SQL Serveru. Bez ohledu na to, kolikrát změníme jazyk a formát data, uložená hodnota zůstane stejná. Je zbytečné přemýšlet o ukládání dat v konkrétním formátu.
  • Existují 4 způsoby formátování dat:CONVERT , NASTAVIT JAZYK , NASTAVTE FORMÁT DATA a FORMÁT .
  • Pokud potřebujete transformovat data na řetězce a naopak, použijte formát ISO 8601 .
  • Existují 3 další způsoby, jak se vypořádat s formáty data:
    • používání ovládacích prvků s ohledem na datum ve vaší aplikaci;
    • transformace dat na řetězce pouze v případě potřeby;
    • nastavení požadovaného časového pásma, kultury, data/času serveru při spuštění, je-li to možné .

Myslíte si, že to bude užitečné pro vás i pro ostatní? Poté prosím sdílejte tento článek na svých oblíbených platformách sociálních médií.


  1. Řešení chyby Drop Column v Oracle 18c a 19c

  2. Vložení DEFAULT hodnoty do sloupce, když je parametr NULL

  3. SQL Server CTE a příklad rekurze

  4. Jak timeofday() funguje v PostgreSQL