Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Anzahl gefundener Datensätze (https://www.delphipraxis.net/205058-anzahl-gefundener-datensaetze.html)

zeras 28. Jul 2020 09:13

Datenbank: SQLITE • Version: 3.x • Zugriff über: Firedac

Anzahl gefundener Datensätze
 
Guten Tag,

ich habe ein Verständnisproblem mit SQL.
Wenn ich die Datenbank so abfrage, bekomme ich beispielsweise 66 Einträge.
Delphi-Quellcode:
begin
  Result := False;
  KAList.Clear;
  SqlState := Format('SELECT %s FROM %s;', [feldKANummer, TableNameKANummer]);
  DataModul.SQLQuery.SQL.Text := SqlState;
  try
    DataModul.SQLQuery.Open();
    if not DataModul.SQLQuery.IsEmpty then begin
      DataModul.SQLQuery.First;
      repeat
        KAList.Add(DataModul.SQLQuery.FieldByName(feldKANummer).AsString);
        DataModul.SQLQuery.Next;
      until DataModul.SQLQuery.Eof;
    end;
  finally
    DataModul.SQLQuery.Close;
  end;

  Result := KAList.Count > 0;
end;
Mache ich das so, bekomme ich nur 50. Weder bei RowsAffected, noch bei RowsAffected komme ich auf den Wert von oben, der stimmen müsste.
Delphi-Quellcode:
begin
  Result := 0;
  SqlState := Format('SELECT %s FROM %s;', [feldKANummer, TableNameKANummer]);
  DataModul.SQLQuery.SQL.Text := SqlState;
  try
    DataModul.SQLQuery.Open();
    //result := DataModul.SQLQuery.RowsAffected;
    result := DataModul.SQLQuery.RecordCount;
  finally
    DataModul.SQLQuery.Close;
  end;
end;
Was mache ich falsch?

Delphi.Narium 28. Jul 2020 09:23

AW: Anzahl gefundener Datensätze
 
Willst Du wissen, wieviele DAaensätze es gibt?

Dann versuch' es doch mal mit 'nem einfachen
SQL-Code:
select count(*) as Anzahl from tabelle
Delphi-Quellcode:
begin
  Result := 0;
  SqlState := Format('SELECT count(*) FROM %s;', [TableNameKANummer]);
  DataModul.SQLQuery.SQL.Text := SqlState;
  try
    DataModul.SQLQuery.Open();
    result := DataModul.SQLQuery.Fields[0].AsInteger;
  finally
    DataModul.SQLQuery.Close;
  end;
end;
Was ist denn bitte KAList? Eine sortierte Stringliste, die beim Sortieren z. B. Duplikate ignoriert? Dann wäre das auch nicht unbedingt eine verlässliche Zählmethode.

Lemmy 28. Jul 2020 09:25

AW: Anzahl gefundener Datensätze
 
Ändert sich was, wenn du im zweiten Code ein "DataModul.SQLQuery.Last" einfügst? Vermutlich wird hier kein FetchAll ausgeführt (unter der Annahme, dass die SQL und die Datenbank jeweils die selbe ist)

zeras 28. Jul 2020 09:29

AW: Anzahl gefundener Datensätze
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1470548)
Willst Du wissen, wieviele DAaensätze es gibt?

Dann versuch' es doch mal mit 'nem einfachen
SQL-Code:
select count(*) as Anzahl from tabelle
Delphi-Quellcode:
begin
  Result := 0;
  SqlState := Format('SELECT count(*) FROM %s;', [TableNameKANummer]);
  DataModul.SQLQuery.SQL.Text := SqlState;
  try
    DataModul.SQLQuery.Open();
    result := DataModul.SQLQuery.Fields[0].AsInteger;
  finally
    DataModul.SQLQuery.Close;
  end;
end;
Was ist denn bitte KAList? Eine sortierte Stringliste, die beim Sortieren z. B. Duplikate ignoriert? Dann wäre das auch nicht unbedingt eine verlässliche Zählmethode.

Danke, die Änderungen haben zum gewünschten Ergebnis geführt.
Zu deiner Frage:
KAList ist die Liste, mit der ich dann später einzelne Datensätze mittels anderer SQL Abfragen abfrage.

zeras 28. Jul 2020 09:32

AW: Anzahl gefundener Datensätze
 
Zitat:

Zitat von Lemmy (Beitrag 1470549)
Ändert sich was, wenn du im zweiten Code ein "DataModul.SQLQuery.Last" einfügst? Vermutlich wird hier kein FetchAll ausgeführt (unter der Annahme, dass die SQL und die Datenbank jeweils die selbe ist)

Wenn ich das so einbaue, wie von dir beschrieben, geht es auch. Warum muss ich dann aber erst Last setzen?
Delphi-Quellcode:
begin
  Result := 0;
  SqlState := Format('SELECT %s FROM %s;', [feldKANummer, TableNameKANummer]);
  DataModul.SQLQuery.SQL.Text := SqlState;
  try
    DataModul.SQLQuery.Open();
    DataModul.SQLQuery.Last;
    result := DataModul.SQLQuery.RecordCount;
  finally
    DataModul.SQLQuery.Close;
  end;
end;

Delphi.Narium 28. Jul 2020 09:43

AW: Anzahl gefundener Datensätze
 
Zitat:

Zitat von zeras (Beitrag 1470550)
KAList ist die Liste, mit der ich dann später einzelne Datensätze mittels anderer SQL Abfragen abfrage.

Das ist schon klar, beantwortet aber nicht die Frage, von welchem Typ sie ist und ob sie unter Umständen Dubletten ignorieren könnte und damit ein falsches Zählergebnis zustande kommt.

Last muss gesetzt werden, damit die Datenbank zum letzten Datensatz geht. Vorher ist RecordCount (je nach Datenbank) die Zahl des letzten, bisher gelesenen, Datensatzes. Und bei einigen Datenbanken bzw. Datenbankkomponenten wird nicht sofort alles gelesen, sondern nur die Sätze, deren Lesen beim ersten Fetch erfolgt. Wenn Du also z. B. 1000000 Sätze in der Tabelle hast, aber beim Fetchen nur 2 Datensätze gelesen werden sollen, so hat RecordCount dann auch nur den Wert 2, derweil: Der Datenbank und der Datenbankkomponenten sind zu diesem Zeitpunkt noch nicht bekannt, dass es 1000000 Sätze gibt. Bisher haben sie halt nur 2 gefunden, beim nächsten Next wissen sie dann, dass es bis dahin nun 3 Sätze sind. Das wird wiederholt, bis EoF erreicht ist. Last ist halt der kürzeste Weg zum letzten Datensatz in der Datenmenge. Und erst wenn das Ende der Datenmenge erreicht ist, ist auch definitiv bekannt, wieviele Datensätze die Datenmenge enthält.

Lemmy 28. Jul 2020 09:47

AW: Anzahl gefundener Datensätze
 
Ergänzend zu Delphi.Narium: Schau mal ob die Query eine Option "FetchAll" hat und ließ mal in der Hilfe dazu...

Und wenn es wirklich "nur" um die Anzahl der Datensätze geht ist der Ansatz von Delphi.Narium immer vorzuziehen, da hier nicht alle Datensätze übers Netz gezogen werden müssen, d.h. das geht eigentlich immer schneller...

zeras 28. Jul 2020 10:47

AW: Anzahl gefundener Datensätze
 
Zitat:

Zitat von Delphi.Narium (Beitrag 1470556)
Das ist schon klar, beantwortet aber nicht die Frage, von welchem Typ sie ist und ob sie unter Umständen Dubletten ignorieren könnte und damit ein falsches Zählergebnis zustande kommt.

KAList ist eine StringList. Mit Dubletten sollte es keine Probleme geben, da bei Insert geprüft wird, ob es diesen Wert schon gibt.

Zitat:

Zitat von Delphi.Narium (Beitrag 1470556)
Last muss gesetzt werden, damit die Datenbank zum letzten Datensatz geht. Vorher ist RecordCount (je nach Datenbank) die Zahl des letzten, bisher gelesenen, Datensatzes. Und bei einigen Datenbanken bzw. Datenbankkomponenten wird nicht sofort alles gelesen, sondern nur die Sätze, deren Lesen beim ersten Fetch erfolgt. Wenn Du also z. B. 1000000 Sätze in der Tabelle hast, aber beim Fetchen nur 2 Datensätze gelesen werden sollen, so hat RecordCount dann auch nur den Wert 2, derweil: Der Datenbank und der Datenbankkomponenten sind zu diesem Zeitpunkt noch nicht bekannt, dass es 1000000 Sätze gibt. Bisher haben sie halt nur 2 gefunden, beim nächsten Next wissen sie dann, dass es bis dahin nun 3 Sätze sind. Das wird wiederholt, bis EoF erreicht ist. Last ist halt der kürzeste Weg zum letzten Datensatz in der Datenmenge. Und erst wenn das Ende der Datenmenge erreicht ist, ist auch definitiv bekannt, wieviele Datensätze die Datenmenge enthält.

Die Erklärung hilft mit sehr weiter.
In der Query habe ich nun gesehen, dass es einen Wert "RowsetSize" gibt, der auf 50 steht. Dies erklärt dann auch das Verhalten, was ich beobachtet habe.


Vielen Dank euch nochmals für die Erklärungen. Damit ist mein Problem gelöst.

Delphi.Narium 28. Jul 2020 10:55

AW: Anzahl gefundener Datensätze
 
Zitat:

Zitat von zeras (Beitrag 1470561)
Zitat:

Zitat von Delphi.Narium (Beitrag 1470556)
Das ist schon klar, beantwortet aber nicht die Frage, von welchem Typ sie ist und ob sie unter Umständen Dubletten ignorieren könnte und damit ein falsches Zählergebnis zustande kommt.

KAList ist eine StringList. Mit Dubletten sollte es keine Probleme geben, da bei Insert geprüft wird, ob es diesen Wert schon gibt.

Das ist aber doch genau das Problem:

Wenn Du in der Datenmenge 50 * den Wert "Hallo" und 47 * den Wert "Leute" bekommst, so wird Dir KAList als Ergebnis im KAList.Count die zwei liefern, auch wenn es tatsächlich 97 Datensätze gibt.

himitsu 28. Jul 2020 14:22

AW: Anzahl gefundener Datensätze
 
Das mit dem Format solltest du besser lassen.
> besser Parameter und Makros

PS: Anzahl und "Werte"
SQL-Code:
SELECT count(xxx), string_agg(xxx, ',') AS value FROM yyy


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz