Autor Téma: SQLite a TBCD prakticky + Problém  (Přečteno 3304 krát)

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #15 kdy: 21-07-2018, 21:59:20 »
Hneď idem vyskúšať..
Vyskúšané !
Funkcia ako taká zbehne. Aj výsledok je matematicky správny, lenže..
Pri vyťahovaní výsledku ( x2 := FDQuery1.Fields[ 1 ].AsBcd; )  príde ku chybovej hláške:

'-12345678901234567891.12345678901234567890123456789012345678901 is not a valid BCD value'
Tá nešťastná bodka - čiarka ako decimal separator stále straší.
Nie je lepšie zabezpečiť pre program, aby sa systém rovno tváril ako US a nie SK/CZ ?

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #16 kdy: 21-07-2018, 22:08:31 »
Inak toto funguje OK:
Kód: Delphi [Vybrat]
  1. AOutput.AsString := BcdToStr( AInputs[ 0 ].AsNumber - AInputs[ 1 ].AsNumber );
Nie je to ideál, ale myslím, že k nejak výraznému spomaleniu nepríde.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite a TBCD prakticky + Problém
« Odpověď #17 kdy: 21-07-2018, 22:31:14 »
Potiz je v tom ze sloupec pro tu UDF funkci v SQL prikazu nepopise datovy typ a vytvori se TStringField. Jeho accessor AsBCD se pak pokusi zkonvertovat retezec s ohledem na nastaveni systemu (a pokud mas carku, dojde k vyjimce). Zkousel jsem datovy typ vynutit:

Kód: MySQL [Vybrat]
  1. SELECT TheValue, Rozdiel(TheValue, 1) AS "x::FLOATTEXT" FROM MyTable;

Nicmene tady se zda ze neprobehne mapovani.
« Poslední změna: 21-07-2018, 22:34:08 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #18 kdy: 21-07-2018, 22:43:15 »
Žiadny pozitívny efekt proti predošlému textu. Ale to riešenie, čo som upravil posledne, je nanajvýš uspokojivé.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite a TBCD prakticky + Problém
« Odpověď #19 kdy: 21-07-2018, 22:48:34 »
Žiadny pozitívny efekt proti predošlému textu. Ale to riešenie, čo som upravil posledne, je nanajvýš uspokojivé.

Tve reseni je bezpecna cesta, protoze jak Ty, tak AsBCD accessor pouzivate konverze vyuzivajici nastaveni systemu. Vrta mi vsak hlavou ta ignorace mapovani.
« Poslední změna: 21-07-2018, 22:50:19 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #20 kdy: 21-07-2018, 23:10:07 »
Už sa teším na budúce aggregate bcdSUM, bcdCOUNT, bcdAVG a aj MIN MAX :)
Ono sa to na prvý pohľad nezdá, ale v double po pár matematických operáciách a zaokrúhleniach sa stráca presnosť.
Nevraviac už o tom, že double ako také nie je možné vzájomne porovnávať.
Ten typ numeric, v rozsahu aspoň 20 číslic by pomohol. Ako presné číslo. Nie ako nejak neurčito zaokrúhlený float. A tá zbytočnosť exponentu u float. Tragédia.
Komu treba 45 000 000 000 000 000 000 000. Ten sprostý exponent je tak akurát dobrý na podobnú somarinu..
Leda tak hypoteticky na IBAN. Lenže tam nejde zase CZ/SK, lebo to už je TEXT
Dobre nech si nechajú aj číslo s exponentom, ale nech k nemu dajú ekvivalent na normálne číslo, čo nemusí byť primitívne zaokrúhlené. To je pre databázy pomerne tragédia..
Preto by mal existovať riadny Numeric / Decimal, ktorý by mal 10-12 bytov a bolo by to prevždy vyriešené. Myslím že to mala už prastará dbf-ka. To zase prišiel na svet medzitým nejaký vedecký mudrlant..
Tu nejde o to, že by SQLite nepodporovala taký rozumný formát.
Odklonili sa od neho aj programovacie jazyky. Aspoň do tej miery, že ak ho majú, tak len ako nejakú neplnohodnotnú a neefektívnu exotiku.
Currerncy by bol kandidát. Ale niekedy je treba viac miest za desatinnou bodkou, než má Currency.
Preto Decimal, napríklad aj taký nenáročný ako Decimal(5, 2). Ale presný.


