RecordCount + group by lub distinct

Odpowiedz Nowy wątek
2012-12-03 12:33
Ozi
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ę?

edytowany 5x, ostatnio: Ozi, 2012-12-03 12:37

Pozostało 580 znaków

2012-12-03 12:38
0

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2012-12-03 12:43
Ozi
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.

edytowany 1x, ostatnio: Ozi, 2012-12-03 12:44

Pozostało 580 znaków

2012-12-03 13:02
Ozi
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... :/

edytowany 1x, ostatnio: Ozi, 2012-12-03 13:03

Pozostało 580 znaków

2012-12-03 13:16
0

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


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.

Pozostało 580 znaków

2012-12-03 13:31
Ozi
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

Pozostało 580 znaków

2012-12-03 13:53
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


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

2012-12-03 13:56
Ozi
0

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

Pozostało 580 znaków

2012-12-03 14:10
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


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.

Pozostało 580 znaków

2012-12-03 14:16
Ozi
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.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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