Autor Téma: Číslovanie parametrov v SQL.Text pri opakovanom výskyte  (Přečteno 2790 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
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)
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #1 kdy: 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.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #2 kdy: 01-09-2020, 14:06:42 »
[0] (prvý YEARS) - Params[1] (DELETED)- Params[2] (druhý YEARS)
Nemuzes mit dva stejne pojmenovane parametry!!

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #3 kdy: 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:
  • Tak ako to je uvedené v príklade
  • 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?
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]
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline vandrovnik

  • Padawan
  • ******
  • Příspěvků: 1528
  • Karma: 52
    • Verze Delphi: 11.3
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #4 kdy: 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...

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #5 kdy: 01-09-2020, 17:08:52 »
Toho som si vedomý.
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #6 kdy: 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.  


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #7 kdy: 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';

Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #8 kdy: 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;
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #9 kdy: 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).


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #10 kdy: 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í ???
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #11 kdy: 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

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #12 kdy: 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:
  • 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
  • sa opakujú, tak musím použiť ParamByName('myParameter')
« Poslední změna: 01-09-2020, 21:25:35 od Stanislav Hruška »
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3516
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #13 kdy: 02-09-2020, 10:37:37 »
Excellent
Rated 1 time
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...


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 7303
  • Karma: 44
    • Verze Delphi: W11 + D11.3.1
Re:Číslovanie parametrov v SQL.Text pri opakovanom výskyte
« Odpověď #14 kdy: 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.
Win11 64b, Delphi 11.3.1, FireBird 4.01
Expert na kladenie nejasne formulovaných otázok.