Autor Téma: IBQuery  (Přečteno 11259 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
IBQuery
« kdy: 05-10-2012, 11:02:34 »
Používam

Kód: [Vybrat]
  SetLength(aParam, 1);
  aParam[0] := PrKey;

  IBQ('SELECT IDUSERS, FKLANDLORDS, USERS.SURNAME, USERS.FIRSTNAME, USERS.TITLE,'
    +' USERS.DATEFROM, USERS.DATETO, LANDLORD'
    +' FROM LANDLORDS INNER JOIN USERS ON LANDLORDS.IDLANDLORDS=USERS.FKLANDLORDS'
    +' WHERE USERS.FKLANDLORDS=:P0');

function IBQ(sSQL: string): Boolean; overload;
var
  I: Integer;
begin
  Result := False;

with MyQuery do
begin
Active := False;
Filter := '';
SQL.Text := sSQL;

    for I := Low(aParam) to High(aParam) do
      Params[I].Value := aParam[I];

    try
      Active := True;
      Result := True;
    except
      on E: Exception do
      begin
        Fault('Chyba v príkaze Select' +#10 + #13 + E.Message);
        Active := False;
      end;
    end;

First;
end;
end;


Vždy mi vráti prvý záznam z Users. V IBE a pod ADOQuery to funguje normálne. Už netuším, čo mám kontrolovať. V Users mám ForeignKey na tabuľku Landlords.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #1 kdy: 05-10-2012, 11:54:51 »
Už som to asi našiel. Vyzerá to, že som nechtiac zmenil kód.
Unáhlil som sa, problém pretrváva.
No, pracuje sa s tým trocha ináč

dmMain.ibqry1.Params.ParamValues['p'] := PrKey;

Trepem a trepem nezmysly. Prosím Vás, nevšímajte si ma.

Už som to objavil, ale vysvetlenie nemám. Problém je v názve parametra

    +' WHERE Users.FKLandlords=:p0');

Ak dám hocičo iné napr. :p1 tak to funguje. Vie niekto prečo?
« Poslední změna: 05-10-2012, 13:33:03 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 576
  • Karma: 25
Re:IBQuery
« Odpověď #2 kdy: 05-10-2012, 14:03:29 »
dmMain.ibqry1.Params.ParamValues['p'] := PrKey;

Už som to objavil, ale vysvetlenie nemám. Problém je v názve parametra

    +' WHERE Users.FKLandlords=:p0');

proc mas v paramValues p a v selectu p0? Ty nazvu parametru se snad davaji do sql dotazu i do parametru, ne? Mely by byt stejne.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #3 kdy: 05-10-2012, 14:25:26 »
V skutočnosti mám

    for I := Low(aParam) to High(aParam) do
      Params.Value := aParam;

To som skúšal čo sa dalo a pritom blbol.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3338
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:IBQuery
« Odpověď #4 kdy: 05-10-2012, 15:05:16 »
V skutočnosti mám

    for I := Low(aParam) to High(aParam) do
      Params.Value := aParam;

To som skúšal čo sa dalo a pritom blbol.
S TIBQuery jsem delal naposledy neco v D5/6, takze HOSIP, ale prijde mi to cele nejake pomatene...

Rekl bych, ze Params jsou typu DB.TParams a tam mas jen 3 moznosti, jak pridat parametr:
  • Jmenem pres IBQ.ParamByName('xxx').Value := yyy
  • Jmenem pres IBQ.Params.ParamValues['xxx'] := yyy
  • Instanci tj. musis si vytvorit instanci TParam a tu pak pridat do kolekce parametru IBQ.Params.AddParam(param)
a pokud si instanci IBQ nevytvaris pro kazdy SQL znovu, tak je treba ty seznamy parametru nulovat.

Pokud ale parametru nedas jmeno, tak bys mel v SQL tzv. pozicni parametry tj. misto :xxx napsat ? nebo ?1 atd.  Ale uz nevim, jestli to Ptak ohnivak a komponenty IBX podporuji.


Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #5 kdy: 05-10-2012, 15:33:16 »
Takže ešte raz, a snáď už správne skopírované

Kód: [Vybrat]
   
for I := Low(aParam) to High(aParam) do
      Params[I].Value := aParam[I];

