Autor Téma: SQLite - zápis dátumu v Select  (Přečteno 2499 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
SQLite - zápis dátumu v Select
« kdy: 13-06-2016, 16:07:15 »
Príklad som nenašiel a mne vychádza, že to mám písať v tvare '01.01.2015' alebo '2015-01-01'
Ale problém je aj v tom, že v DB mám dátumy zobrazené dvoma spôsobmi:
1) 01.01.2015
2) 2015-01-01
a to sú, aspoň podľa mojich pokusov, dve rôzne hodnoty! Neviem síce prečo mám dva druhy zápisu, ale robí to problém. Predsa budem používať DateToStr(MyDate).
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Daniel_Andrascik

  • Hrdina
  • ****
  • Příspěvků: 392
  • Karma: 15
    • Verze Delphi: D2007, XE3
Re:SQLite - zápis dátumu v Select
« Odpověď #1 kdy: 13-06-2016, 17:02:39 »
No DateToStr momentalne nie je zrovna najlepsia volba. Vysledny textovy retazec je totiz zavisly od jazykovych nastaveni windowsu. Takze sa ti ani moc necudujem ze mas v db datumy raz tak a raz inac. Vseobecne pouzivany format datumu v SQL je "yyyy-mm-dd [hh:nn[:ss[:mmm]]]" (hranate zatvorky oznacuju nepovinne zadanie).

Zasadne pouzivam tieto dva prevodove prikazy na zadavanie datumov do sql.

Kód: [Vybrat]
FormatDateTime('yyyy-mm-dd',MyDate);
FormatDateTime('yyyy-mm-dd hh:nn:ss',MyDate);

Najidealnejsie bude ked si vytvoris na to dve funkcie nieco ako DateToSQLDateString a DateTimeToSQLDateString, nech nemusis ten format stale pracne vypisovat.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #2 kdy: 13-06-2016, 18:31:35 »
V skutočnosti použijem EncodeDate. To bol iba príklad, že použijem nejakú funkciu na vrátenie dátumu, ktorého formát je závislý na nastavení OS. Ako to aj spomínaš.
Mňa viac trápi, že v jednej tabuľke mám dva druhy zobrazenia dátumov a s tými sa pracuje. Neviem ako som k tomu došiel. Doteraz som vždy vychádzal z toho, že nezáleží ako sú údaje zobrazené ale ako sú uložené. A dátum je vždy číslo.
Lenže tu mi vychádza, že to tak nie je. To je pre mňa menší šok.
Predsa je nezmysel aby som písal
Kód: [Vybrat]
where MyDate = '01.01.2015' or Mydate = '2015-01-01'
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline mjseven

  • Mladík
  • **
  • Příspěvků: 59
  • Karma: 5
    • Verze Delphi: D7, D2006, XE2, Lazarus
