Autor Téma: SQLite BUG ?: SELECT Alias FROM ( Select Field1 Alias::<T> FROM Table)  (Přečteno 1107 krát)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Toto funguje (vráti pole x) :
Kód: MySQL [Vybrat]
  1. SELECT * FROM ( select datum AS [x::DATE] from demo )
Príkaz v zmysle predošlého, s istotou obsahuje pole x, takže by nemal byť problém, ale skončí s chybou:
[FireDAC].[Phys].[SQLite] ERROR: no such column: x
Kód: MySQL [Vybrat]
  1. SELECT x FROM ( select datum AS [x::DATE] from demo )
Test projekt je priložený

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Pouzij uvozovky, jde o alias:

Kód: MySQL [Vybrat]
  1. SELECT "x" FROM ( select datum AS [x::DATE] from demo )
Kód: MySQL [Vybrat]
  1. SELECT "uvozovky jsou treba, protoze pro alias lze napsat i kratkou pohadku" FROM ( select datum AS [uvozovky jsou treba, protoze pro alias lze napsat i kratkou pohadku::DATE] from demo )
« Poslední změna: 26-11-2017, 22:21:08 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Tak som to skusil cez Create View
A veru nejde ani to.
Ospravedlnujem sa, ze je tam kdesi vidiet kod mysql. To je len formatovaci oznam.
Pracujem v SQLite
Kód: MySQL [Vybrat]
  1. CREATE TABLE if not exists [demo] ( id Integer, name TEXT( 20 ), Datum DateTime );
  2. INSERT INTO [demo] ( id, name, Datum ) VALUES ( 1, ''Skúška'', GETDATE() );
  3. CREATE VIEW if not exists AliasT AS select id, datum AS [x::DATE] from demo;

ale ani takto to nefunguje:
Kód: MySQL [Vybrat]
  1. SELECT x FROM AliasT
ani takto to nefunguje (A to by snad uz malo fungovat. Alebo ?):
Kód: MySQL [Vybrat]
  1. SELECT [x] FROM AliasT
toto tusim vypisuje iba string x :
Kód: MySQL [Vybrat]
  1. SELECT "x" FROM AliasT

Pritom toto ide a pole x tam je..
Kód: MySQL [Vybrat]
  1. SELECT * FROM AliasT
Mam to overene aj cez
Kód: Delphi [Vybrat]
  1. FDQuery1.Fields[ 1 ].FieldName

Delfin sorry, ale Tvoj navrh mi vypise iba "x", miesto datumu.
Mam skusenost so zapisom:
Kód: MySQL [Vybrat]
Ale aj v tomto pripade hlasi chybu.
Horsi je ten SELECT VIEW, co je hore. Ten by teda veru ist mal..
Pouzij uvozovky, jde o alias:

Kód: MySQL [Vybrat]
  1. SELECT "x" FROM ( select datum AS [x::DATE] from demo )
Kód: MySQL [Vybrat]
  1. SELECT "uvozovky jsou treba, protoze pro alias lze napsat i kratkou pohadku" FROM ( select datum AS [uvozovky jsou treba, protoze pro alias lze napsat i kratkou pohadku::DATE] from demo )

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Pravda; mel bych si napred zkusit nez odpovim ::) Ano, hodnoty uvnitr uvozovek jsou brany za konstantni. Omlouvam se!

Ohledne view; ten hint pro alias ::<T> je interni vec FireDAC pouzita pri sestavovani datasetu prikazu ktery nejaky vraci.

Nema tedy zadny vyznam pro CREATE VIEW. Sloupec tak ve skutecnosti dostane pro view z pohledu SQLite alias [x::DATE]. No a kdyz pak na nem spoustis dotaz na sloupec s nazvem x, koncis na chybe protoze o x SQLite nema tuseni. Pokud vsak spustis SELECT * FROM AliasT, SQLite vrati sloupce vsechny vcetne toho s aliasem [x::DATE], ktery pak shodou okolnosti FireDAC rozparsuje na nazev a hint datoveho typu pri sestavovani datasetu.

Dotaz jako je tento by Te k tomu sloupci dostal (a i tady by doslo k parsovani nazvu sloupce a pouziti datoveho hintu):

Kód: MySQL [Vybrat]
  1. SELECT [x::DATE] FROM AliasT

To same plati i pro uvodni dotaz; k parsovani nazvu sloupce dojde az na strane klienta pri sestavovani datasetu. SQLite povazuje i tam pri spousteni dotazu alias za celek, tj. [x::DATE]. Slo by leda:

Kód: MySQL [Vybrat]
  1. SELECT [x::DATE] FROM ( select datum AS [x::DATE] from demo )
« Poslední změna: 26-11-2017, 23:23:52 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Aha, tomu rozumiem, co pises.
Ale v zasade myslim, ze ide o chybu.
Vid aj
CREATE VIEW v predoslom prispevku a
CREATE TEMPORARY TABLE v tomto prispevku nizsie.
Pretoze, ako uzivatel, chcem aby veci fungovali ocakavane.
Ked autori ponuknu riesenie, nemaju skoncit v polovici (myslim autorov FireDAC)
Bohuzial vsetky veci okolo funkcii, ktore nevracaju typ, ale tvaria sa, ze by to malo nejako ist, je dost komplikovane. Dnes som to hodne studoval, robil testy, ved asi vies. Nemam teraz este kompletne informacie. Pokracujem v testoch. Vratim sa k tomu, az budem mat jasnejsie.
Inak aspon cez to create view, by clovek cakal, ze s typmi nejako lepsie vysporiadaju.
CREATE VIEW vrati spravny typ, ale nevie v SQL menom zavolat to predmetne alias::<T> pole.
Da sa otvorit len pomocou *    (v zmysle vsetky polia)
Vid moj predosly prispevok

Inak test CREATE TEMPORARY TABLE dopadol  presne s rovnako nepriaznivym vysledkom, ako CREATE VIEW.
Pole vytvorene metodou alias::<T> nie je mozne nasledne v selecte zavolat.
Znovu len ako
SELECT * FROM myTempTable

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Kód: MySQL [Vybrat]
  1. CREATE TABLE if not exists [demo] ( id Integer, txtTest TEXT( 20 ), Datum DateTime;
  2. INSERT INTO [demo] ( id, txtTest, Datum ) VALUES ( 1, ''Skúška'', GETDATE() )
  3. CREATE TEMPORARY TABLE tempTbl AS select id, txtTest AS [myText::Text(20)], datum AS [myDateTime::DATE] from demo
Veru Delfin mas pravdu, ide to zavolat len takto:
Kód: Delphi [Vybrat]
  1. SELECT id, [myText::Text(20)], [myDateTime::DATE] FROM tempTbl
Cakal by som ze nazvy stlpcov v tomto pripade skratia o to "::<T>"
Moc by to pomohlo.
Snad si to spravim sam.
Ale potom aku mam istotu, ze tam niekde dalej, nie je milion inych chytakov?

Davam este na povsimnutie tento zadrhel:
Ako vidiet tabulka obsahuje aj pole typu text :  txtTest Text(20)
Po ulozeni do Temporary table sa vsak pole zmeni na Text(32000), nejak tak, plus minus.
Takze aj tam, kde nie je pole vypocitane, ale dalo by sa prevziat z povodnej struktury tabulky sa stane text neznamej dlzky. A neda sa zobrazit  v gride. No viem da sa to naprogramovat. Ale na toto veru nie som z Access enginy celkom zvyknuty. Tam to je dost hladsie..
Takze aj s textom nastavaju presne tie neiste hratky, ako je to u datumov.. Grrr..

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Inak test CREATE TEMPORARY TABLE dopadol  presne s rovnako nepriaznivym vysledkom, ako CREATE VIEW.
Pole vytvorene metodou alias::<T> nie je mozne nasledne v selecte zavolat.
Znovu len ako
SELECT * FROM myTempTable

Jiste ze nejde. Asi jsem se vsak spatne vyjadril. Staci si v hlave oddelit prikazy spoustene na SQLite engine od deskriptoru sloupcu datasetu ktery FireDAC dostane jako popis vysledku spusteneho prikazu (a podle kterych pak sestavuje kolekci poli). Tedy prikaz jako napr. tento:

Kód: MySQL [Vybrat]
  1. SELECT x FROM (SELECT MyColumn AS [x::DATE] FROM MyTable)

se spusti na SQLite tak jak je; a SQLite cte prikaz jako "vyber hodnoty sloupce MyColumn vsech zaznamu tabulky MyTable a pro dataset je pojmenuj aliasem [x::DATE]; z tohoto datasetu pak vyber hodnoty sloupce x vsech zaznamu". A protoze zadne x v tom vnitrnim datasetu neni (je tam [x::DATE]), prikaz skonci chybou.

Ten ::<T> hint aliasu se zpracovava az s deskriptorem datasetu, prikaz se tedy na SQLite spousti vcetne datovych hintu.

A jestli je to chyba, hm, tezko posoudit... Ty datove hinty mely byt jen pro vyrazy v SELECT listu - ze je tim myslen vnejsi uz v popisu neni. Muselo by se navic sahat pred spustenim do prikazu a hinty z nej vyparsovat. Jeden by si pak mohl chybne vylozit pouziti tech hintu s funkci jako napr. CONVERT a mohl by pak ocekavat v komplexnich prikazech striktni datove typy za pomoci prave tech hintu.
« Poslední změna: 27-11-2017, 00:32:07 od Delfin »
I'm a soldier, so don't panic!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Davam este na povsimnutie tento zadrhel:
Ako vidiet tabulka obsahuje aj pole typu text :  txtTest Text(20)
Po ulozeni do Temporary table sa vsak pole zmeni na Text(32000), nejak tak, plus minus.
Takze aj tam, kde nie je pole vypocitane, ale dalo by sa prevziat z povodnej struktury tabulky sa stane text neznamej dlzky. A neda sa zobrazit  v gride. No viem da sa to naprogramovat. Ale na toto veru nie som z Access enginy celkom zvyknuty. Tam to je dost hladsie..
Takze aj s textom nastavaju presne tie neiste hratky, ako je to u datumov.. Grrr..

Pro textove retezce ma SQLite datovy typ TEXT. Vse ostatni je bonus FireDACu. Zase, zkus se podivat jestli jsi toho nenechal moc v rezii SQLite.
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
No a uplne vtipne je toto zistenie:
SELECT z CREATE VIEW, presnejsie tento:
Kód: MySQL [Vybrat]
  1. SELECT * FROM AliasT
v tomto prikaz v Delphi kode:
Kód: Delphi [Vybrat]
  1. s := FDQuery1.Fields[ 1 ].FieldName
naplni do premennej s, hodnotu x
Ale SELECT tam tu hodnotu nevidi!
Ten vidi skutocny, dlhy nazov pola v tabulke:
[x::DATE]
Tak to povazujem za ozaj dost zlomyselne od autorov.

Chapem, ako je to technicky. Ozaj tak, ako pise Delfin, ale nechapem, ako moze programator (autori FireDAC) ponukat taketo riesenie.
Z pohladu na jednu a tu istu vec, by som mal ako z SQL, tak na druhej strane z pohladu v Delphi
Kód: Delphi [Vybrat]
  1. FDQuery1.Fields[ 1 ]
ziskat tem isty vysledok.
Ale nie: raz je to
[x::DATE]
a druhy raz iba
x

Uff mozno to je technicko-abstraktne-logicky v poriadku, lenze sme skor ludia nez stroje.
Potom jasne, ze IT oddelenie sa len tazko moze dohodnut s marketingom.
Ked jedni ziju v praktickom a druhi v abstraktnom svete.
Ti jedni maju realne peniaze a ti druhi skor abstrakne:)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Ano bonus FireDAC to je.
Lenze a la Microsoft (Gates), nie a la Apple (Jobs)  :)

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
No a uplne vtipne je toto zistenie:
SELECT z CREATE VIEW, presnejsie tento:
Kód: MySQL [Vybrat]
  1. SELECT * FROM AliasT
