.NET Tip #31: Pozor na datum v SQL Serveru

Tomáš Jecha       3. 7. 2009       SQL, Databáze, .NET Tips       7968 zobrazení

Dnes tu budu psát o 2 chuťovkách, které mohou vývojáře překvapit při psaní Transact-SQL scriptů pro Microsoft SQL Server. Obě by se daly označit oblíbeným tagem “na mém počítači to funguje, tak proč ne na serveru u zákazníka?!”.

První problém je s parsováním data. Pokud píšete SQL scripty, často narazíte na nutnost zadat datum textově. Možná už tušíte, že na každém serveru může být formát jiný. Ty se liší pořadím jednotlivých složek (m = měsíc, y = rok, d = den). V SQL Serveru existují následující: mdy, dmy, ymd, ydm, myd, dym. Formát lze ale snadno nastavit příkazem SET DATEFORMAT formát. Takže pokud chcete používat datum ve formátu ‘2009-05-17’ bylo by dobré před zadáváním zavolat:

-- formát datumů ROK, MĚSÍC, DEN
set dateformat ymd

Jak to tak bývá, tak většinou je zadávání data bez problémů, ale lepší je formát vždy upřesňovat. Více informací na MSDN: http://msdn.microsoft.com/en-us/library/ms189491.aspx

Druhý zádrhel může nastat při zjišťování čísla dne v týdnu funkcí DATEPART(dw, ‘datum’). Ta vrací rozsah mezi 1-7. Pokud nekouknete do dokumentace a pouze si zkusíte, jaké čísla to vrací pro jaký den, můžete si myslet, že čísla jsou pro jednotlivé dny pevně dány. Bohužel ale první den může být kterýkoliv v závislosti na nastavení. Proto je i zde lepší před zjišťováním dne v týdnu použít funkci SET DATEFIRST číslo_dne. Jako parametr předáte číslo dne, který má být označován jako první (1 pro pondělí, 7 pro neděli).

Více informací opět na MSDN: http://msdn.microsoft.com/en-us/library/ms181598.aspx

 

hodnocení článku

0       Hodnotit mohou jen registrované uživatelé.

 

Nový příspěvek

 

Diskuse: .NET Tip #31: Pozor na datum v SQL Serveru

Jo jo, toto je skvělý tip! Narazil jsem na něj, když jsem gugloval můj problém. Díky, Tomáši.

Přesto mám obavy, že mi to nepomůže...?

Konvertuju aplikaci (import dat z TXT souboru do databáze na SQL server 2005). Dřív to bylo ve VB6, přepisuju do VB .NET 2.0

VB script posílá na SQL server následující insert:INSERT INTO DP_Deliveries ( plant, delnote, date_rec ) VALUES ('Vitre', '0180011257', 16/07/2010 )

Když spustím script verze VB6 (tedy klasické ASPčko), proběhne to OK a datum date-rec se správně uloží jako 16.7.2010, zatímco když totéž spustím pod VB .NET 2.0, uloží se pokaždé datum 1.1.1900. Je mi divné, že konverze hodnoty 16/07/2010 proběhne na SQL serveru na hodnotu 1.1.1900 bez jakékoli chybové hlášky.

Není mi tedy jasné, proč je datum ukládané příkazem INSERT z VB6 scriptu konvertováno a uloženo SQL serverem správně (16/07/2010 konvertuje na 16.7.2010), zatímco tentýž příkaz INSERT z VB.NET 2.0 dopadne při konverzi datumu na SQL serveru špatně (16/07/2010 konvertuje na 1.1.1900). SQL server přece obdrží formálně stejný zápis příkazu INSERT. Je-li tento INSERT vygenerován scriptem VB6, je vše OK, zatímco když je vygenerován VB.NET 2.0 scriptem, probíhá konverze datové položky jinak. Proč?? Problém musí být jedině v .NET platformě na tom SQL serveru, která nějak modifikuje znění příkazu "INSERT (...)", než jej předá na SQL, ufff.

Moc děkuji za nakopnutí správným směrem...

Jindra

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: .NET Tip #31: Pozor na datum v SQL Serveru

Tohle se bude hodit!

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Diskuse: .NET Tip #31: Pozor na datum v SQL Serveru

Velmi zajímavý postřeh. Je dobré vědět o rozdílech v reprezentaci časů na různých serverech. Taková věc se pak může těžko ladit. Chtěl jsem se ale zeptat, jestli existuje i možnost jak zjistit aktuální nastavení formátu datumu a času na serveru pro všechny datové typy: date, smalldatetime, datetime, datetime2 a datetimeoffset?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

To bohužel nevím. V zásadě jsem ale vždy potřeboval parsování směrem do SQL Serveru, ne naopak - pro získání hodnot zpětně lze používat YEAR(@datum), MONTH(@datum) a DAY(@datum). Vlastně jediný důvod proč parsovat datum je fixní vstup v rámci SQL skriptu. Mohu vědět, na co to využijete?

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Zatím to na nic využívat nepotřebuji. Jen by mě zajímalo jaký formát času SQL server tedy využívá - neboť je evidentně jiný pro různá lokalizace systému. Jestli to jde někde nalézt v dokumentaci či pomocí nějaké funkce.

Například zmiňovaná SET DATEFIRST procedura nastaví první den v týdnu a naopak pro jeho zjištění existuje @@DATEFIRST. Proto by mě zajímalo jestli existuje i nějaká funkce pro zjištění formátu času jako doplněk pro SET DATEFORMAT metodu, osobně jsem v dokumentaci nic nenašel.

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.

Nyní zakládáte pod článkem nové diskusní vlákno.
Pokud chcete reagovat na jiný příspěvek, klikněte na tlačítko "Odpovědět" u některého diskusního příspěvku.

Nyní odpovídáte na příspěvek pod článkem. Nebo chcete raději založit nové vlákno?

 

  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:  
Heslo:  

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback