Autor Téma: Field mapping  (Přečteno 2776 krát)

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Field mapping
« kdy: 01-10-2017, 14:01:24 »
Prosím o radu. Pro svoji rozsáhlejší aplikaci jsem se rozhodl použít FireDac, doposud vše správně fungovalo, až s použitím SQL dotazu kde jsou počítaná pole nastal problém.

Jednoduchý příklad, jak se chyba projeví:
Databáze SQLite.
Mám TFDQuery s naplněným SQL dotazem který obsahuje počítaná pole, fieldy jsou persistentní, vygenerované v IDE.
V době generování dotčené tabulky obsahovaly data a fieldy se vytvořily správně - tedy správného typu, v mém případě TFloatField.
Problém nastane když do sql dotazu přidám where kterým odfiltruji všechny záznamy - tedy prázdný recordset.
Po znovuotevření query, Firedac očekává všechny fieldy typu TWideString a skončí chybou. "Expecting: Float actual: WideString". Co s tím?

Mapping použít nemůžu, protože ten nelze aplikovat na jednotlivé fieldy.

Předem dík, za rady.

Edit: abych byl konkrétní, přikládám ještě SQL. Bez toho Where je vše ok, s ním ko.

SELECT MA.NAME,
IFNULL(SUM(DI.DOCITEM_VALUE), 0.0) AS DOCITEM_VALUE,
IFNULL(SUM(DI.DOCITEM_VALUE_BASE), 0.0) AS DOCITEM_VALUE_BASE,
IFNULL(SUM(DI.ID_DOCITEM_VALUE_UNIT), 0) AS ID_DOCITEM_VALUE_UNIT,
IFNULL(AVG(DI.PRICE), 0.0) AS AVG_PRICE 
FROM MATERIAL MA LEFT JOIN DOCITEM DI ON DI.ID_MATERIAL = MA.ID

WHERE MA.NAME = 'abcd'

GROUP BY MA.ID


« Poslední změna: 01-10-2017, 14:29:25 od J_M »

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Re:Field mapping
« Odpověď #1 kdy: 01-10-2017, 15:20:43 »
Problém snad vyřešen. Použil jsem mapping. Přes MapRule.NameMask lze nastavit konkrétní field.
Tak zatím nic :)

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Re:Field mapping
« Odpověď #2 kdy: 01-10-2017, 17:27:52 »
Ne, to jsem nebyl já, ale také jsem na to narazil:)

Typecast se mi moc nelíbí - složitý zápis selectu a taky bych musel upravit parser sql ve kterém s tím nepočítám.
Mapování fieldů je pro mě ideální. Mám totiž v paměti celou strukturu databáze včetně typů, kterou načítám z DB při spuštění aplikace.
To se pak využívá pro automatické vytvoření fieldů každého query ještě než se otevře.
Přidat mapování byla záležitost pár minut. Tedy až potom co jsem na to přišel :)

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Re:Field mapping
« Odpověď #3 kdy: 01-10-2017, 18:27:43 »
Ale to je přece v pořádku že neuhodne jaký typ tam patří, od toho to mapování je ne?
Pokud je pro dané pole SourceDataTyp = dtUnknown, přiřadím jako TargetDataType := dtSpravnyTyp a jede to.
Takhle mě to stálo pár minut a nemusím dál nic řešit.
A co třeba změna typu atributu v databázi - s typecastem bych pak musel opravovat všechny SQL dotazy.

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Re:Field mapping
« Odpověď #4 kdy: 01-10-2017, 22:45:28 »
Souhlasím, že tvoje řešení je pro SQLite správné. Ale já se snažím mít tu aplikaci pokud možno univerzální, nezávislou na konkrétní DB.

Citace
Pokud si podle nazvu sloupcu nekdo zacne mapovat nezname datove typy nechavam na svobodne volbe kazdeho

Já to přece nemapuji jen podle názvu sloupců, ale podle metadat načtených z databáze, což je ve výsledku stejné, jako bych si do SQL dotazu ručně dopisoval typy, akorát si to psaní ušetřím. ;)

Offline J_M

  • Nováček
  • *
  • Příspěvků: 28
  • Karma: 0
Re:Field mapping
« Odpověď #5 kdy: 01-10-2017, 23:55:51 »
Citace
Co se tyce nazvu, pak jsem asi nepochopil poznamku "Přes MapRule.NameMask lze nastavit konkrétní field.
Ano, to mapování mají řešené tak, že se musí použít název sloupce v aplikaci. Já ten název však získávám z sql parseru vždy před použitím query, takže nemůže dojít k žádné chybě.

Citace
pak bych jen upozornil na funkce AVG (napr. pro INTEGER datove typy muze byt FLOAT)

To je pravda, pro tyhle případy používám standardní SQL Cast a parser mi zase vrátí správný typ. Takže další specifikace typu není nutná a je to univerzálnější.