v tomto prikaz v Delphi kode:
Kód: Delphi [Vybrat]
  1. s := FDQuery1.Fields[ 1 ].FieldName
naplni do premennej s, hodnotu x
Ale SELECT tam tu hodnotu nevidi!
Ten vidi skutocny, dlhy nazov pola v tabulke:
[x::DATE]
Tak to povazujem za ozaj dost zlomyselne od autorov.

Proc zlomyslne? Hinty pouzivej ve vnejsim SELECT listu prikazu ktere vraceji dataset; nikde jinde! Co se deje je to, ze do SQLite ulozis definici view kde je psano:

Kód: MySQL [Vybrat]
  1. CREATE VIEW if not exists AliasT AS select id, datum AS [x::DATE] from demo;

SQLite cte, "pokud neexistuje, vyrob pohled AliasT na tabulku demo ze sloupcu id a datum, kde datum bude mit alias [x::DATE] (ne x, protoze FireDAC prikaz neupravuje!)". Ty pak spoustis:

Kód: MySQL [Vybrat]
  1. SELECT x FROM AliasT

SQLite cte, "prines mi vsechny zaznamy pro sloupec x pohledu AliasT". Zadny takovy sloupec vsak SQLite nezna. V definici ma [x::DATE]. Pak zkusis:

