RecordCount + group by lub distinct

0

Jest sobie kawałek przykładowego kodu:

  sqlstring := '';
  sqlstring := 'select sum(cena*ilosc) as wartosc, waluta from oferta';
  sqlstring := sqlstring + ' where nr_oferty=' + inttostr(nr_oferty);
  sqlstring := sqlstring + ' group by waluta';
  q_tmp.CommandText := sqlstring;
  q_tmp.Open;
  if q_tmp.RecordCount>1 then
  begin
    showmessage('Oferta ma pozycje o różnej walucie.');
  end;

Okazuje się, że RecordCount źle zlicza wynik zapytania, w którym jest "group by".
Przykładowo, jeśli mamy tabelkę z pozycjami:

+------+-----+--------+
| cena | ilosc| waluta |
+------+-----+--------+
| 5 | 2 | PLN |
| 7 | 2 | EUR |
| 23 | 1 | PLN |
| 34 | 1 | EUR |
| 33 | 1 | PLN |
+------+-----+--------+

i wynik powyższego zapytania to:

+---------+--------+
| wartosc | waluta |
+---------+--------+
| 66 | PLN |
| 48 | EUR |
+---------+--------+

...czyli liczba wierszy wynosi 2, to RecordCount i tak zwraca liczbę 5.

Pomyślałem więc, że można zrobić to w taki sposób:

  sqlstring := '';
  sqlstring := 'select distinct waluta from oferta';
  sqlstring := sqlstring + ' where nr_oferty=' + inttostr(nr_oferty);
  q_tmp.CommandText := sqlstring;
  q_tmp.Open;
  if q_tmp.RecordCount>1 then
  begin
    showmessage('Oferta ma pozycje o różnej walucie.');
  end;

Okazuje się, że też nie!
Tutaj odpowiedzią na to zapytanie jest:

+--------+
| waluta |
+--------+
| EUR |
| PLN |
+--------+

Ale na linii "if q_tmp.RecordCount>1 then" Delphi wywala mi błąd:

[0x0005]: Operation Not Supported

Co źle robię?

0

A czy jesteś w stanie uzasadnić niezbędność użycia RecordCount?

0

Użycie RecordCount nie jest niezbędne. Chcę po prostu poznać liczbę wierszy, jakie zwróci zapytanie z "group by". Jeśli da się to sprawdzić w inny sposób, to z góry dziękuje za podpowiedź.

Uprzedzam ewentualne pytanie, czy muszę używać zapytania z "group by". Niby nie, ale później i tak to zapytanie wykonam, bo będę go używał do pętli:

  while not q_tmp.Eof do
  begin
    (...)
    q_tmp.Next;
  end;

...i tutaj ta pętla jest wykonywana poprawnie tylko 2 razy, a nie 5.

Zanim jednak uruchomię tą pętlę chciałbym wiedzieć, ile razy zostanie ona wykonana.

Dodam, że q_tmp to SQLDataSet z dbExpress.

0

Tutaj:
http://www.delphigroups.info/2/8/751075.html
znalazłem coś takiego:

select count(distinct field1) from table1

Tak więc można to zrobić tak:

  sqlstring := '';
  sqlstring := 'select count(distinct waluta) as ilosc_walut from oferta';
  sqlstring := sqlstring + ' where nr_oferty=' + inttostr(nr_oferty);
  q_tmp.CommandText := sqlstring;
  q_tmp.Open;
  if q_tmp['ilosc_walut']>1 then
  begin
    showmessage('Oferta ma pozycje o różnej walucie.');
  end;

Niby rozwiązuje problem, ale tak, jak wyżej napisałem - i tak muszę poniżej zrobić kolejne zapytanie z "group by". I tym sposobem zamiast robić jedno zapytanie, muszę robić dwa... :/

0

Dawno nie używałem TSQLQuery i tak sobie strzelam, sprawdź co masz w q_tmp.RowsAffected

0

Chyba nie bardzo, bo helpie w Delphi piszą:

Returns the number of rows operated upon by the latest query execution.

Inspect RowsAffected to determine how many rows were updated or deleted by the last query operation. If no rows were updated or deleted, RowsAffected has a value of zero. RowsAffected will have a value of –1 if the execution of the SQL statement could not be executed due to an error condition. This latter situation would typically follow the raising of an exception.

Tu już też była o tym mowa:
[DELPHI] Różnica między RowsAffected a RecordCount

Swoją drogą wyrażenie "q_tmp.RowsAffected" nie przechodzi mi przez kompilator:

[DCC Error] main.pas(18981): E2362 Cannot access protected symbol TCustomSQLDataSet.RowsAffected

0

to jest bug w dbexpress - dbexpress aby poznać "prawdziwy" recoedcount bez pobierania wszystkich danych wysyła drugie zapytanie (po prostu generuje select count) ale źle rozpoznaje warunki i/lub grupowanie w źródłowym zapytaniu. Nie przeskoczysz tego - pozostaje Ci jedynie samemu odpytywać bazę dwa razy

0

Te dbexpress swoje lata ma i jeszcze nikt tam tego buga nie zdążył naprawić? :/

0

nowa wersja (gdzie mogło to być poprawione) wyszła z RadStudio 2010 (rok 2009) więc jak masz jakieś starsze środowisko to zapewne błąd tam jest, a jak masz nowsze to nie mam pojęcia czy to poprawili

0
abrakadaber napisał(a):

nowa wersja (gdzie mogło to być poprawione) wyszła z RadStudio 2010 (rok 2009) więc jak masz jakieś starsze środowisko to zapewne błąd tam jest, a jak masz nowsze to nie mam pojęcia czy to poprawili

Mam Embarcadero RadStudio Delphi 2010.

1 użytkowników online, w tym zalogowanych: 0, gości: 1