![]() |
Datenbank: Firebird • Version: 1.5 • Zugriff über: IBExpress
SQL-Select während der Ausführung wieder abbrechen
Ich arbeite mit Firebird und IBExpress und möchte dem Anwender die Möglichkeit bieten, einen langwierigen Select-Befehl wieder abzubrechen. Hier ergeben sich nun zwei Probleme, nachdem ich das ClientDataSet.Open aufgerufen habe.
1. Ich muss ein geeignetes Ereignis (z.b. Tastendruck oder Mausklick) abfangen, obwohl das Programm das OPEN ausführt. 2. Ich muss dann das OPEN von außen stoppen können. Ich habe einen Ansatz über Threads versucht, habe aber mit der Thread-Programmierung wenig Erfahrung. Das Abfangen des Ereignisses funktioniert problemlos. Mit TerminateThread kann ich auch den Thread, der das OPEN ausführt radikal beenden. Ich frage mich aber, ob dieser radikale Abbruch überhaupt sinnvoll und zulässig ist. Meistens scheint es zwar zu funktionieren, manchmal habe ich aber hinterher Probleme bei Programmende, so als wären irgendwelche Speicherbereiche nicht korrekt freigegeben worden. Das Programm hängt sich dann ohne Fehlermeldung auf. Meine Fragen: 1. Ist der Ansatz überhaupt der richtige? Welche Alternativen sind möglich? 2. Gibt es irgendwelche Randbedingungen, die beim TerminateThread zu beachten sind? 3. Kennt jemand zu diesem Problem bereits einen anderen Beitrag in der Delphi Praxis oder irgend ein geeignetes sonstiges Dokument? Dank für jede Hilfe! Daddy |
Re: SQL-Select während der Ausführung wieder abbrechen
Hallo,
ab FB2 (oder 2.1 ?) kann eine Transaktion unterbrochen werden (Release Notes). Bei IBX geht das aber trotzdem nicht. Das mit den Threads geht auch, ![]() Es sollte mindestens eine eigene Transaktions-Komponente benutzt werden. Heiko |
Re: SQL-Select während der Ausführung wieder abbrechen
Hallo... :hi:
Zitat:
Ich verwende teilweise komplexe SQL´s. Der Nutzer hätte gar keine Chance den Vorgang zu "unterbrechen", da die Daten ruck-zuck im Dataset sind. Was hälst du denn vom Verwerfen des Datasets wenn der Nutzer das Ergebnis nicht sehen will ? :zwinker: Nachtrag: Kann der User das SQL selbst eingeben ? Wenn ja, dann ist mir klar was du meinst... :zwinker: |
Re: SQL-Select während der Ausführung wieder abbrechen
@haentschman
Zitat:
Zitat:
|
Re: SQL-Select während der Ausführung wieder abbrechen
Hallo,
Zitat:
D.h., innerhalb der
Delphi-Quellcode:
while not Query.Eof do
begin // hier unterbrechen Query.Next; end; Heiko |
Re: SQL-Select während der Ausführung wieder abbrechen
Zitat:
Gruß Daddy |
Re: SQL-Select während der Ausführung wieder abbrechen
Zitat:
|
Re: SQL-Select während der Ausführung wieder abbrechen
Zitat:
Die Diskussion führt inzwischen in eine völlig falsche Richtung. Ich möchte einfach nur nach dem OPEN noch Zugriff von außen haben. Warum das OPEN nun langwierig ist oder nicht ist in diesem Zusammenhang ja eigentlich völlig unerheblich. |
Re: SQL-Select während der Ausführung wieder abbrechen
hmmm... :gruebel:
mir fallen da eigentlich nur 2 Varianten ein: 1. das Open in einem Thread ablaufen lassen und ggf. abschießen (wie schon erwähnt) 2. während der Server die Daten "zusammensucht" kannst du eh nicht eingreifen. Vieleicht gibt es eine Möglichkeit am Dataset anzusetzen wenn die Daten eintrudeln. Mit jedem DS wird doch "OnSroll" aufgerufen. Was würde passieren, wenn man das Dataset einfach mittendrin freigibt ? 3. ein Tool programmieren was auf dem Server läuft, das den Report zusammenstellt und dann z.B. als File zur Verfügung stellt. ...alles in allem wird das nur über "schmutzige" Tricks funktionieren. :hi: |
Re: SQL-Select während der Ausführung wieder abbrechen
Also nach Euren Kommentaren habe ich mir das noch einmal genauer angesehen. Wie gesagt, ich rufe an der Stelle, um die es mir geht, einfach nur ClientDataSet.Open auf. Aber im Hintergrund passiert natürlich mehr. Das ClientDataSet ist mit einem DataSetProvider verknüpft, der sich die Daten über ein SQLDataSet holt. Das SQLDataSet greift auf den Firbird Server zu. Nach dem OPEN des ClientDataSet wird nun tatsächlich relativ schnell (und immer wieder) das OnAfterScroll des SQLDataSet durchlaufen, nämlich während die Daten in das ClientDataSet geschoben werden. Insofern könnte ich auch an dieser Stelle eingreifen und müsste dem ClientDataSet oder dem Provider mitteilen, dass keine weiteren Daten notwendig sind. Gibt es hierfür einen Aufruf?
|
Re: SQL-Select während der Ausführung wieder abbrechen
:-D Hab zwar keine Antwort auf meine ursprüngliche Frage erhalten, aber dank Eurer Hinweise dennoch eine Lösung für mein Problem gefunden. Ich trage jetzt beim ClientDataSet in der Eigenschaft "PacketRecords" einen Wert abweichend vom Default -1 ein (z.B. 500). Dann wird das ClientDataSet.Open ausgeführt, holt sich aber erst einmal nur 500 Datensätze. Anschließend läuft mein Programmcode weiter und Rave wird aufgerufen. Rave holt sich dann nach und nach die weiteren Datenpakete. Da ich aber für Rave ohnehin schon eine Aussprungsmöglichkeit während des Aufbaus der Seiten vorgesehen hatte, hat der Anwender nun die Möglichkeit die Datenermittlung und Druckausgabe rechtzeitig zu verhindern. Mit den 1 bis 2 Sekunden, während derer das nicht möglich ist, kann ich (und sicher auch der Anwender) leben.
Falls aber noch jemand eine Antwort auf meine in #10 gestellte Frage weiss, wäre ich daran weiterhin interessiert. Ansonsten vielen Dank! :cheers: Daddy |
Re: SQL-Select während der Ausführung wieder abbrechen
:wall: Hmmm! Meine Begeisterung war vielleicht etwas voreilig.
Es kann ja auch vorkommen, dass ein Rave Report einfach nur das Ergebnis einer Aufsummierung anzeigen soll. Um also den Einwand aus #3 zu entkräften, kann man ja einfach mal annehmen, dass eine Million Datensätze, die dann vielleicht noch über zwei left joins mit anderen Tabellen verknüpft sind, gelesen und addiert werden müssen. Und das Ergebnis wird anschließend in der Druckvorschau angezeigt oder direkt auf dem Drucker ausgegeben. Das wird ja auch auf einem schnellen System schon mal 10 oder deutlich mehr Sekunden dauern können. In meinem Programm lässt sich z.B. eine Fünf-Jahres-Entwicklung der Umsatzzahlen abfragen und da können schon eine ganze Menge Daten anfallen. Dann wäre es natürlich doch von Vorteil eine Antwort auf #1 oder #10 zu bekommen, um solch ein Select wieder anzuhalten. Hat also vielleicht doch jemand eine Idee? :gruebel: |
Re: SQL-Select während der Ausführung wieder abbrechen
Zitat:
Mit dem Dependency Walker lässt du dir die Funktionen anzeigen. Über eine Suchmaschine nach den Funktionsnamen suchen und die Deklarationen als *.pas oder *.h auftreiben. Ich weiss nicht, ob ich auf dem falschen Dampfer bin, weil ich hier keine fbclient.dll vorliegen habe, aber es gibt anscheinend eine Funktion:
Delphi-Quellcode:
Die Vermutung liegt nahe dass man isc_dsql_finish() vielleicht schon aufrufen kann, wenn die Query noch gar nicht fertig ist.
function isc_dsql_finish(db_handle : PISC_DB_HANDLE): ISC_STATUS;stdcall; external IBASE_DLL;
Also untersuchst du erst mal, wo isc_dsql_finish() in der Zeos-Lib aufgerufen wird. Vielleicht ist ein vorzeitiger Abbruch schon vorgesehen oder man kann es durch eine kleine Erweiterung nachrüsten. u.s.w. eben Reverse Engineering |
Re: SQL-Select während der Ausführung wieder abbrechen
Hallo,
um noch mal zum Thema zu kommen ... Ab FB2.1 (oder schon 2.0 ?) besteht die Möglichkeit, eine laufende Query zu beenden, und zwar über die Monitoring Tables. ![]() Suche dort nach Cancel a Running Query Das das in einem anderen Thread passieren muss, sollte klar sein. Heiko |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:00 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