Pôvodne ma vystrašila info z odkazu:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#High-Precision_Numbers (http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#High-Precision_Numbers)
A nemá se v tom INSERT použít desetinná tečka?S bodkou to nefungovalo vôbec. S čiarkou tak, ako som napísal.
Vtip je v tom, že ten Numeric funguje. Je pravdepodobné, že FireDAC interne prehodí typ na blob, alebo text. Funguje nad tým napríklad aj agregačná funkcia SUM. Ibaže zobrazí double. Zatiaľ mi vkladanie funguje len cez Delphi kód. Nie cez SQL. Napríklad pre Numeric( 26,16 ), sa zdá, že pracuje ako s Float/Double.Pôvodne ma vystrašila info z odkazu:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#High-Precision_Numbers (http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#High-Precision_Numbers)
Duvod je na miste. Manual rika, ze pro takto precizni hodnoty mas pouzit datovy typ TEXT a mapovani datovych typu FireDAC. SQLite tak precizni hodnotu do datoveho typu REAL neulozi.
Jinak hlodá ve mně zvědavost, z jakého měření padají tak přesná čísla, protože i double by uměl uložit vzdálenost ze Země k Alfa Centauri s přesností naTeraz je to ako hobby. Ale plánujem to rozbehnúť. Už viackrát som narazil na problém s nepresnosťou pri sčítaní veľkého množstva údajov. V rámci rôznych štatistík.1 cm10 m :-)
Vtip je v tom, že ten Numeric funguje. Je pravdepodobné, že FireDAC interne prehodí typ na blob, alebo text. Funguje nad tým napríklad aj agregačná funkcia SUM. Ibaže zobrazí double. Zatiaľ mi vkladanie funguje len cez Delphi kód. Nie cez SQL. Napríklad pre Numeric( 26,16 ), sa zdá, že pracuje ako s Float/Double.
Ale Numeric( 64,23 ), založí zrejme pole typu Char(34), aspon taky je datasize. Hlási ho však ako ftFMTBcd.
Vecer mrknu na to co se uvnitr deje..Rád sa dozviem niečo praktické na túto tému. Alebo zo zákulisia..
[quote link=topic=16248.msg100752#msg100752 date=1532095121]Rád sa dozviem niečo praktické na túto tému. Alebo zo zákulisia..
Vecer mrknu na to co se uvnitr deje..
Mohl by sis vsak vytvorit vlastni datovy typ, jenz bude mit affinity TEXT, treba FLOATTEXT a pro nej vytvorit mapovani (kdybys pouzil mapovani primo na TEXT, mohlo by dojit ke kolizi hodnot jenz mely byt ulozeny jako text). Pak muzes pouzit desetinnou tecku, protoze se SQLite nebude snazit o konverzi do SQLITE_FLOAT a FireDAC se stavajicim kodem dokaze prevest SQLITE_TEXT s desetinnou teckou. Tedy napr.:Samozrejme potrebujem k tomu vlastné Custom funkcie, pretože so stringami SQLite matiku neovláda.Kód: Delphi [Vybrat]..
var Value: TBcd; MapRule: TFDMapRule; begin FDQuery1.FormatOptions.OwnMapRules := True; MapRule := FDQuery1.FormatOptions.MapRules.Add; MapRule.TypeMask := 'FLOATTEXT'; MapRule.TargetDataType := dtFmtBCD; FDQuery1.SQL.Text := 'DROP TABLE IF EXISTS MyTable;' + 'CREATE TABLE MyTable(TheValue FLOATTEXT);' + 'INSERT INTO MyTable (TheValue) VALUES (''-12345678901234567890.12345678901234567890123456789012345678901'');' + 'SELECT TheValue FROM MyTable;'; FDQuery1.Open; Value := FDQuery1.Fields[0].AsBCD; ... end;
Samozrejme potrebujem k tomu vlastné Custom funkcie, pretože so stringami SQLite matiku neovláda.
AsNumber z toho spraví double a .. som v háji:)
Bolo by to celé zbytočné. Alebo som niečo prehliadol?
Bohužiaľ custom funkcie nepodporujú cast AsBCD
Inak, pozitívne je, že Custom funkcie SQLite databázu extra nespomaľujú.
Žiadny pozitívny efekt proti predošlému textu. Ale to riešenie, čo som upravil posledne, je nanajvýš uspokojivé.
To je pre databázy pomerne tragédia.."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...
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.
..To beriem.
"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...
Ešte tak BCD. Lenže to je doosť veľké a skôr nejaké kostrbaté: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
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é.
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
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
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
..O UDF sa postarám. Tam je pri SELECT-e už nutný typecasting.
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.
Niečo v tom smere sme už preberali. Myslíš, že mám šancu?
Tá funkcia/event funguje. Len je treba Castnúť funkciu v rámce SELECT.Kód: Delphi [Vybrat]
procedure TForm1.FDSQLiteFunction1Calculate(AFunc: TSQLiteFunctionInstance; AInputs: TSQLiteInputs; AOutput: TSQLiteOutput; var AUserData: TObject); begin AOutput.AsNumber := AInputs[0].AsNumber - AInputs[1].AsNumber; end;
se v metode TSQLiteValue.SetData pro parametr AOutput nastavi datovy typ SQLITE_TEXT a hodnota se prevede na text s desetinnou teckou. Problem nastane pri cteni hodnoty accessorem AsBcd (jenz pouziva systemovy format), nebo neco vic?
..
Tá funkcia/event funguje. Len je treba Castnúť funkciu v rámce SELECT.
Napríklad:Kód: MySQL [Vybrat]Potom sa dá čítať Field.AsBcd a aj Field.AsAnsiString.
Ak sa necastne, dá sa čítať len Field.AsAnsiString.
- dej pozor na prekryti puvodni property ??? čo sa stane ak ju prekryjem? Veď o to mi ide nie?
- pri pouziti puvodni verze zapisu se (u Tebe) pro TStringField ulozi retezec s carkou.
V mojej verzii som schválne vynechal :Kód: Delphi [Vybrat]Pretože tade to snáď nikdy nepôjde.
{ if Self is TStringField then SetAsString( Data.FmtBcd.BcdToStr( Value, fmtSettingsDOT ) ) else}
Ak zapisujem AsBCD, tak Firedac si pamätá, že zapisujem do poľa TNumericField a nie do TStringField
Nie sú to vlastne chyby vo FireDAC? Veď by to malo všetko fungovať..
K tomu bodu A.
TBcd.Implicit. Pokúšam sa o record helper for TBcd
Lenže chyba: E2123 PROCEDURE, FUNCTION, PROPERTY, or VAR expected
Teda neviem ako modifikovať class operator Implicit
Je to v Data.FmtBcd
No mne sa zdá, že tu boli prezentované štandardné metódy. Tie fungujú napr. pre US nastavenie určite bez problémov. Lenže programovací nástroj by mal rešpektovať aj národné nastavenia.Nie sú to vlastne chyby vo FireDAC? Veď by to malo všetko fungovať..
Nerekl bych. Pro tak presne hodnoty potrebujes pro SQLite sloupec s affinity TEXT.
No mne sa zdá, že tu boli prezentované štandardné metódy. Tie fungujú napr. pre US nastavenie určite bez problémov. Lenže programovací nástroj by mal rešpektovať aj národné nastavenia.
Alebo by mal umožniť pomocou prítomných parametrov situáciu vyriešiť.
Ak by aj všetko ostatné fungovalo len pre US, tak ani Unicode nie je treba .. Obrazne povedané.
A kto tam strká tú čiarku? Nikto iný než systém. Nie užívateľ. Ani SQLite nie. Neviem prečo si BCD berie niečo zo systému, ak mu to prekáža. BCD je vlastne riešené v Data.FmtBcd, takže nie FireDAC, ale Delphi spôsobuje tieto ťažkosti.
Samozrejme aj pri Double je presne ten istý problém, ale ten sa darí niekde po ceste zakryť, na rozdiel od BCD.