« Poslední změna: 21-07-2018, 23:21:30 od Miroslav Baláž »

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3686
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:SQLite a TBCD prakticky + Problém
« Odpověď #21 kdy: 22-07-2018, 09:05:28 »
A rozdeliť to desatinné číslo na dve celé čísla? Neviem, ani len netuším, čo by to znamenalo v praxi pri matematických operáciach
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #22 kdy: 22-07-2018, 11:51:36 »
Uvažoval som o tom. 2 x 8 bytov (celkom 16), by nádherne stačilo. Keby to bolo napríklad niečo ako Currency, s presnosťou nie na 4, ale aspoň 10 číslic. Aj keď Currency tuším interne počíta so 6 desatinnými miestami, výsledok, zaokrúhľuje na 4. Tá pevná desatinná časť je smola.
Pre dve čísla v databáze by museli byť dve polia a s tým robiť SQL-y.. To by bolo divné.
Preto by to chcelo odkladať ako record do blobu.
Tiež by to chcelo narobiť špeciálne funkcie. Prvé pole by nieslo info o celých číslach. No a desatinná časť by bolo double.
Mimo databázy ( v Delphi ) by sa ten record uložil do BCD. Základné výpočty BCD zvláda.
Lenže to by bolo treba prekopať FireDAC.

Úplnou lahôdkou pre prácu s číslami je knižnica MPArith 1.37.12 https://sslsites.de/wolfgang-ehrhardt.de/
Používa niečo ako veľké celé číslo a k tomu má info o :  1. exponente a 2. bitprecision.
Knižnica pri voliteľnom rozsahu presnosti, umožní nielen základné matem operácie, ale aj mnohé matematické funkcie.
Pri voľbe presnosti 80 bitov spočíta výsledok s presnosťou 24 čísel.
Presnosť sa dá nastaviť napríklad na 512 bitov.
Max presnosť je však až 120000 bitov !!!
Smola je, že každé číslo tam pozostáva z cca 5 Bigint + reťazec číslic podľa presnosti.
Je to veľká "spotreba" najmä kvôli variabilite tej knižnice.

Z toho nejak odkukať, ako využiť 10 bajtov (fixne, bez možnej zmeny rozsahu ), z toho 9 bajtov pre presnosť 21 číslic   + 1 bajt na mantisu.
Resp poskytovať presnosť 19 číslic a posledné dve zaokrúhliť, ako to robí Currency.
10 bajtov by som v databáze na danú tému vďačne obetoval.

Je to určite menej než berie BCD v kombinácii s textom. Tam je to 34 bajtov. Ak taký text uložím ako UTF16, bude to 68 bajtov.



Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2339
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite a TBCD prakticky + Problém
« Odpověď #23 kdy: 22-07-2018, 11:52:05 »
To je pre databázy pomerne tragédia..
Preto by mal existovať riadny Numeric / Decimal, ktorý by mal 10-12 bytov a bolo by to prevždy vyriešené. Myslím že to mala už prastará dbf-ka. To zase prišiel na svet medzitým nejaký vedecký mudrlant..
Tu nejde o to, že by SQLite nepodporovala taký rozumný formát.
"Normalni" RDBMS samozrejme radnou podporu nejakeho BigDecimal typu maji. Ale kdyz si zkusis na foru SQLite vyhledat podobne pozadavky jako mas, tak odpovedi je, ze SQLite je LITE...

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #24 kdy: 22-07-2018, 12:28:23 »
..
"Normalni" RDBMS samozrejme radnou podporu nejakeho BigDecimal typu maji. Ale kdyz si zkusis na foru SQLite vyhledat podobne pozadavky jako mas, tak odpovedi je, ze SQLite je LITE...
To beriem.
Lenže ani Delphi k tomu neposkytuje moc podpory, nielen databáza/SQLite.

Ešte tak BCD. Lenže to je doosť veľké a skôr nejaké kostrbaté:
Ako vidíme, FireDAC pre SQLite poskytuje určité možnosti (BCD). Tam sa ale zase výdatne pletie problém desatinná čiarka vs desatinná bodka.
Je to veru nejaké nedotiahnuté.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2339
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite a TBCD prakticky + Problém
« Odpověď #25 kdy: 22-07-2018, 13:22:04 »
Ešte tak BCD. Lenže to je doosť veľké a skôr nejaké kostrbaté:
Ako vidíme, FireDAC pre SQLite poskytuje určité možnosti (BCD). Tam sa ale zase výdatne pletie problém desatinná čiarka vs desatinná bodka.
Je to veru nejaké nedotiahnuté.
Tak desetinna tecka/carka a oddelovace tisicu vyzaduji pozornost vzdycky, protoze ruzni useri mohou mit ruzna narodni prostredi a to dokonce v jednom kulturnim prostredi napr. programator serverovych aplikaci vetsinou miva anglicy OS, naopak cizokrajny manager miva svoje materske prostredi atd. Asi jedinym uspokojivym resenim je udelat striktni rozhrani mezi view a modelem, tam se vyfackovat s ruznym formatem a vnitrne uz pouzivat jenom jeden. U SQLite to lze vynutit asi before triggerem - jakmile ti do pole nekdo strci hodnotu v jinem formatu, tak to fuckovat

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1396
  • Karma: 58
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:SQLite a TBCD prakticky + Problém
« Odpověď #26 kdy: 22-07-2018, 16:00:51 »
U SQLite to lze vynutit asi before triggerem - jakmile ti do pole nekdo strci hodnotu v jinem formatu, tak to fuckovat