Kód: MySQL [Vybrat]
  1. SELECT * FROM AliasT

SQLite cte, "prines mi vsechny zaznamy vsech sloupcu (na nazvech mi nezalezi)". Prikaz se spustit podari a FireDAC si od SQLite vyzada popis datasetu. Najde v nem nazev sloupce [x::DATE], ten si rozparsuje a sloupec nazve jako x s datovym typem ftDate. Zadna veda ;D

A konecne, viz. reference:

Citace
For an expression in a SELECT list, SQLite avoids type name information. When the result set is not empty, FireDAC uses the value data types from the first record. When empty, FireDAC describes those columns as dtWideString. To explicitly specify the column data type, append ::<type name> to the column alias:

Kód: MySQL [Vybrat]
  1. SELECT count(*) as "cnt::INT" FROM mytab

Kde SELECT list je definovan jako sloupce resultsetu prikazu SELECT.
« Poslední změna: 27-11-2017, 00:49:29 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
No, ak by sme sa pozreli hlbsie na FireDAC a jeho parsovanie SQL, tak by sme tam nasli take veci, ze hlada zatvorku v obecnom poli "vyraz AS xy::Date", kde vyraz moze byt hocico napriklad toto:
Kód: MySQL [Vybrat]
  1. "ja som text so zatvorkou (, prave bola, ukoncenie)" || GetDATE() || " a este ( dalsie ) zatvorky tu mozu byt" AS mojText::Text(32)
No a ktoru zatvorku asi najde prvu?
Je tam jesne pouzite
Kód: Delphi [Vybrat]
  1. ..Pos( '(', text ) ..

To mi pripada hodne dobrodruzne parsovanie. To riesenie, co ponukaju je z mojho pohladu dost alibisticke.
Potrebujem SQL realne vyuzit. Pomerne v obecnej rovine. A tam veru narazam na necakane mantinely u toho FireDAC riesenia.
Ano v teoretickej rovine je vsetko ako vravis. Lenze rad by som ziskal vysledky. A zacinam narazat na znacne prakticke problemy, kde moznosti FireDAC v tomto pripade nevedu k rieseniu.
Mam rozpracovany Tvoj i svoj navrh riesenia prenosu informacie zo vzorca do vysledku, ale zatial som nedosiahol ziadne uspokojive a jasne vysledky.
Nieze by to neslo. Ono to ide podla planu, ale ani to nestaci pre dokoncenie praktickej myslienky. Zatial.. Budem sa snazit dalej..

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Mam rozpracovany Tvoj i svoj navrh riesenia prenosu informacie zo vzorca do vysledku, ale zatial som nedosiahol ziadne uspokojive a jasne vysledky.
Nieze by to neslo. Ono to ide podla planu, ale ani to nestaci pre dokoncenie praktickej myslienky. Zatial.. Budem sa snazit dalej..

Porad si muzes parsovat prikazy sam. A pro resultset si pred otevrenim sestavit kolekci perzistentnich poli. A ty datove hinty, pokud bys je potreboval pouzit z prikazu odstranovat. Verim ze lexeru pro SQLite budou mraky (mozna i pro Delphi) ;)
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Porad si muzes parsovat prikazy sam. A pro resultset si pred otevrenim sestavit kolekci perzistentnich poli. A ty datove hinty, pokud bys je potreboval pouzit z prikazu odstranovat. Verim ze lexeru pro SQLite budou mraky (mozna i pro Delphi) ;)
Dobre, ak by som išiel touto cestou. Teda nejaký low-level API. Myslím toto:
http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Using_SQLite_with_FireDAC#Using_SQLite_low-level_API
tak ako budem prezentovať dáta? Napríklad do dbGrid.
Môžeš mi naznačiť ako ďalej pokračovať, keď by som to riešil napr. takto:
(vybraté z uvedeného dokazu)
Kód: Delphi [Vybrat]
  1.     oStmt := TSQLiteStatement.Create(oDB);
  2.     try     // prepare statement
  3.       oStmt.Prepare('select * from "Orders" where OrderID > :ID1 and OrderID < :ID2');
  4.              // add bind variables (parameters)
  5.       for i := 1 to oStmt.ParamDefsCount do
  6.         TSQLiteBind.Create(oStmt.Params);
  7.              // add column variables (fields)
  8.       for i := 1 to oStmt.ColumnDefsCount do
  9.         TSQLiteColumn.Create(oStmt.Columns).Index := i - 1;
  10.              // set parameter values and execute
  11.       oStmt.Params[0].AsInteger := 11000;
  12.       oStmt.Params[1].AsInteger := 12000;
  13.       oStmt.Execute;
  14.              // fetch records and read columns
  15.       while oStmt.Fetch do
  16.         Memo1.Lines.Add(Format('OrderID: %d, CustomerID: %s',
  17.           [oStmt.Columns[0].AsInteger, oStmt.Columns[1].AsString]));
  18.     finally
  19.       oStmt.Free;
  20.     end;
ako nasypem údaje do nejakého dataSetu namiesto toho Memo1, čo je použité vyššie?
Ak sa tu niekto podelí so skúsenosťami s uvedenej oblasti, bol by som veľmi vďačný.
Poznatky, upozornenia, zdroje, vzory kódov, výstrahy, čokoľvek.
Pre získanie predstavy, či by bola schodná táto cesta.
Takže vopred ďakujem:)

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Hura, jeden existujuci priklad vyuzitia TSQLiteStatement, som nasiel na disku:)
FireDAC.Phys.SQLiteIniFile.pas v ceste:
Kód: Delphi [Vybrat]
  1. Database\FireDAC\Samples\AddOn\SQLiteIniFile\
Je tam funkcne demo.
Ale inak bieda, ziadna dalsia slusna dokumentacia, ci priklady. Ani googlenie nepomohlo.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
To API neni pro prime pouziti. Nic Ti v jeho pouziti nebrani, jen se nediv chybejici dokumentaci. Tzv. "low level" je z pohledu FireDAC o vrstu vys (tam uz se sdruzuji podporovane DBMS).

Ale ja nepsal nic o low level API. Tohle muzes udelat i "zvenku". Pred predanim prikazu FireDAC objektu prikaz rozparsujes, poskladas si perzistentni pole, predas upraveny dotaz a ten spustis.

FireDAC spousteny prikaz upravuje jen v pripade pouziti maker, takze neni treba chodit tak hluboko do nitra ;)
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Ahoj delfin,
nakoniec som postnul tuto zakladnu temu aj na forum Embarcadero.
https://forums.embarcadero.com/thread.jspa?threadID=269003
Moja angličtina môže byť nezrozumiteľná, ale je tam jasný funkčný príklad.
Ten dávam aj sem.
V skratke: tvrdím, že alias::<T>, OK.
Lenže očakávam od neho len ten typecast výsledku, ale určite nie rozšírený názov poľa.
Predstav si viac vnorených SELECT príkazov. Čo s tým strašným chaosom, ktorý by tak vznikol veľmi rýchlo?
Že to nikoho nezaujíma? Ale malo by. Potom by sa tá celá engina používala omnoho produktívnejšie.
Takto sa to používa málo. A je to ozaj problém.
Hmm, teraz ma napadlo, že keby fungovala poriadne funkcia CAST, tak by som mohol dať normálny Alias a nie ten technokratický :)
Lenže funkcia CAST sa chová ako všetky funkcie vo FireDAC/SQLite. Že nevracia správny typ, ale len ten základný. Takže v SQLite asi ani nemá moc nejaký význam..

Veď aj FireDAC nakoniec interne priznáva, že meno výsledného poľa v skutočnosti nie je to rozšírené, ale to, čo je pred ::<T>
Mám na mysli Field_x_.FieldName
Tak uvidíme, či tam niekto ponúkne riešenie.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2005
  • Karma: 103
    • Verze Delphi: D2007, XE3, DX10
nakoniec som postnul tuto zakladnu temu aj na forum Embarcadero.
Sice jsou cross posty neeticke, ale ja na tvem miste bych to postnul radeji SO - prece jenom tam to auditorium je asi nejvetsi a autor FireDac pred lety sam diskutovaval...

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
nakoniec som postnul tuto zakladnu temu aj na forum Embarcadero.
Sice jsou cross posty neeticke, ale ja na tvem miste bych to postnul radeji SO - prece jenom tam to auditorium je asi nejvetsi a autor FireDac pred lety sam diskutovaval...
Dik, skusím aj to asi.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Muzu Ti odpovedet tady i na EMBT (i na SO, pokud si jeste vzpomenu na login; dlouho jsem tam nebyl), jestli chces ;D

Je to by design. Datove hinty jsou implementovany jen na urovni vnejsiho SELECT listu.

Ohledne view; SQLite si napamatuje (a pamatovat nebude) definici VIEW jinak nez nejakym naznakem pres nazev sloupce. A pokud jej ulozis s hintem, s hintem se na nej musis v SELECT listu obracet, protoze jde o prikaz spousteny na SQLite engine. FireDAC nijak nedonuti SQLite aby si definici VIEW ulozil separatne jako nazev sloupce a datovy typ ktery ten engine ani nezna (i kdyby znal stejne s tim nic nezmuze). Jak by FireDAC podle Tebe mel pretransformovat prikaz pro vytvoreni VIEW tak aby SQLite pochopil ze jde o nazev a datovy typ? Jinymi slovy (kdyz si odmyslis FireDAC), jak chces na SQLite vytvorit VIEW s takovou definici?

To by byl dotaz na predelani SQLite, ne FireDAC.
« Poslední změna: 27-11-2017, 17:51:17 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Delfin, tak ja neviem, nejak tusim, ze mas pravdu. Ale nechcem sa s tym celkom zmierit, pretoze to jednoducho potrebujem.
Ked veci potrebujem, tak sa moc nestaram, ze by nemali ist. Spravim vsetko pre to, aby isli, aby isli lepsie, tak ako potrebujem. Nech maju nejaky zmysel. Spravidla to rovnako potrebuju aj ostatni. Iba sa nikto neozve.
V tom SQLite/FireDAC je uz tak vela spraveneho a zrazu, bac.
Na jednom promile sa ma zastavit cele kvalitne riesnie?
Tak som to postnul na SO. Znacne som to upravil, takze sa to na prvy pohlad moc nepodoba. Muselo sa to zaobist bez vzoroveho kodu ale nastrkal som tam toho dost. Mozno sa toho niekto uchopi.
Mozno to zmazu, je to jedno. Mam ine starosti nez aby som sa obzeral, ako dopadne hodnotenie:)
Tu je link:
https://stackoverflow.com/questions/47517284/firedac-sqlite-typecast-with-as-fldtype-in-nested-queries-functions-how-t

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Fajn ze se nevzdavas :) Jen mam vazne obavu ze toho moc nevyresis. Muzes jeste jit cestou toho parsovani a hinty z vnitrnich SELECT listu u SQL prikazu pred spustenim vyhazet. U definice VIEW asi holt smula; tam by musel SQLite nejako podporovat definici nazvu a datovych typu.

Staci si jen predstavit co se deje na ktere strane. V tomto pripade se prikazy spousti na SQLite engine, a produktem uspesneho spusteni je popis datasetu ze ktereho muze FireDAC pomoci datovych hintu specifikovat pole v kolekci "na prani".
« Poslední změna: 27-11-2017, 20:21:26 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Fajn ze se nevzdavas :) Jen mam vazne obavu ze toho moc nevyresis. Muzes jeste jit cestou toho parsovani a hinty z vnitrnich SELECT listu u SQL prikazu pred spustenim vyhazet. U definice VIEW asi holt smula; tam by musel SQLite nejako podporovat definici nazvu a datovych typu.

Staci si jen predstavit co se deje na ktere strane. V tomto pripade se prikazy spousti na SQLite engine, a produktem uspesneho spusteni je popis datasetu ze ktereho muze FireDAC pomoci datovych hintu specifikovat pole v kolekci "na prani".
Aha, tak to znamená, že "fld::type" sa musí strčiť celé do SQLite enginy, aby sa zas až pri výstupe dal dešifrovať typ pre prezentáciu dát?
No a mimochdom UDF funkcie nie su tie prišité aj vrátane definície práve do enginy?
A nemôžu teda prenášať žiadnu informáciu, keď sú k engine nejak prilinkované?
Nechce sa mi veriť, že toto je neriešiteľný problém.
Voči tomu, čo je v oboch balíkoch už naprogramované.

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
To API neni pro prime pouziti. Nic Ti v jeho pouziti nebrani, jen se nediv chybejici dokumentaci. Tzv. "low level" je z pohledu FireDAC o vrstu vys (tam uz se sdruzuji podporovane DBMS).

Ale ja nepsal nic o low level API. Tohle muzes udelat i "zvenku". Pred predanim prikazu FireDAC objektu prikaz rozparsujes, poskladas si perzistentni pole, predas upraveny dotaz a ten spustis.

FireDAC spousteny prikaz upravuje jen v pripade pouziti maker, takze neni treba chodit tak hluboko do nitra ;)
Na ktorom mieste presne v kode mozem povedat, ze nechcem column definition podla FireDAC, ale podla seba.
Ako nizko musim teda ist? Ak vravis., ze nie je uplne nutne low-level.
Niekde som videl aj take odporucene riesnie, ze si pred kazdym SQL vytvoris temp table so svojou definíciou polí a tam nasypeš data zo selectu.
No a ak by som to spojil s low-level, tak som pomaly doma..

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Na ktorom mieste presne v kode mozem povedat, ze nechcem column definition podla FireDAC, ale podla seba.
Ako nizko musim teda ist? Ak vravis., ze nie je uplne nutne low-level.
Niekde som videl aj take odporucene riesnie, ze si pred kazdym SQL vytvoris temp table so svojou definíciou polí a tam nasypeš data zo selectu.
No a ak by som to spojil s low-level, tak som pomaly doma..

Naplnis jen kolekci FieldDefs. Tak jako bys to udelal v design time pres fields editor.
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Naplnis jen kolekci FieldDefs. Tak jako bys to udelal v design time pres fields editor.
Ak uvediem konkretne na priklade, tak kedy v ramci tohoto?
Kód: MySQL [Vybrat]
  1.   FDQuery1.SQL.Text := 'SELECT * FROM [myView]';                  
  2.   FDQuery1.Active   := True;
Pred riadkom 1, 2, alebo az na konci.
Zatial som to nikdy neriesil.
Design time pri databazach nepouzivam snad nikdy. Takze to mi tiez moc nehovori.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Design time pri databazach nepouzivam snad nikdy. Takze to mi tiez moc nehovori.

Taky ne. Musi to byt pred otevrenim kurzoru (radek 2.). Snad i pred definici prikazu by se dalo (pokud se ta definice se zmenou prikazu nemaze). Muzu zkusit...
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Naplnis jen kolekci FieldDefs. Tak jako bys to udelal v design time pres fields editor.
Ak uvediem konkretne na priklade, tak kedy v ramci tohoto?
Kód: MySQL [Vybrat]
  1.   FDQuery1.SQL.Text := 'SELECT * FROM [myView]';                  
  2.   FDQuery1.Active   := True;
Pred riadkom 1, 2, alebo az na konci.
Zatial som to nikdy neriesil.
Design time pri databazach nepouzivam snad nikdy. Takze to mi tiez moc nehovori.

iiha, to bolo jednoduche. Takze sa blizim k rieseniu.
Opravujem opravene :)
Bolo to jednoduche, ale unahlil som sa so svojim prispevkom, ten som zmazal a davam spravne zenenie kodu:
Kód: Delphi [Vybrat]
  1. FDQuery1.SQL.Text := 'SELECT * FROM ( select [id], [datum] AS [myDate::DATE] from [demo] )';
  2. FDQuery1.Active   := True;
  3. i := FDQuery1.FieldDefs.Count; // 2
  4. FDQuery1.FieldDefs.Clear;
  5. i := FDQuery1.FieldDefs.Count; // 0
  6. FDQuery1.FieldDefs.Add( 'id', ftSmallInt, 0 );
  7. FDQuery1.FieldDefs.Add( 'datum', ftDate, 0 );
  8. i := FDQuery1.FieldDefs.Count; // 2
  9.  
Kod som doplnil do toho, co som publikoval na embarcadero. Takze keby niekto chcel vyskusat. Ma aj cely kod.
Len toto bolo "vylepsene", co je uvedene tuna som teda pozmenil

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
BUU.......
POZOR. IBA SA TVARI, ze ide. Vytvorim novu definiciu poli, aj vratane typu.
Zda sa, ze prebehne OK. Ale typ sa nepodari zmenit.
Testujem podrobnejsie a nejde to. Prispevok uz neviem zmazat, ale dam opravu, ked budem vediet, ako dalej pokracovat.

Naplnis jen kolekci FieldDefs. Tak jako bys to udelal v design time pres fields editor.
Ak uvediem konkretne na priklade, tak kedy v ramci tohoto?
Kód: MySQL [Vybrat]
  1.   FDQuery1.SQL.Text := 'SELECT * FROM [myView]';                  
  2.   FDQuery1.Active   := True;
Pred riadkom 1, 2, alebo az na konci.
Zatial som to nikdy neriesil.
Design time pri databazach nepouzivam snad nikdy. Takze to mi tiez moc nehovori.

iiha, to bolo jednoduche. Takze sa blizim k rieseniu.
Opravujem opravene :)
Bolo to jednoduche, ale unahlil som sa so svojim prispevkom, ten som zmazal a davam spravne zenenie kodu:
Kód: Delphi [Vybrat]
  1. FDQuery1.SQL.Text := 'SELECT * FROM ( select [id], [datum] AS [myDate::DATE] from [demo] )';
  2. FDQuery1.Active   := True;
  3. i := FDQuery1.FieldDefs.Count; // 2
  4. FDQuery1.FieldDefs.Clear;
  5. i := FDQuery1.FieldDefs.Count; // 0
  6. FDQuery1.FieldDefs.Add( 'id', ftSmallInt, 0 );
  7. FDQuery1.FieldDefs.Add( 'datum', ftDate, 0 );
  8. i := FDQuery1.FieldDefs.Count; // 2
  9.  
Kod som doplnil do toho, co som publikoval na embarcadero. Takze keby niekto chcel vyskusat. Ma aj cely kod.
Len toto bolo "vylepsene", co je uvedene tuna som teda pozmenil

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
BUU.......
POZOR. IBA SA TVARI, ze ide. Vytvorim novu definiciu poli, aj vratane typu.
Zda sa, ze prebehne OK. Ale typ sa nepodari zmenit.

Vsak ony se nemaji menit. Od toho jde o definice :) Jimi proklamujes ze vis jaka je definice sloupcu datasetu. Proto jsem psal ze muzes naparsovat SQL prikaz, z datovych hintu vnejsiho SELECT listu sestavit kolekci definici a datove hinty vnitrnich prikazu odstranit.

No, a pak jsem psal ze ty definice je treba vytvorit pred otevrenim kurzoru (v puvodnim kodu se kurzor otevira na radku 2.); tj. pred nastavenim Active na True (nebo volanim Open).
« Poslední změna: 27-11-2017, 23:17:17 od Delfin »
I'm a soldier, so don't panic!

Offline Miroslav Baláž

  • Plnoletý
  • ***
  • Příspěvků: 124
  • Karma: 4
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
BUU.......
POZOR. IBA SA TVARI, ze ide. Vytvorim novu definiciu poli, aj vratane typu.
Zda sa, ze prebehne OK. Ale typ sa nepodari zmenit.
..
No, a pak jsem psal ze ty definice je treba vytvorit pred otevrenim kurzoru (v puvodnim kodu se kurzor otevira na radku 2.); tj. pred nastavenim Active na True (nebo volanim Open).
Nie typy poli v tomto pripade nejdu zmenit. Ani pred, ani po.
V rpípade pred, otvorenie FDQuery ich premaze. NEPOMOZE.
Ked su po, tak sa mozem hrat, ze ich prepisem, aj zmazem, a znovu vytvorim. To sa zda, ze ide. Aj pocet  v Count sa zmeni, ale po vytvoreni su tam zase tie typy, co predtym.

Ale hrajem sa s Low Level API: TSQLiteDatabase a TSQLiteStatement.
Tam viem ziskat udaje bez toho, ze by bol naplneny dataset.
Ten mozem slobodne sam vytvorit a naplnit ho.
Co mi odporucas, mam pouzit TFDMemTable, alebo by na to bolo nieco vhodnejsie?

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 610
  • Karma: 27
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Nie typy poli v tomto pripade nejdu zmenit. Ani pred, ani po.
V rpípade pred, otvorenie FDQuery ich premaze. NEPOMOZE.
Ked su po, tak sa mozem hrat, ze ich prepisem, aj zmazem, a znovu vytvorim. To sa zda, ze ide. Aj pocet  v Count sa zmeni, ale po vytvoreni su tam zase tie typy, co predtym.

Ale hrajem sa s Low Level API: TSQLiteDatabase a TSQLiteStatement.
Tam viem ziskat udaje bez toho, ze by bol naplneny dataset.
Ten mozem slobodne sam vytvorit a naplnit ho.
Co mi odporucas, mam pouzit TFDMemTable, alebo by na to bolo nieco vhodnejsie?

Premaze? Mohl bych videt minimalni, kompilovatelnou ukazku? Jestli se zase neprepisuje v konkretnim pripade SQLite DBMS datovych hintu...

Jinak ano, muzes pouzit TFDMemTable. Jen jako storage. S tim, ze upravy (vkladani, mazani) nebudou reflektovany. To bys musel zase zaridit rucne.
I'm a soldier, so don't panic!

 

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

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