Aha ho. Nevložil som to ako kód tak mi hranaté zátvorky vyhodilo.
 Je pravda, že zoznam parametrov nenulujem. Doteraz som s tým poblém nemal. Momentáne čumím, že ibTable.RecordCount mi vracia 1 a je ich tam viac. Vôbec sa nenudím   >:(
« Poslední změna: 05-10-2012, 15:34:52 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3338
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:IBQuery
« Odpověď #6 kdy: 05-10-2012, 15:45:49 »
Aha ho. Nevložil som to ako kód tak mi hranaté zátvorky vyhodilo.
Je pravda, že zoznam parametrov nenulujem.
Aha. Oni ty IBQuery pri zmene SQL vygeneruji automaticky seznam parametru. Pak to dava smysl a ani nulovat to nemusis.

Momentáne čumím, že ibTable.RecordCount mi vracia 1 a je ich tam viac. Vôbec sa nenudím   >:(
RecordCount bys nemel vubec pouzivat a pokud ano, tak jedine po predchozim FetchAll, pokud je tech dat malo a chces je opravdu nacist. Jinak je treba zeptatse se DB pomoci select count(*)...

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #7 kdy: 05-10-2012, 16:07:22 »
Je mi jedno čo použijem. Záznamov je málo a potrebujem ich dať do poľa. Takéto problémy som doteraz nepoznal. Skúsim ten Count. Ale prečo mi nefunguje RecordCount? Je to local DB a okrem čítania s ňou nič nerobím.

A už sa teším ako budem riešiť diakritiku. Mám ju rozhádzanú, ale to má čas. Najprv si chcem o tom niečo prečítať.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3338
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:IBQuery
« Odpověď #8 kdy: 05-10-2012, 16:15:43 »
Je mi jedno čo použijem. Záznamov je málo a potrebujem ich dať do poľa. Takéto problémy som doteraz nepoznal. Skúsim ten Count. Ale prečo mi nefunguje RecordCount? Je to local DB a okrem čítania s ňou nič nerobím.
Nefunguje ti ani po tom FetchAll? RecordCount je u SQL databaze obecne nedefinovane a spatne zjistitelne, protoze data se z SQL serveru tahaji po castech a nic jako lokalni DB neexistuje - maximalne SQL server bezici na stejnem stroji, na kterem s Delphi pracujes.

Takze bud musis nejdriv precist vsechno a nebo  vubec RecordCount (krome TClientDataset) nepouzivat.

Offline Mi.Chal.

  • Guru
  • *****
  • Příspěvků: 576
  • Karma: 25
Re:IBQuery
« Odpověď #9 kdy: 05-10-2012, 20:32:56 »
Ale prečo mi nefunguje RecordCount? Je to local DB a okrem čítania s ňou nič nerobím.

K čemu RecordCount chceš? Kdysi se to řešilo na builderu, ono to má snad význam toho, kolik záznamů se dotáhlo. Ty se ale tahají po částech (když voláš Next, tak se můžou dotáhnout další), takže to nemusí mít stejnou hodnotu jako počet záznamů vrácených SQL dotazem. Prakticky to ale asi na nic nepotřebuješ, stačí volat Next dokud není nastaveno Query.Eof. Pokud chceš skutečný počet záznamů, tak přes sql dotaz s Select count.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1559
  • Karma: 37
    • Pepak.net
Re:IBQuery
« Odpověď #10 kdy: 06-10-2012, 07:05:03 »
K čemu RecordCount chceš? Kdysi se to řešilo na builderu, ono to má snad význam toho, kolik záznamů se dotáhlo.
1) Jasný praktický význam má počet záznamů pro uživatele, konkrétně pro zobrazení progressbaru. Přinejmenším pro moje uživatele je, soudě podle toho, s čím se na mě obrací, důležitější vidět, že operace probíhá a jak je daleko, než jak rychle se dohrabe k výsledku. (Jinými slovy, nevadí čekat, ale musí jít odhadnout, jak dlouho ještě budou čekat.)

2) Zjištění počtu záznamů předem je u některých typů dotazů hodně nákladné. Typicky u operací, kde složitý dotaz vytáhne z velké tabulky relativně málo záznamů a ty potom dalšími operacemi upravuji.

Takže v tomto případě Stanislava chápu.

A přidám i řešení, plus mínus - Zeos určitě, a IB myslím taky, mají někde v query property, jestli se má resultset načítat postupně "jak bůh SQL zamýšlel", nebo najednou. Při načtení najednou RecordCount funguje. Jméno property si nepamatuju, resp. používám natolik specifickou sadu komponent (dost stará verze Zeosu, s mnoha in-house úpravami), že nedokážu rozlišit, co ještě je součást dnešního Zeosu a co je relikt minulosti a/nebo náš přílepek.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3338
  • Karma: 139
    • Verze Delphi: D2007, XE3, DX10
