![]() |
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. |
AW: TFDQuery und positionieren
Wenn es nur einen Benutzer "Max" gibt, bekommst Du logischerweise auch nur einen Datensatz. Kann es sein, dass Du eher
![]() |
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? |
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.
|
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:
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.
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,[]); 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:
. Und das können alle schnell ;-)
Query.SQL.Text := 'SELECT * FROM Kunden WHERE Vorname = :Suchbegriff';
|
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. |
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). |
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:
liefert Dir alles ab dem Kunden, dessen Name >= Max ist und wenn Du da dann noch ein
select * from Kunden WHERE Vorname >= :Suchbegriff
SQL-Code:
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.
select * from Kunden WHERE Vorname >= :Suchbegriff order by vorname
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:
|
AW: TFDQuery und positionieren
Zitat:
Zitat:
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. |
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 07:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz