Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   TFDQuery und positionieren (https://www.delphipraxis.net/208961-tfdquery-und-positionieren.html)

Edelfix 5. Okt 2021 14:25

Datenbank: ADS • Version: 12 • Zugriff über: FireDac

TFDQuery und positionieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Wie würdet ihr das machen?

Ich habe als Beispiel eine Form mit einem DBGrid, DBNavigator, Datasource, FDQuery und FDConnection.

Alles mit einander verbunden.



Jetzt möchte ich in der Datenmenge suchen und den Treffer im DBGrid anzeigen.

Im DBGrid sollen alle Datensätze sichtbar (so viel wie das DBGrid anzeigen kann) sein und auf dem gesuchten Datensatz ist der Curser.

Wenn ich per SQL ein "SELECT * FROM Kunden WHERE Vorname='Max'" mache dann bekomme ich nur einen Datensatz.

Sieht im DBGrid komisch aus. Ich brauche auch die davor und die danach.

DeddyH 5. Okt 2021 14:30

AW: TFDQuery und positionieren
 
Wenn es nur einen Benutzer "Max" gibt, bekommst Du logischerweise auch nur einen Datensatz. Kann es sein, dass Du eher Delphi-Referenz durchsuchenLocate suchst?

Edelfix 5. Okt 2021 14:35

AW: TFDQuery und positionieren
 
Locate macht genau das was ich brauche. Aber es wird auf den Lokalen Daten durchgeführt und dauert ewig lange.

Gibt es eine Alternative?

Uwe Raabe 5. Okt 2021 14:58

AW: TFDQuery und positionieren
 
Na ja, du willst alle Datensätze anzeigen und auf einen davon positionieren. Eine Query liefert lediglich eine Datenmenge, positionieren muss man dann lokal. Wenn du die Datenmenge irgendwie einschränken kannst wird es schneller laufen - sonst müssen halt alle Daten lokal durchsucht werden. Wie eine solche Einschränkung aussehen kann, lässt sich nicht generell sagen. Das kommt immer auf die Abfrage an.

Delphi.Narium 5. Okt 2021 15:15

AW: TFDQuery und positionieren
 
Hat Dein DBGrid die Eigenschaft VisibleRowCount? Wenn ja, dann könntest Du ein (äußerst unschönes) Konstrukt dieser Art verwenden:
Delphi-Quellcode:
  Query.Close;
  Query.SQL.Text := Format('SELECT first %d * FROM Kunden WHERE Vorname >= :Suchbegriff',[DBGrid.VisibleRowCount]);
  Query.Params.ParamByName('Suchbegriff').AsString := EditMitDemSuchbegriff.Text;
  Query.Open;
  Query.Locate('Vorname',EditMitDemSuchbegriff.Text,[]);
Als Anwender käme ich mir aber ziemlich ... vor, wenn meine Suche nur genau ein Ergebnis liefert, mir aber ein paar Ergebnisse mehr angezeigt werden, nur damit die Anzeige voll wird und ich mir daraus dann wieder mein Ergebnis heraussuchen muss.
Wenn's nur ein Ergebnis gibt, ist die Datenbankabfrage schneller und meine Arbeit als Anwender auch, weil ich in den Ergebnissen nicht erst nach dem schauen muss, was ich eigentlich suchte, sondern bei einem Datensatz als Ergebnis recht schnell feststellen kann, ob es auch das gesuchte Ergebnis ist.

Sprich: Wenn die Suche nur einen Datensatz als Ergebnis liefert, dann erwarte ich als Anwender, dass mir auch nur ein Datensatz als Ergebnis geliefert wird (egal, wieviele Datensätze theoretisch oder praktisch oder bildschirmfüllend oder ... angezeigt werden könnten).

select first geht z. B. bei FireBird:
Delphi-Quellcode:
Query.SQL.Text := Format('SELECT first %d * FROM Kunden WHERE Vorname >= :Suchbegriff',[DBGrid.VisibleRowCount]);

Access nennt das select top:
Delphi-Quellcode:
Query.SQL.Text := Format('SELECT top %d * FROM Kunden WHERE Vorname >= :Suchbegriff',[DBGrid.VisibleRowCount]);

MySQL hängt lieber ein Limit hinten an das SQL an:
Delphi-Quellcode:
Query.SQL.Text := Format('SELECT * FROM Kunden WHERE Vorname >= :Suchbegriff limit %d',[DBGrid.VisibleRowCount]);

Das alte Oracle macht es (glaub' ich) eher so:
Delphi-Quellcode:
Query.SQL.Text := Format('SELECT * FROM Kunden WHERE Vorname >= :Suchbegriff ROWNUM <= %d',[DBGrid.VisibleRowCount]);

Und neue Oracle mögen sowas:
Delphi-Quellcode:
Query.SQL.Text := Format('SELECT * FROM Kunden WHERE Vorname >= :Suchbegriff FETCH FIRST %d ROWS ONLY',[DBGrid.VisibleRowCount]);

Andere DB, andere Syntax ;-)
Es lebe die datenbankunabhängige Programmierung, die übrigens, wenn das DBGrid nur die tatsächlich gefundenen Ergebnisse anzeigt und nicht aufgefüllt wird, erhalten bleibt.
Delphi-Quellcode:
Query.SQL.Text := 'SELECT * FROM Kunden WHERE Vorname = :Suchbegriff';
. Und das können alle schnell ;-)