Re:SQLite - zápis dátumu v Select
« Odpověď #3 kdy: 13-06-2016, 18:42:22 »
V SQLite jsou datumy malá alchymie  :(
Pro práci v selectech mi hodně pomohla funkce strftime https://www.sqlite.org/lang_datefunc.html
přímo v SQL dotazu.
Tuším, že číselně ukládá jen TimeStamp a ostatní datumové jako text.




Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #4 kdy: 13-06-2016, 18:44:40 »
Citace
Tuším, že číselně ukládá jen TimeStamp a ostatní datumové jako text.
To správanie tomu zodpovedá. Na tie funkcie som narazil, ale nevenoval som im veľmi pozornosť. Ale prečo mi to uložilo v rôznych formátoch (FireDACSQLite)
« Poslední změna: 13-06-2016, 18:53:43 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 1678
  • Karma: 70
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite - zápis dátumu v Select
« Odpověď #5 kdy: 13-06-2016, 20:54:05 »
Kód: [Vybrat]
where MyDate = '01.01.2015' or Mydate = '2015-01-01'
No hlavne: ty nemas u zadne DB co v selectu zapisovat datum a cas v nejakem konkretnim formatu. Konkretni format datumu je otazka prezentacni vrstvy na rozhrani stroj-clovek a preferenci UI.

Na to jsou parametrizovane dotazy, kde to do parametru predas hodnotu jako Delphi typ TDateTime (nebo jak se to jmenuje) a zbytek nechas na wrapperu. A ten by mel vedet, jake jsou moznosti Sqlite pracovat s datumem a casem viz

http://www.sqlite.org/datatype3.html#section_2_2
http://www.sqlite.org/lang_datefunc.html

a vhodne SQL prikaz sestavit.


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #6 kdy: 13-06-2016, 21:23:29 »
Ten SQLite ma privedie do hrobu. Na čo som sa to dal nahovoriť :'(
Citace
Na to jsou parametrizovane dotazy, kde to do parametru predas hodnotu jako Delphi typ TDateTime
Robím to zásadne a iba/len cez parametre. Napriek tomu sa mi tam objavil v dvoch formátoch. A formát dd.mm.yyyy neuvádzajú. Neviem či to nie je zmena platná pre ver. 3.13.0
Teraz konkrétne
Kód: [Vybrat]
SELECT DISTINCT CLUB_MEMBER.DATEFROM, CLUB_MEMBER.DATETO
FROM CLUB_MEMBER
WHERE
  ('10.04.2016' BETWEEN CLUB_MEMBER.DATEFROM AND CLUB_MEMBER.DATETO) or
  (CLUB_MEMBER.DATEFROM < '10.04.2016' and CLUB_MEMBER.DATETO is null)
mi vráti

01.01.2015
01.01.2015 30.04.2016  // Majú byť dva
01.05.2016                     // nejakých 110

V prílohe je časť tabuľky. Záznamov s DateTo is null je tam 111


Zabudol som. Teraz tie príkazy robím v query builder-y. Preto tam nemám parametre. Ale ani parametre nepomohli.
« Poslední změna: 13-06-2016, 21:35:02 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Daniel_Andrascik

  • Hrdina
  • ****
  • Příspěvků: 392
  • Karma: 15
    • Verze Delphi: D2007, XE3
Re:SQLite - zápis dátumu v Select
« Odpověď #7 kdy: 13-06-2016, 21:36:18 »
ja sa zacinam obavat ze tie tvoje stlpce DATEFROM a DATETO su v podstate textove fieldy a co do nich nasipes to tam mas format neformat a komparacaie ktore nad nimi robis v SQL nie su ciselne, ale uz textove. Ako mas definovau tu tabulku vlastne?

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #8 kdy: 13-06-2016, 21:50:38 »
Citace
Ako mas definovau tu tabulku vlastne?
Dobre :)
Kód: [Vybrat]
CREATE TABLE CLUB_MEMBER
 (IDCLUB_MEMBER INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
FKCLUBS INTEGER NOT NULL REFERENCES CLUBS (IDCLUBS),
FKMEMBERS INTEGER REFERENCES MEMBERS (IDMEMBERS) NOT NULL,
DATEFROM DATE NOT NULL,
DATETO DATE);
A dátumy sa skutočne ukladajú ako texty.
Citace
2.2. Date and Time DatatypeSQLite does not have a storage class set aside for storing dates and/or times. Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values:
  • TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").
  • REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar.
  • INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC.
Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #9 kdy: 13-06-2016, 21:54:04 »
No, teraz som pokusne uložil dátum a je vo formáte 2016-10-14. Idem všetko upraviť do tohto formátu a uvidím čo sa bude diať.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #10 kdy: 13-06-2016, 22:13:43 »
Dokonca mi po oprave vyberie iba dva záznamy. A všetko čo sa týka dátumov som si poriadne skontroloval.
V Accesse by som to mal už 3x hotové >:(
A to ešte nepodporuje Right a Outer Join ! Osobne mi to nevadí ale query builder mi v niektorých prípadoch pretláča Right namiesto Left a potom ryčí ::) . Samé radosti 8)
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #11 kdy: 13-06-2016, 22:30:11 »
Už som skoro vypol NB, ale ešte som to skúsil. A už mi to ide. Mám taký dojem, že ak niečo s SQLite robím, tak môže/musí byť otvorená len raz - v jedinom programe. Ináč to bude robiť bludy. A to som nemal splnené. Mal som ju otvorenú v SQLiteStudio a FlySpeed SQL Query.
A tiež nie je možné použiť jeden parameter na dvoch miestach. Musia byť dva. Či sa mýlim? To neznáša ani Access. FB s tým problém nemá.
Snáď to zajtra dokončím.
« Poslední změna: 13-06-2016, 22:33:18 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Daniel_Andrascik

  • Hrdina
  • ****
  • Příspěvků: 392
  • Karma: 15
    • Verze Delphi: D2007, XE3
Re:SQLite - zápis dátumu v Select
« Odpověď #12 kdy: 13-06-2016, 23:45:01 »
No jo. SQLite pracuje s datovymi typmi dost zvlastne. Ma aj jeden "misticky" datovy typ nazvany NUMERIC. V SQLite okrem celociselnych typov a textov nic ine nepouzivam takze nemal som v tom az taky velky prehlad. Ale preletel som si popis datovych typov a v rychlosti som to pochopil tak ze datovy typ NUMERIC (a vlastne nie len on, ale asi vsetky) mozu vyuzit hociaku uloznu triedu (INTEGER, REAL, TEXT i BLOB) s tym ze do datoveho typu NUMERIC sa prevadzaju stlpce z deklaraciou BOOLEAN, DATE, DATETIME, DECIMAL(x,y) a vlaste vsetky ktore SQLite nepozna a SQLite si sama vyberie az pocas inzertu alebo updatu do akej uloznej datovej triedy to bude ukladat a zacina od tych najusporejsich a ked jej to neide tak stale postupuje vyssie.

Cizne najprv sa data snazi ukladat ako Integer, ked to neide tak potom ako real a ked ani to neide tak potom TEXT a ten si mozme povedat ze znesie vsetko. No a to sa stalo aj tebe. Mysteriom tohto pristupu je to ze aj ked je stlpec definovany ako nejaky typ, ci uz INTEGER, REAL, NUMERIC, alebo TEXT tak aj tak v podstate na kazdom riadku tabulky moze byt inym datovym typom. Teraz som si to vyskusal a ziram.

Skus si nieco take:
Kód: [Vybrat]
CREATE TABLE t1(nu NUMERIC);
INSERT INTO t1 VALUES(500);
INSERT INTO t1 VALUES(500.58);
INSERT INTO t1 VALUES(x'A6B3D0');
INSERT INTO t1 VALUES('asfsd fadsf');
SELECT typeof(nu) FROM t1;

Cize ja osobne v SQLite ked pracujem z datumami tak vzdy pracujem s unixackim vyjadrenim casu coz je pocet sekund od 1970-01-01 00:00:00 UTC (delphi na to ma tiez funkcie DateTimeToUnix a naopak). Pokial nepotrebujem milisekundy tak vzdy preferujem tento cas pretoze sa jedna o najuspornejsi datovy typ a to celocislny integer s ktorym sa pracuje najrychlejsie a najuspornejsie. Problem je len to ze je to pracnejsie pretoze to vobec nie je human readable udaj a stale s nim musis narabat pomocou funkcii https://www.sqlite.org/lang_datefunc.html Cize furt musim pouzivat napr. nieco take:

Kód: [Vybrat]
SELECT datetime(MyUnixTimeField, 'unixepoch');
a podobne

Na druhu stranu zase krasne a jednoznacne pracuju operatory <, >, =. Pretoze je to klasicka celocislna aritmetika, cize ja som v tomto pripade nikdy nemal problem. No praca s datumami v SQLite nie je celkom to prave orechove.

Ak mas datum v tabulke ulozeny vo formate '01.01.2001' tak si v prdeli, pretoze na to nemozes pouzit operatory < a >. Pretoze ak ho budes porovnavat s datumom '30.01.1000' tak ten s letopoctom tisic bude vacsi ako ten z 2001 pretoze 30ka je vacsia ako 01. Ak by si mal datumy striktne ulozene vo formate yyyy-mm-dd tak ti to porovnanvanie bude este dobre fungovat. Cize bud pouzi pocet sekund cize unix time, alebo textovy format yyyy-mm-dd ale potom si musis byt vedomi toho ze je to len text a vzdy to len textom ostane a platia pre to aj vsetky ostatne pravidla a format musis dodrzat do bodky...

A este pozor aj na takuto chybu 2016-5-15. Namiesto 5ky musi byt vzdy 05. Pocet znakov musi byt vzdy 10.
« Poslední změna: 13-06-2016, 23:49:57 od Daniel_Andrascik »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #13 kdy: 14-06-2016, 07:43:02 »
Vďaka za vysvetlenie. Keď som sa dočítal, že to je text, tak ma napadli aj tie súvislosti. Aj to, že formát 01.01.2016 je volovina.
Ako prinútim FireDAC aby dátum uložil v unix formáte? To bolo prvé čo ma napadlo. Číslo je číslo. Radšej používať tie funkcie, než mať bordel. Akurát to v náhľade neprečítam.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 2610
  • Karma: 23
    • Verze Delphi: XE7 professional
Re:SQLite - zápis dátumu v Select
« Odpověď #14 kdy: 14-06-2016, 08:14:12 »
A najlepšie by to bolo bez času. Len čistý dátum.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: