Databáze > Ostatní DB
SQLite: TFDSQLiteFunction využitie parametra Aggregated
99529:
A mozna by se i sluselo rozsirit udalost OnFinalize o rozvinuti property Output, tedy s prototypem (na to uz je ale nejspis kvuli zpetne kompatibilite pozde):
--- Kód: Delphi ---procedure (AFunc: TSQLiteFunctionInstance; AOutput: TSQLiteOutput; var AUserData: TObject)
On totiz ten finalizacni callback slouzi k predani vysledku (a uvolneni uzivatelskych dat), coz by prave rozvinutim property Output uzivatele vizualne pobidlo k predani hodnoty. Neni to vsak prekazkou. Jak uz jsem psal, hodnota se da predat i zapisem:
--- Kód: Delphi ---AFunc.Output.AsWideString := sRslt;
Pro to je vsak treba opravit FireDAC.
miroB:
--- Citace: Delfin 28-03-2018, 19:07:23 ---Hm. Zvlastni. SQLite vola ten finalizacni callback s jinym kontextem (sqlite3_context). Tohle je nicmene chyba FireDAC. Ve zkratce, parametr context je v nasledujicich metodach pro agregacni funkce ruzny, no a protoze FireDAC ignoruje jeho predani, nemuzes tak vratit pri finalizaci hodnotu:
..
Rychla oprava by mohla byt napr. (modul FireDAC.Phys.SQLiteWrapper):
--- Kód: Delphi ---procedure TSQLiteFunctionInstance.DoFinalize(context: psqlite3_context);begin FOutput.Handle := context; // je treba uchovat kontext, jinak nebude mozne vratit hodnotu Func.DoFinalize(Self);end;
--- Konce citace ---
Skvelé.. Doplnil som do FireDAC.Phys.SQLiteWrapper riadok 3 z tvojho kódu. A šlape to:)
Teraz už budú agregačné UDF funkcie fungovať. Je zaujímavé, že ani google o využívaní UDF SQLite / TFDSQLiteFunction s nastaveným parametrom Aggregate nepíše úplne nič..
Samozrejme tým pádom ani návody FireDAC/Embarcadero.
Ďakujem.
miroB:
--- Citace: Delfin 28-03-2018, 19:13:47 ---..
On totiz ten finalizacni callback slouzi k predani vysledku (a uvolneni uzivatelskych dat), coz by prave rozvinutim property Output uzivatele vizualne pobidlo k predani hodnoty. Neni to vsak prekazkou. Jak uz jsem psal, hodnota se da predat i zapisem:
--- Kód: Delphi ---AFunc.Output.AsWideString := sRslt;..
--- Konce citace ---
Práveže, toto som skúšal tiež, lenže to nefungovalo, tak som skúšal kadečo. Stratil som s tým teda ozaj dosť času. Uff..
Ale ten tvoj návrh na doplnenie handleru, ten to teda vyriešil..
99532:
Neni zac! ;) Tady je report RSP-20227.
miroB:
Trochu problém, toto riešenie funguje len pre jednu inštanciu funkcie v rámci SQL.
Viacnásobné požitie tej iste funkcie v SQL vyššie uvedeným spôsobom nefunguje :
--- Kód: MySQL ---SELECT MojTotal(pole1), MojTotal(pole2) FROM xyPre funkcie, ktoré nie sú aggregate, by sa dalo využiť tvoje: AOutput.Handle + Dictionary.
Jednoduchým skombinovaním dvoch riešení to nejde.
Link na tvoj príspevok, kde navrhuješ postup pre viac inštancií jednej funkcie:
--- Citace: Delfin 12-03-2018, 09:14:13 ---
--- Konce citace ---
Lenže nové Output.Handle už neumožní vyhľadanie hodnoty v Dictionary, pretože sa zmeni riešením pre Aggregate.
Bijú sa tieto dva čiastkové kódy:
--- Kód: Delphi ---if not FResults.TryGetValue(AOutput.Handle, Value) then Value := AInputs[0].AsInteger else Value := Value + AInputs[0].AsInteger; FResults.AddOrSetValue(AOutput.Handle, Value);V rámci opravy Finalize, sa priradí iný handle, než je v Dictionary:
--- Kód: Delphi ---procedure TSQLiteFunctionInstance.DoFinalize(context: psqlite3_context);begin FOutput.Handle := context; // je treba uchovat kontext, jinak nebude mozne vratit hodnotu Func.DoFinalize(Self);end;[/quote]
Musel som použiť ešte ďalšiu property FHandleOld, pre zachovanie FHandle. Potom to už funguje.
Navigace
[0] Seznam témat
[#] Další strana
[*] Předchozí strana
Přejít na plnou verzi