Edelfix 5. Okt 2021 15:36

AW: TFDQuery und positionieren
 
Funktioniert leider nicht ganz so wie soll.

Es sollte eigentlich nur positionieren. Durch Top 50 zum Beispiel habe ich im DBGrid nur 50 Einträge.

Es sind dann "Max", "Maximilian" ... und so weiter dabei. Sieht erst einmal gut aus.

Insgesamt sind es aber 124.000 Einträge in der Kunden Datenbank. Jetzt srolle ich weiter runter und ende bei Eintrag 50.

Ich muss die suche wieder entfernen damit ich weiter srollen kann. Dadurch ist aber Positionierung wieder weg.

Es funktioniert nicht wenn ich die Datenmenge begrenze. Es müsste so etwas wie "Order BY" ab dem gesuchten Datensatz sein.

hoika 5. Okt 2021 16:02

AW: TFDQuery und positionieren
 
Hallo,
du könntest statt Locate First/Next benutzen, also von Hand suchen.
Vorher noch ein DisableControls, damit die Suche nicht sichtbar ist.
Und noch die Bookmark-Funktionen zum Merken des aktuellen Datensatzes (vor der Suche).

Besser find ich aber eine Suche direkt in der Query (wie weiter oben schon vorgeschlagen wurde).

Delphi.Narium 5. Okt 2021 16:30

AW: TFDQuery und positionieren
 
Wenn Du alle Datensätze haben willst, dann musst Du alle Datensätze laden. Dann geht nur Locate auf dem Client und dann geht nur langsam.

Das ist halt so, wenn man viele Daten auf dem Client hat und der dann selber suchen muss, gehen alle Vorteile, die eine Datenbank bietet, verloren.

SQL-Code:
select * from Kunden WHERE Vorname >= :Suchbegriff
liefert Dir alles ab dem Kunden, dessen Name >= Max ist und wenn Du da dann noch ein
SQL-Code:
select * from Kunden WHERE Vorname >= :Suchbegriff order by vorname
machst, dann sind alle Kunden ab Max aufsteigend sortiert nach Vorname. Und das können dann auch noch ein paar tausend Sätze zum Scrollen sein, mit entsprechende Laufzeiten. Aber Max wird dabei immer der erste sein, wenn es denn einen Kunden mit dem Vornamen Max geben sollte.
Und nein: Rückwärtsscrollen bis zum Vornamen Anton (o. Ä.) geht dann nicht.

Und wenn man mit Filtern arbeitet und es gibt nur einen Max, dann enthält das DBGrid auch nur einen Datensatz.

Wenn Du wirklich alle Datensätze laden und sehen willst und der Cursor, entsprechend des Suchbegriffes, positioniert werden soll, dann gibt es (meines Wissens) nur Locate und damit ist Deine Frage:
Zitat:

Zitat von Edelfix
Gibt es eine Alternative?

leider mit Nein zu beantworten.

Jasocul 6. Okt 2021 10:24

AW: TFDQuery und positionieren
 
Zitat:

Zitat von Edelfix (Beitrag 1495740)
Insgesamt sind es aber 124.000 Einträge in der Kunden Datenbank.

Konzeptioneller Fehler. Kein Anwender muss alle 124.000 Datensätze sehen.
Zitat:

Zitat von Edelfix (Beitrag 1495740)
Es müsste so etwas wie "Order BY" ab dem gesuchten Datensatz sein.

Und wie soll die Sortierung in den anderen Bereichen sein? :wink:

Ein order by kanst du immer in deine SQL-Abfrage einbauen. Die Einschränkung der Datensätze wäre noch mit einem "like" möglich. Das ist zwar nicht besonders performant, dürfte aber vermutlich immer noch schneller sein, als alle Datensätze zu holen und dann mit einem Locate zu arbeiten.

Edelfix 6. Okt 2021 11:50

AW: TFDQuery und positionieren
 
Ein Programm das nur Kunden Daten Anzeigt ist bissen dünne. Natürlich sind da noch andere Masken die mit diesen Daten arbeiten.
Wenn ich nach einem Kunden suche und direkt danach zu der Form mit Rechnungen wechsle dann denn Button „gehe zu Kunden“ klicke und der Kunde ist wegen einer reduzierten Datenmenge nicht vorhanden dann habe ich ein Problem.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:30 Uhr.
Seite 1 von 2  1 2      

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