Re:IBQuery
« Odpověď #11 kdy: 06-10-2012, 07:18:52 »
2) Zjištění počtu záznamů předem je u některých typů dotazů hodně nákladné. Typicky u operací, kde složitý dotaz vytáhne z velké tabulky relativně málo záznamů a ty potom dalšími operacemi upravuji.
 mnoha in-house úpravami), že nedokážu rozlišit, co ještě je součást dnešního Zeosu a co je relikt minulosti a/nebo náš přílepek.
Ano, dulezite je vedet, ze se neco deje a jak je to daleko. ale pokud je reseni natolik nakladne, tak bys mel informovat o prubehu uz pri vykonavani SQL a k tomu ti RecordCount nepomuze. Takze bud nejakou jalovou animaci, nebo u Ptaka Ohnivaka vypocet do SP  a posilat si z nej notifikace o prubehu pomoci POST_EVENT...
A je-li result set po slozitem vypoctu maly, lze pouzit to FetchAll.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #12 kdy: 06-10-2012, 09:43:42 »
// FetchAll
To nepoznám. Pozriem sa na to.

Spomenul som si, že kedysi kdesi prečítal približne "DB nevie počet riadkov. Musíte použiť metódu Last." Takto to funguje. Platí to pre tabuľky aj dotazy.

Všetky moje úvahy/skúsenosti vychádzajú s Access-u a zásadne lokálnej DB. V Access-e sú mnohé veci automatizované a vo FB si ich musím urobiť ručne. Vidˇ nové vlákno.

Takže jednoznačne odporúčate použiť
FetchAll a/alebo count(*)

a nespoliehať sa na
RecordCount + Last.

Teraz myslím aj na to, že táto aplikácia by teoreticky mohla byť sieťová. A tak sa musím aj správať. Nateraz ťahám tak málo záznamov, že sa vždy načítajú všetky.

Písal som, že počet záznamov potrebujem na nastavenie dĺžky poľa. V tomto prípade načítavam nastavenia programu a pod. a najlepšia práca sa mi vidí práve pomocou poľa. Tak si mnohé veci môžem jednoducho automatizovať pomocou for I := Low(pole) to High(pole) do...
Nastaviť si pole na dĺžku 100 a v prípade potreby ho zväčšovať po skokoch mi v tomto prípade nevyhovuje. Pri práci s ním by som musel kontrolovať, či hodnota v ňom nie je null a použiť Break.
V pri mojom riešení som v prípade chyby upozornený na prekročenie dĺtžky poľa. Čo ma zachráni od prúseru.

Teraz mám dĺžku až 17.
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.

Offline pepak

  • Padawan
  • ******
  • Příspěvků: 1559
  • Karma: 37
    • Pepak.net
Re:IBQuery
« Odpověď #13 kdy: 06-10-2012, 10:16:12 »
Všetky moje úvahy/skúsenosti vychádzajú s Access-u a zásadne lokálnej DB. V Access-e sú mnohé veci automatizované a vo FB si ich musím urobiť ručne. Vidˇ nové vlákno.
Spíš je to dané tím, že implementace příslušných datasetů některé věci dělá automaticky. Otázka je, nakolik je to dobře - je to jistě pohodlnější, ale současně to znamená, že se vždy provádí časově náročné operace, které mohou být někdy potřeba.

Citace
Písal som, že počet záznamov potrebujem na nastavenie dĺžky poľa.
V tom bude patrně algoritmická chyba - předem neznámý počet záznamů se obvykle v poli neuchovává. Máš nějaký zásadní důvod, proč je neukládáš třeba do TListu, když už chceš zachovat přístup jako k poli?

Citace
Tak si mnohé veci môžem jednoducho automatizovať pomocou for I := Low(pole) to High(pole) do...
Je to tak zásadně odlišné od for i := 0 to Pred(List.Count) do ... ?

Citace
Nastaviť si pole na dĺžku 100 a v prípade potreby ho zväčšovať po skokoch mi v tomto prípade nevyhovuje. Pri práci s ním by som musel kontrolovať, či hodnota v ňom nie je null a použiť Break.
Ano, tak třeba přesně tohle TList dělá docela dobře.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 6147
  • Karma: 44
    • Verze Delphi: W10 + D11
Re:IBQuery
« Odpověď #14 kdy: 06-10-2012, 10:37:46 »
Hm, s TList-om akosi nepracujem. Čo nie je môže byť.
Len jedna otázočka, to pole je viac rozmerné s rôznymi typmi údajov. Zvláda to TList?. Alebo tam budem musieť použiť TObject?
W10 64b, Delphi 10.4, FireBird 3.08
Expert na kladenie nejasne formulovaných otázok.