![]() |
Datenbank: InterBase • Version: 6.1 • Zugriff über: IBObjects
Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Hallo Leute,
wir arbeiten mit Delphi 5 und den IBObjects (TIBOQuery usw.). Gibt es die Möglichkeit, eine Query, ein Table oder irgendein anderes TDataSet so zu benutzen, dass es sich die Daten nicht aus der Datenbank, sondern aus einer anderen Query holt? Das Anwendungsszenario sieht folgendermaßen aus: Ich habe eine Tabelle, in der gesucht werden kann. Die Daten werden währenddessen in einem Tabellen-Control angezeigt. Nun möchte ich, dass sich bei jedem Tastenanschlag in einem Suchfeld die Anzeige weiter einschränkt. Ich kann also nicht jedes Mal eine neue DB-Anfrage machen, nur um eine Teilmenge der schon geholten Daten nochmals zu holen. Stattdessen möchte ich einfach die schon bekannten Daten nutzen und davon nur eine Teilmenge darstellen. Es handelt sich um größere Datenmengen (mehrere 10.000 Datensätze). Ich weiß, dass das TClientDataSet dazu wie geschaffen ist. Dessen Einsatz steht aber außer Frage, da wir noch in Delphi 5 programmieren und hier die Nutzung nur erfolgen kann, wenn die midas.dll auf allen Clients installiert und registriert ist (Uses LibMidas ist erst ab D6 möglich) und das können wir nicht sicherstellen. |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Moin, Moin,
Die Idee eine Query mit dem kompletten Datenbestand einmalig öffnen, und dann mit einer weiteren Query darauf zu greifen wird nicht funktionieren ! Schon mal über die Verwendung eines Filters nachgedacht, oder eventuell mit Locate arbeiten ? Die bessere Alternative für eine schnelle Suche innerhalb der Daten ist auf jeden Fall die Daten gut und geschickt zu indizieren, und alle Möglichkeiten Deines Datenbankservers zu nutzen. Was für eine RDBMS setzt Du denn ein ? (Ups, wer lesen kann ....) Beste Grüße Michael |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Wenn ich bei jedem Tastenanschlag eine DB-Abfrage starten würde, dann wäre das einfach nur elendig langsam. Allein die Latenz durch das LAN ist doch schon zu langsam dafür - egal wie schnell der Server reagieren würde. Deshalb möchte ich die Einschränkung lokal berechnen, und zwar vorzugsweise nur für so viele Datensätze wie ich grad brauche (wie angezeigt werden).
Tastenanschlag -> Grid unter Berücksichtigung der neuen Bedingungen mit so vielen Datensätzen füllen, wie angezeigt werden Das Ganze muss also in Sekundenbruchteilen (Hundertstel) passieren! |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
klingt so als ob Du Filter verwenden solltest ....
|
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Ich denke, der Ansatz ist nicht optimal. Ein Tastenanschlag (bzw. Suchänderung) könnte ja auch bedeuten, dass aus dem Suchstring etwas gelöscht wurde. Dann kommst Du mit einer weiteren Subfilterung nicht mehr zurecht.
Du solltest versuchen, immer komplett neu zu selectieren/zu filtern und diesen Vorgang bestmöglich zu optimieren. Das wäre jedenfalls mein Ansatz. Ich habe ein altes Projekt, bei dem ich anhand von Sucheingaben einen Datensatz lokalisiere. Das erfolgt bei jeder Suchtextänderung indem erst in einer Straßen-Tabelle nach einem passenden Straßenindex gesucht wird und dann in einer Grundstücks-Tabelle nach dem Straßenindex und der passenden Hausnummer. Durch die Trennung in zwei Tabellen und Index-Verwendung geht das sehr schnell. Vielleicht kannst Du ja Deine DB noch optimieren? |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Zitat:
Dieses lokale Filtern geht wohl z.B. in FibPlus. Zitat:
Ich weiß ja nicht, was du als "Tabellencontrol" benutzt. Aber allein das Neu Laden der gefilterten Daten in der Grid dauert lange genug. Aus gutem Grunde gibt es dieses Verhalten in diversen LookUp - Komponenten. Aber ich würde nie auf die Idee kommen, eine Rechnung über ein LookUp zu suchen. Für Anreden, Mengenneinheiten - eben kleinere Tabellen - ist das OK. Aber wenn du es versuchen willst, dann benutze diverse MemDatasets. Diese können meist per Assign Daten und Struktur eines TDataSet übernehmen. Ich würde aber bei so vielen Daten immer Eingabe - Enter - Suchen bevorzugen. Evtll. noch durch einen Timer, welcher nach ca. 1 Sekunde Pause automatisch filtert. Frank |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Ich habe mich jetzt ein wenig zu TIBOQuery und Filtern belesen. In den IBO-FAQ steht folgendes:
Zitat:
|
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
hat die Komponente eventuell ein onFilterRecord Ereignis?
In dem Ereignis kannst Du nach Deinen Kriterien Filtern. Ich nutze es mit TMSQuery da funktioniert es super und blitz schnell |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Zitat:
|
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Zitat:
|
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Und mit FIRST statt TOP?
|
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Mit FIRST auch nicht, und LIMIT kann er auch nicht. Auszug aus der mir vorliegenden Hilfedatei:
Code:
SELECT [TRANSACTION transaction]
[DISTINCT | ALL] {* | <val> [, <val> …]} [INTO :var [, :var …]] FROM <tableref> [, <tableref> …] [WHERE <search_condition>] [GROUP BY col [COLLATE collation] [, col [COLLATE collation] …] [HAVING <search_condition>] [UNION <select_expr> [ALL]] [PLAN <plan_expr>] [ORDER BY <order_list>] [FOR UPDATE [OF col [, col …]]]; <val> = { col [<array_dim>] | :variable | <constant> | <expr> | <function> | udf ([<val> [, <val> …]]) | NULL | USER | RDB$DB_KEY | ? } [COLLATE collation] [AS alias] <array_dim> = [[x:]y [, [x:]y …]] <constant> = num | 'string' | charsetname 'string' <function> = COUNT (* | [ALL] <val> | DISTINCT <val>) | SUM ([ALL] <val> | DISTINCT <val>) | AVG ([ALL] <val> | DISTINCT <val>) | MAX ([ALL] <val> | DISTINCT <val>) | MIN ([ALL] <val> | DISTINCT <val>) | CAST (<val> AS <datatype>) | UPPER (<val>) | GEN_ID (generator, <val>) <tableref> = <joined_table> | table | view | procedure [(<val> [, <val> …])] [alias] <joined_table> = <tableref> <join_type> JOIN <tableref> ON <search_condition> | (<joined_table>) <join_type> = [INNER] JOIN | {LEFT | RIGHT | FULL } [OUTER]} JOIN <search_condition> = <val> <operator> {<val> | ( <select_one>)} | <val> [NOT] BETWEEN <val> AND <val> | <val> [NOT] LIKE <val> [ESCAPE <val>] | <val> [NOT] IN (<val> [, <val> …] | <select_list>) | <val> IS [NOT] NULL | <val> {>= | <=} | <val> [NOT] {= | < | >} | {ALL | SOME | ANY} (<select_list>) | EXISTS (<select_expr>) | SINGULAR (<select_expr>) | <val> [NOT] CONTAINING <val> | <val> [NOT] STARTING [WITH] <val> | (<search_condition>) | NOT <search_condition> | <search_condition> OR <search_condition> | <search_condition> AND <search_condition> <operator> = {= | < | > | <= | >= | !< | !> | <> | !=} <plan_expr> = [JOIN | [SORT] [MERGE]] ({<plan_item> | <plan_expr>} [, {<plan_item> | <plan_expr>} …]) <plan_item> = {table | alias} {NATURAL | INDEX (<index> [, <index> …])| ORDER <index >} <order_list> = {col | int} [COLLATE collation] [ASC[ENDING] | DESC[ENDING]] [, <order_list> …] |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Wenn ich einen Filter setze, gibt es eine Exception sobald ich FindFirst aufrufe (Filtered = False!). Er zerschießt das SQL irgendwo innerhalb von FindFirst, daher habe ich noch nicht einmal das zerschossene SQL als Text zur Analyse. Ich werde morgen noch den OnFilterRecord Event ausprobieren.
IBO Version 3.4.Ce auf Delphi 5 |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Hallo,
wenn es sich nur um die Daten einer Tabelle/Query handelt, kannst du das TOP/LIMIT mit einer Stored Procedure nachbauen, und ja, dass kann IB seit Version 4.2 ;) Heiko |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
OnFilterRecord wird bei meiner Version von IBObjects (3.4.Ce) aufgrund eines Bugs nicht/nur manchmal aufgerufen. Da ich aber die Ergebnisse sowieso in ein Stringgrid einlese, kann ich ja auch beim Einlesen selbst aussortieren... Das Einfache liegt so nahe, dass man es übersieht!
Ich lese also ein, bis der nächste Tastenanschlag kommt, dann wird abgebrochen. Durch den neuen Tastenanschlag wird das Einlesen neu gestartet. Während des Einlesens habe ich ein Application.Processmessages eingebaut. Das ermöglicht mir Eingaben im Suchfeld (etwas hakelig, aber geht). DoClose und CloseQuery werden aber komischerweise erst ausgeführt, nachdem das Einlesen beendet ist, so dass ich es nicht abbrechen kann, wenn die Form geschlossen werden soll. Wieso wird das nicht beim nächsten Application.Processmessages aufgerufen? |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Zitat:
Delphi-Quellcode:
... und das hängt so lange in Application.HandleMessage, bis ich alle Daten eingelesen habe und damit die Prozedur beende.
repeat
Application.HandleMessage; if Application.FTerminate then ModalResult := mrCancel else if ModalResult <> 0 then CloseModal; until ModalResult <> 0; |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
Eine live-Suche über eine Query lösen zu wollen, ist sportlich. I.a. werden die Daten schon geeignet im Speicher abgelegt, z.B. in einem Baum, Trie o.ä.
Als in-memory Kopie einer Tabelle würde ich eine in-memory Tabelle empfehlen :stupid: z.B. "kbMemTable" oder ein TClientDataset. Ich würde allerdings würde die Daten wirklich einsaugen und in einer geeigneten Struktur ablegen. Ich kann mir vorstellen, das man alles in einen String klatscht, mit geeigneten Feld/Recordtrennern und dann ein sauschnelles Pos drüber laufen lässt. Wonach soll denn überhaupt gesucht werden? |
AW: Tabelle/Query, die ihre Daten aus einer anderen Query bezieht
@Iwo Asnet:
Wenn du von Anfang an liest, wirst du feststellen, dass ich TClientDataSet ausgeschlossen habe incl. des Grundes. An die IBObjects als Zugriffmöglichkeit auf die DB bin ich gebunden, die setzen wir im ganzen Programm ein. Mein genannter Ansatz funktioniert inzwischen einwandfrei, damit habe ich meine Lösung gefunden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:50 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