Do sloupce s affinity TEXT muzes ulozit textovou hodnotu s tim ze se ulozi vzdy tak jak je. Ve FireDAC pak muzes vytvorit mapovani trebas na dtFmtBCD diky cemuz se zacnou tvorit sloupce typu TFMTBCDField kde se s hodnotou v bufferu pracuje spravne (pro textovou hodnotu je vsak treba pouzit desetinnou tecku). Problemem jsou UDF, kde se pro vystup vytvori sloupec typu TStringField do nehoz kdyz sahnes pro hodnotu pres AsBcd accessor, pouzije konverzi na zaklade nastaveni systemu.
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #27 kdy: 22-07-2018, 16:05:12 »
..
Tak desetinna tecka/carka a oddelovace tisicu vyzaduji pozornost vzdycky, protoze ruzni useri mohou mit ruzna narodni prostredi a to dokonce v jednom kulturnim prostredi napr. programator serverovych aplikaci vetsinou miva anglicy OS, naopak cizokrajny manager miva svoje materske prostredi atd. Asi jedinym uspokojivym resenim je udelat striktni rozhrani mezi view a modelem, tam se vyfackovat s ruznym formatem a vnitrne uz pouzivat jenom jeden. U SQLite to lze vynutit asi before triggerem - jakmile ti do pole nekdo strci hodnotu v jinem formatu, tak to fuckovat
Ten trigger, to je dosť zaujímavý nápad. Nad tým sa ešte zamyslím

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2339
  • Karma: 126
    • Verze Delphi: D2007, XE3, DX10
Re:SQLite a TBCD prakticky + Problém
« Odpověď #28 kdy: 22-07-2018, 16:53:16 »
pouzije konverzi na zaklade nastaveni systemu.
No ale abych to nemusel resit, tak si triggerem zajistim, ze v DB se do pole TEXT nedostane syntaxe, kterou tam nechci videt a pak v te UDF udelam jen konverzi formatu, kterou videt chci za pouziti sveho TFormatSettings

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 377
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:SQLite a TBCD prakticky + Problém
« Odpověď #29 kdy: 22-07-2018, 17:07:30 »
..
Do sloupce s affinity TEXT muzes ulozit textovou hodnotu s tim ze se ulozi vzdy tak jak je. Ve FireDAC pak muzes vytvorit mapovani trebas na dtFmtBCD diky cemuz se zacnou tvorit sloupce typu TFMTBCDField kde se s hodnotou v bufferu pracuje spravne (pro textovou hodnotu je vsak treba pouzit desetinnou tecku). Problemem jsou UDF, kde se pro vystup vytvori sloupec typu TStringField do nehoz kdyz sahnes pro hodnotu pres AsBcd accessor, pouzije konverzi na zaklade nastaveni systemu.
O UDF sa postarám. Tam je pri SELECT-e už nutný typecasting.
Aby som však  nemusel večne typecast-ovať, tak by som chcel spraviť takú úpravu FireDAC, že prefix u názvu poľa by znamenal automaticky nejaký typ.
Ono sú s týmto tvarom "FieldName::Integer" trochu obecnejšie problémy.
Mám predstavu asi takto:
"s_"  : String/Text
"n_"  : Numeric( 30,10 ) - to stačí na vytvorenie tfFmtBcd. Numeric(28, 10) ešte nestačí, to by bol len ftBcd a ten prakticky nemá význam, lebo Double.
a tiež "t_", "d_", "dt_" .. atď
Niečo v tom smere sme už preberali. Myslíš, že mám šancu?
Dokonca Float/Double a Text by nemuseli byť v tom zahrnuté, lebo do nich to spravidla padne
samo.

« Poslední změna: 22-07-2018, 17:13:43 od Miroslav Baláž »

 

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: