No mne naskakuje husia koža aj keď vidím alternatívu b (ktorá je uvádzaná ako dobrá). Je možno lepšia ako a z performance hľadiska, ale pre mňa dobrá je maximálne ako workaround.
Predsa SQL interpret musí vedieť implicitne skonvertovať string vo formáte 'YYYY-MM-DD' (poprípade iný vopred daný formát) na dátum. Konverzie dátumov na string a naopak sa má predsa robiť len na UI vrstve.
Milujem keď čítam zdrojový kód a vidím že developeri hore dole na applikačnej a SQL vrstve konvertujú dátumy na string a naopak.
V příkladu sale_date = to_date('1970-01-01', 'YYYY-MM-DD') se jedná o explicitní konverzi ze stringu na date. Pokud napíši sale_date = '1970-01-01' tak dojde k téměř k témuž - k implicitní konverzi stringu na date. Použití explicitní konverze patří mezi best practice (minimálně na Oracle), kdy se snižuje závislost chování aplikace na konfiguraci databáze - nejde ani o výkon, ale o blbuvzdornější aplikaci - co vím, tak Oracle konverzi zvládne, bez problémů - předchází se tím ale nastartování UI, kdy se databáze snaží rozpoznat formát.
Mno ... nevim jak ktera databaze, ale minimalne nektery ti v pripade varianty A budou provadet konverzi VSECH zaznamu v tabulce na char, aby je slo porovnat s charem, kdezto v pripade druhym, se konverti jednou pred zahajenim dotazu, kterej je o porovnani s konstantou ... coz muze byt i radove rychlejsi.
Jestli pak budes provadet explicitni nebo implicitni konverzi ... to uz je jen otazka "sychr je sychr", protoze formaty datumu ... to je v databazich kapitola sama pro sebe (stejne jako desetinna tecka vs carka ...).
Zcela zjevne si nikdy nic zasadniho neresil, protoze jinak by ses nad takovou drobnosti vubec nepodivoval. Ja tu mam trebas M$ SQL a to, v jakym formatu datum zkousne zalezi i na fazi Mesice ... (ja mam EN widle, kolega CZ ... a na problem je zadelano, protoze kdyz mu ja poslu query s implicitni konverzi, on ho proste nespusti a musi si ho predelat).
Před více než 10 roky jsem na s MS SQL zažil drsné chvíle, kdy server měnil implicitní formát v závislosti, jestli byl na serveru někdo přihlášený nebo ne (přepínal češtinu a angličtinu). Ve chvíli, kdy jsem se tam přihlásil, abych oddebugoval jednu chybu mi aplikační server spadnul na chyby formátů. Takže já osobně tuhle best practicy respektuji.
Len tak naokraj som chcel, že v MSSQL by vás ani CONVERT(DATETIME, 'YYYY-MM-DD') vo všetkých jazykoch nezachránil. CONVERT(DATETIME, 'YYYYMMDD') už áno. Je to relatívne bežný omyl.
Chápem že situácia je taká aká je a kvôli spätnej kompatibilite sa to tak ľahko nezmení. Len sa mi zdá trochu choré že server musí ešte riešiť aj konverziu dátumov podľa nastaveného jazyka a nie proste striktne vyžaduje len jediný správny formát. Zobrazenie a čítanie dátumov v používateľom požadovanom formáte by podľa mojej skromnej mienky malo byť záležitosťou UI.
To souhlas, ale proste je to tak jak to je, ze primo SQLko umi vracet datumy v ruznych formatech na prani ... a uplne stejne se chovaji desetinna cisla, kde z toho podle nastaveni vylezou tecky nebo carky. A to znam i aplikaci, kde se pri komunikaci pres XML vyplnuje zhruba nasledovne:
[OBJEDNAVKA]
[POLOZKA zbozi="sud" baleni="3,5"]4.7[/POLOZKA]
[/OBJEDNAVKA]
Proste nejakou hlavu vymazanou by bylo treba strcit do 1/2coulovy vodovodni trubky ... zjevne by se tam vpohode vesla.
Ja tu neriešim variantu A, mne sa len nepáči varianta B a ani to nie s ohľadom na performance, ale kvalitu kódu. Ja som proste zástanca jednoduchosti a nepáči sa mi keď niekto rieši niečo na vrstvách na ktoré to nepatrí.
No trochu sa ma dotklo keď si ma obvinil na základe tvojich dojmov že som nič poriadne neriešil :). Ja som veru nikoho konkrétneho neurážal. Ale keď vidím mnohých diskutujúch ktorým etika na fórach nič nehovorí, tak sa nad tým len pousmejem.
Keby si mi radšej napísal ako v tvojich zásadných riešeniach postavených na M$SQL postupuješ keď nevieš aký je nastavený jazyk a aká je fáza mesiaca. Pretože ja som na podobný problém ešte nenarazil. Asi som príliš zásadový dátum vždy píšem ako YYYYMMDD alebo YYYY-MM-DDTHH:MM:SS (poprípade YYYY-MM-DD ale to len keď sa hrám v konzole a chcem aby to pekne vyzeralo, každopádne ako generovaný string z DB adaptéra by som to pre MSSQL nepoužil). Počul si už o ISO 8601 o ktorom už počuli aj súdruhovia v M$?
Pouzivat muzes format jaky chces, potiz je v tom, ze ty jednoduse predem nevis, jak se rozhodne to M$ SQL ze ma/nema nastavenej jazyk/konverze. Pokud mas aplikaci + server naprosto ve svy moci, tak se sice da spolejhat na to, ze se to bude chovat porad stejne (dokud to neopatchujes), ale k databazi/serveru se vetsinou taky pripojujou nejaci klienti ... a u tech proste to, jak maji nastavenej jazyk neovlivnis. Navic prave v pripade widli je velmi zasadni rozdil, jestli jde o widle anglicke s ceskou lokalizaci nebo widle ceske ... a to na vsech urovnich (jak srv tak klient).
A potom konverzi zajistuju tam, kde uz to mam ve sve moci - tedy klido na urovni SQL. Totiz ona bezpecnost/konzistence dat/... je o asi tak rad dulezitejsi, nez nejaka milisekunda.
BTW: Spousta "webaru" pouzivajicich MySQL vubec netusi, jak (spravne) tu databazi pripojit, a pak se divej, ze maj potize s diakritikou, s hledanim ... a datumy, protoze vubec netusej, ze jsou 3 mista, kde to musi nastavit - a jedno z nich je trebas vlastni konexe do databaze, kde se prave spolejhaj na nejakou implicitni hodnotu ... o ktere vubec nevi ze existuje.
(pro zajimavost, v pripade webu je treba znat nataveni databaze, nastaveni konexe a pak jeste poslat spravne hlavicky - jinak to nebude fungovat)
Pokud vim, jeho predstava je, ze to ma vypadat takhle:
SELECT
FROM sales
WHERE sale_date = '19700101';
Coz bude sranda, az tam napisu '19700511' a pak se bude resit, jestli je to 11.5. nebo 5.11. ... nebot oboji je jiste mozne (a i ten vice imbecilni zapis - tedy YYYYDDMM sem uz videl - pouzivaj ho britove, podobne jako palce a stopy ...).
Pokud tam je ta konverze, tak je zcela jasne, co tim pisatel minil a tudiz netreba resit, jak je zrovna nastaveny prostredi.
No myslel som si že to priamo vyplýva z toho čo som napísal, ale to môže povedať o sebe každý. Takže sa ospravedlňujem a skúsim ešte raz:
Neodsudzujem autora že robí CONVERT, ja to ale nepovažujem za ideálne riešenie, ale ako nutné zlo (workaround), a úplne chápem že na niektorých serveroch sa to proste robiť musí. Kebyže Convert nebol potrebný, nikdy by developer nebol omylom napísal niečo ako Variant A (iba ak naschvál).
V ideálnom svete by každý SQL server ktorý vie že sale_date je typu date/datetime pochopil
SELECT FROM sales
WHERE sale_date = 19700101
ale nie som ortodoxný. Celkom by mi stačilo aby si každý výrobca SQL servera zvolil svoj formát, ktorý vie za každých okolností implicitne rozparsovať
(napr. '19700101', '1970-01-01')
SQL bylo navrženo pro ruční zadávání, takže výrobci předpokládali, že uživatelé budou chtít zadávat a číst datumové typy dle svých národních zvyklostí - a s radostí jim to umožnili, a uživatelé to začali chtít. Navíc, v běžných programovacích jazycích chyběla jakákoliv podpora pro typ date, pro regulární výrazy, .. takže parsování stringů a operace s datumy na straně klienta byly dost obtížné, a bylo příjemné, když to db udělala za vás. Dost pozdě jim došlo, že to nebyl dobrý nápad, nicméně z důvodů zpětné kompatibility to už nešlo změnit. Když se podíváte do kódu Postgresu pro typ date, tak objevíte dost komplikovaný kód, kterého by se všichni rádi zbavili a podporovali jenom ANSI formát - 'YYYY-MM-DD', ale to nejde.
Jinak způsob zápisu datumu jako celého čísla není šikovný. Totiž hrozí možná záměna s integrem - jednak hrozí riziko chyb typu
WHERE sales_date = 1970-01-01
což je samosebou něco jiného, než programátor očekával - a třeba pg nedovoluje implicitní konverzi mezi date a int.
Aha. Jedna se tedy o konflikt mezi Vasi predstavou "idealniho sveta" a realitou.
To je opravdu nebezpecny pristup. Toto neni idealni svet, kazdy SQL server je trosku jiny a snaha psat reseni pro "idealni svet" nutne skonci spatne. A prestoze ja sam si casto preji, aby ruzne technologie pracovaly trosku "lepe" (rozumejte: tak jak JA si myslim ze by to bylo lepe), tyto uvahy vedou pouze k frustraci a stresu.
Je urcite dobre vedet jak by slo neco udelat lepe (a pak to tak udelat, pokud clovek dostane prilezitost), ale kritizovat SPRAVNE a FUNKCNI reseni, protoze by v "idealnim svete" mohlo byt jine, je velmi spatny pristup.
Implicitní konverzi je obecně lepší se vyhnout. Navíc třeba konkrétne u Oracle nevíte co vlastně bude konvertovat.
Dotaz
select * from tabulka where sloupcec_typu_string=1;
proběhne tak, že se pokusí zkonverovat hodnoty soupečku na číslo (a přitom samozřejmě většinou spadne)
Uvedeny priklad a konverzia to_date('1970-01-01', 'YYYY-MM-DD') je uplne spravna a presne takto sa to ma robit. Pretoze neexistuje, aby sa to ponechalo na implicitnu konverziu. Naopak, komukolvek, kto ponechava konverziu na DATE na system a robi implicitnu konverziu, by som lamal ruky. Jedine co by som vylepsil je na to_date('19700101', 'YYYYMMDD') .