Forum Delphi.cz

Delphi => FireDAC => Téma založeno: Stanislav Hruška 01-09-2020, 12:15:55

Název: Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 12:15:55
Ak sa parametre neopakujú, tak predpokladám, že to je podľa ich výskytu v SQL.Tex. Príklad
Kód: [Vybrat]
FVstQuery.SQL.Text := 'SELECT F.IDFOCS, F.CONSCRIPTIONUMBER, F.ISACTIVE,'+
  ' F.SHORTTITLE, F.CITY, F.STREET, F.CHAIRMANNAME'+
' FROM FOCS F'+
' WHERE F.DELETED = :DELETED AND F.YEARFOUNDED <= :YEARS';
DELETED = 0 A YEARS = 1.
Opakovaný výskyt parametra. Priklad
Kód: [Vybrat]
FVstQuery.SQL.Text := 'SELECT F.IDFOCS, F.CONSCRIPTIONUMBER, F.ISACTIVE, :YEARS'+
  ' F.SHORTTITLE, F.CITY, F.STREET, F.CHAIRMANNAME'+
' FROM FOCS F'+
' WHERE F.DELETED = :DELETED AND F.YEARFOUNDED <= :YEARS';
Tu to ako bude
YEARS = 0 a DELETED = 1, alebo musím použiť
Params[0] (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 01-09-2020, 14:05:40
Zase neco carujes :-O

Parametry jsou bud pozicni nebo pojmenovane. Pozicni jsou ? a nelze je sdilet tj. kazdy ? musi mit v seznamu parametru vlastni hodnotu, pojmenovane maji prefix : a odkazujeme se na ne jmenem, ne pozici. A uvedeny zpusob parametrizace nelze v jednom SQL prikazu michat.
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 01-09-2020, 14:06:42
[0] (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
Nemuzes mit dva stejne pojmenovane parametry!!
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 16:04:16

Citace
Zase neco carujes :-O
Vôbec nečarujem. Takéto situácie mám bežne. Viď nižšie
  • (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
  • [/l][/l]
Nemuzes mit dva stejne pojmenovane parametry!!
Ja to bežne používam tak ako to je v príklade a doteraz som s tým nemal problém. MS Access to neumožňuje.
Sú dva základné prípady:
To miešanie prístupu nerobím. Podvedome som cítil, že buď jedno alebo druhé. Ja mám/používam vždy :myParameter. O pozičných parametroch som akosi nepočul.
Ja to beriem tak, že sa pri parsovaní SQL.Text-u vytvorí zoznam z :myParameterA až :myParameterX. Kedže to je zoznam, tak k jednotlivým položkám môžem pristupovať pomocou indexov.
Dôvod otázky:
Teraz mám všade prístup podľa mena. Ovšem, ak robím spracovanie v cykle pomocou dávky, tak sa odporúča pristupovať pomocou indexov (devArt). Hľadal som to aj FireDAC, ale žiadnu takú poznámku som nenašiel. Viem, že to platí všeobecne. Pri prístupe podľa mena tam je vždy práca navyše a pri vysokom počte položiek sa to prejaví. Ja mám rádove maximálne 1 - 2 tisícky záznamov, čo nie je veľa. Ale nechcem mať vedome v programe žiadne brzdy o ktorých viem.[/list]
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: vandrovnik 01-09-2020, 16:34:33
Teraz mám všade prístup podľa mena. Ovšem, ak robím spracovanie v cykle pomocou dávky, tak sa odporúča pristupovať pomocou indexov (devArt). Hľadal som to aj FireDAC, ale žiadnu takú poznámku som nenašiel. Viem, že to platí všeobecne. Pri prístupe podľa mena tam je vždy práca navyše a pri vysokom počte položiek sa to prejaví. Ja mám rádove maximálne 1 - 2 tisícky záznamov, čo nie je veľa. Ale nechcem mať vedome v programe žiadne brzdy o ktorých viem.

Při tomhle počtu záznamů bude rozdíl v rychlosti sotva měřitelný, zato se Ti při přístupu podle jména a nějaké dodatečné změně dotazu nestane, že bys omylem zapisoval do jiných parametrů, než jsi zamýšlel...
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 17:08:52
Toho som si vedomý.
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 01-09-2020, 17:51:35
Ak mám nejaký subSelect viac krát použitý v hlavnom Query. U mňa to nie je nič mimoriadne. Ako by som to mal riešiť, aby sa mi parametre neopakovali?
Nejak mam pocit, ze se s tebou nedokazu vubec na nicem domluvit: V seznamu parametru bys mel mit jen jeden parametr se stejnym jmenem a ten v SQL muzes pouzit kolikrat chces.

A obvykly zpusob predani parametru je
Kód: Delphi [Vybrat]
  1. someDataset.ParamByName('XXX').AsXXX := XXX;

Ono kdyz udelas:
Kód: Delphi [Vybrat]
  1. someDataset.Params.Add('XXX', .....);
  2. someDataset.Params.Add('XXX', .....);
tak FireDac do nesetridene kolekce ten parametr pridaji 2x, tj.

someDataset.Params[0].Name = 'XXX';
someDataset.Params[1].Name = 'XXX';


ale jakmile se s tim operuje pres jmeno, tak najdou vzdycky jen prvni, protoze delaji full scan. Ale z pohledu programatora je to prasarna, ktera funguje jinak nez je zamysleno (parser resi odkaz na parametr zacinajici : hledanim jmena) a tedy to funguje spis dilem nahody a uz vubec bych nechtel videt, jak by se to chovalo na vsech ruznych jinych konektivitach, jestli by te s tim duplikatnim jmenem nevyfuckovali - ja ano :-)

Citace
Teraz mám všade prístup podľa mena. Ovšem, ak robím spracovanie v cykle pomocou dávky, tak sa odporúča pristupovať pomocou indexov (devArt).
Pokud polezes natvrdo na indexy, tak pokud nesouhlasi position, tak stejne delaji full scan...
Pokud honit rychlost, tak si ty instance parametru vytahat do promennych tj.
Kód: Delphi [Vybrat]
  1. var paramYear = TFDParam;
  2. paramYear := someDataset.Params.Add('YEAR', .....);
  3. ...
  4. paramYear.AsXXX := XXX;
  5.  

Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 18:41:12
Citace
Nejak mam pocit, ze se s tebou nedokazu vubec na nicem domluvit: V seznamu parametru bys mel mit jen jeden parametr se stejnym jmenem a ten v SQL muzes pouzit kolikrat chces.
Vyzerá to, že si ma zle pochopil. Ja aktívne žiadne parametre nevytváram. Čiže žiadne DataSet.Params.Add(). Zásadne vždy len poskladám SQL.Text a naraz ho priradím do FDQuery. Jediné čo občas urobím je, keď mi FireDAC vynadá, že nepozná typ parametra. Tak to doplním. Tak námatkovo som vybral na ukážku kód. Nechal som v ňom len časti kde sú parametre aby bolo vidieť o čom hovorím. Nedávam to formátovať, lebo sa to skoro nedá čítať. Opakované parametre som vyznačil tučne
.
FqryUI.SQL.Text := FqryUI.SQL.Text + N_Purge;
function TConsumption.TConsumeOw.N_Purge: string;
  Result := 'SELECT GEN_ID(SETTLEMENT_ID, 1), I.FKFOCS, I.YEARS, F.FKOWNER_FLAT, F.FKSERVICEPARAMETERS,'+
    ' CASE'+ ' WHEN F.READFINAL > :LASTDATE THEN :LASTDATE'+
    ' CASE'+ ' WHEN F.KINDSTATE > :KS2 THEN 0'+
    ' CASE'+ ' WHEN F.KINDSTATE > :KS2 THEN 0'+
    ' CASE'+ ' WHEN F.KINDSTATE > :KS2 THEN 0'+
  ' FROM '+ N_Initial +
    ' INNER JOIN '+ N_Final + ' ON (I.FKOWNER_FLAT = F.FKOWNER_FLAT)'+
function TConsumption.TConsumeOw.N_Initial: string;
  Result := '(SELECT C.FKFOCS, SA.YEARS, C.FKOWNER_FLAT, DOT.FKSERVICEPARAMETERS, DOT.FKCAANALYTICOPTIONS,'+
  ' WHERE'+
    ' ((C.READING BETWEEN :LOWERBEGIN AND :LOWEREND)'+
      ' OR'+
    ' ((C.READING BETWEEN :LOWEREND + 1 AND :UPPERBEGIN - 1) AND (C.KINDSTATE = :KS1))'+
      ' AND (MP.YEARFROM <= :YEARS) AND ((MP.YEARTO >= :YEARS) OR (MP.YEARTO IS NULL)))) I';
function TConsumption.TConsumeOw.N_Final: string;
begin
  Result := '(SELECT C.FKOWNER_FLAT, DOT.FKSERVICEPARAMETERS, DOT.FKCAANALYTICOPTIONS, DOT.FKSUBACCOUNTS, C.FKMETERS,'+
    ' CASE'+ ' WHEN C.KINDSTATE = :WITHOUTREADING THEN MP.WITHOUTREADING'+
      ' WHEN C.KINDSTATE = :TAMPERING THEN MP.TAMPERING'+
  ' WHERE'+
    ' ((C.READING BETWEEN :UPPERBEGIN AND :UPPEREND)'+
      ' OR'+
    ' ((C.READING BETWEEN :LOWEREND + 1 AND :UPPERBEGIN - 1) AND (C.KINDSTATE = :KS2)))'+
      ' AND (MP.YEARFROM <= :YEARS) AND ((MP.YEARTO >= :YEARS) OR (MP.YEARTO IS NULL))) F';

Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 18:52:22
Príklad použitia
Kód: [Vybrat]
for I := 0 to FNodes.Count -1 do
begin
  GetParameters(FNodeData, NewPeriod, I);
.
procedure TfrmDepositNewMonth.GetParameters(const NodeData: PTableData; const NewPeriod: TDate; const I: Integer);
begin
  FqryPaidSipo_I.ParamByName('IDPAIDSIPOS').AsIntegers[I] := NewPrimaryKey;
  FqryPaidSipo_I.ParamByName('FKFOCS').AsIntegers[I] := NodeData.Integers[IDFocs];
  FqryPaidSipo_I.ParamByName('PERIOD').AsDates[I] := NewPeriod;
  FqryPaidSipo_I.ParamByName('PAID').AsIntegers[I] := 0;
end;
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 01-09-2020, 19:23:35
Vyzerá to, že si ma zle pochopil. Ja aktívne žiadne parametre nevytváram. Čiže žiadne DataSet.Params.Add().
To .Add udela SQL preprocesor, tady to byla jen ilustrace, ze do Params je mozne dostat vice parametru se stejnym jmenem. Nicmene ParamByName najde jen prvni (=jediny).

Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 20:15:18
Podľa mojej ukážky, posledné riadky vo funkciách.
Takže parameter :YEARS bude v Params 4x? Hm, potom nerozumiem, že mi to funguje. Čosi tu nesedí ???
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 01-09-2020, 20:35:48
Takže parameter :YEARS bude v Params 4x? Hm, potom nerozumiem, že mi to funguje. Čosi tu nesedí ???
Samozrejme ze ne. Ale cele je to reakce na konstrukci
Params[0] (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
z puvodniho dotazu.

Uz jsem z tebe GoGo a vzdavam to
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 01-09-2020, 21:23:13
To bola len otázka, či to takto funguje ;D  Citujem sa
Citace
Tu to ako bude
YEARS = 0 a DELETED = 1, alebo musím použiť
Params[0] (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
Podľa diskusie asi musím použiť jedine ByName. Pretože pri viacnásobnom výskyte jedného parametra asi neviem povedať na ktorej pozícii sa bude nachádzať. Hlavne keď to skladanie textu je komplikované a môže byť variabilné.
Myslím si, že to môžem(e) uzatvoriť s týmto záverom. Ak názvy parametrov:
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 02-09-2020, 10:37:37
To bola len otázka, či to takto funguje ;D 
No vsak. Jak te vubec takova p*covina mohla napadnout  :o

Citace
Myslím si, že to môžem(e) uzatvoriť s týmto záverom.
   sú unikátne a som si istý ich pozíciou, tak môžem použiť Params(I) - majú tam byť hranaté zátvorky. Ale formátovanie
Ne, to je chybny zaver: pojmenovane parametry tvori neusporadanou mnozinu a o poradi jednotlivych clenu nelze cinit zadne predpoklady. To, ze to u nejake implementace nahodou funguje neznamena, ze to neni silena praktika - jakoby nestacilo, ze psat neco v SQL per se je samo o sobe k posr*ni, jeste aby to nekdo doprasil timto zpusobem a vytvoril tresniku na dortu v podobe neudrzovatelneho kodu  >:(

Ostatne - proc myslis, ze se temer vytratily z praxe pozicni parametry, prestoze to byl puvodni a jediny zpusob, jak SQL prikaz parametrizovat? Bylo neudrzovatelne...

Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: Stanislav Hruška 02-09-2020, 11:37:42
Citace
No vsak. Jak te vubec takova p*covina mohla napadnout 
Tak, že to tom totálne nič neviem ;)
Citace
Ostatne - proc myslis, ze se temer vytratily z praxe pozicni parametry, prestoze to byl puvodni a jediny zpusob, jak SQL prikaz parametrizovat? Bylo neudrzovatelne...
Pre mňa to je nová informácia. Ja som vychádzal z odporúčania DevArt. Ale je pravda, že mali na mysli veľký počet "riadkov". Niekde okolo 100 K. A to sa mňa určite netýka.
Ďakujem za objasnenie problematiky. Aj keď (mi) to trochu trvalo.
Na moje pomery som sa dosť hrabal vo FireDAC helpe, ale na nič s tým spojené som nenarazil.
Název: Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
Přispěvatel: pf1957 02-09-2020, 11:59:17
Ja som vychádzal z odporúčania DevArt. Ale je pravda, že mali na mysli veľký počet "riadkov". Niekde okolo 100 K.
To neznamena, ze kdyz to napsalo DevArt, ze to neni zavrzeni hodna technika. Pocet radku, to se snad tyka jen bulk insertu a tam by se to optimalizovalo na rychlost jako kterykoli jiny invariant, tady podobne jako dataset designer zapamatuje instance TFields v samostatnych promennych u formulare/datamodulu, aby se nemusely v run-time lovit z nejakych kolekci. Tady bys pred cyklem pomoci FindParam ty parametry vytahal do promennych, nebo by si nenechal seznam parametru automaticky vytvaret z SQL a vytvoril si ho sam a instance zapamatoval.