Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi SQL-Select während der Ausführung wieder abbrechen (https://www.delphipraxis.net/147622-sql-select-waehrend-der-ausfuehrung-wieder-abbrechen.html)

daddy 12. Feb 2010 14:46

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

hoika 12. Feb 2010 14:58

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,
1

Es sollte mindestens eine eigene Transaktions-Komponente benutzt werden.


Heiko

haentschman 12. Feb 2010 16:05

Re: SQL-Select während der Ausführung wieder abbrechen
 
Hallo... :hi:

Zitat:

Ich arbeite mit Firebird und IBExpress und möchte dem Anwender die Möglichkeit bieten, einen langwierigen Select-Befehl wieder abzubrechen.
verstehe ich nicht wirklich wie "langwierig" das SQL sein soll :gruebel:
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:

daddy 12. Feb 2010 16:54

Re: SQL-Select während der Ausführung wieder abbrechen
 
@haentschman

Zitat:

verstehe ich nicht wirklich wie "langwierig" das SQL sein soll Grübelnd...
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.
Im Prinzip ist Firebird in der Tat extrem schnell. Aber, wenn ich z.B. eine Inventurliste mit sagen wir mal 400 Seiten drucke, kann das eben doch eine (kurze) Weile dauern, bis die Daten verfügbar sind. Erst recht, wenn die Abfrage online über eine VPN-Anbindung erfolgt. Und wenn der Anwender dann merkt, dass er die Liste vielleicht doch grad gar nicht haben möchte, sollte es möglich sein, dieses auch während der Ausführung des Selects schon zu unterbrechen.

Zitat:

Was hälst du denn vom Verwerfen des Datasets wenn der Nutzer das Ergebnis nicht sehen will ?
Meinst Du das Select im Hintergrund weiterlaufen zu lassen und anschließend damit nichts zu machen? Wär natürlich im Prinzip möglich, würde aber den Server unnötig belasten und unnötigen Datentraffic zum Client bedeuten! Also keine optimale Lösung.

hoika 12. Feb 2010 17:08

Re: SQL-Select während der Ausführung wieder abbrechen
 
Hallo,

Zitat:

Und wenn der Anwender dann merkt, dass er die Liste vielleicht doch grad gar nicht haben möchte
Hm, ist hier das "Rüberziehen" der Daten vom Server nicht der Flaschenhals ?

D.h., innerhalb der

Delphi-Quellcode:
while not Query.Eof do
begin

 // hier unterbrechen

  Query.Next;
end;

Heiko

daddy 12. Feb 2010 17:27

Re: SQL-Select während der Ausführung wieder abbrechen
 
Zitat:

Hm, ist hier das "Rüberziehen" der Daten vom Server nicht der Flaschenhals ?
Nein, da so eine Schleife in meinem Programm nicht existiert. Ich rufe ja nur - wie in #1 erwähnt - ClientDataSet.Open auf. Danach wird die Datenmenge von Rave weiter verwendet. Bei der Erzeugung des Rave Reports ist eine Unterbrechung möglich, beim OPEN aber noch nicht zuverlässig. Ich werde jetzt mal prüfen, ob eine explizite Transaktion irgendetwas ändert. Bin aber weiter für Hinweise dankbar.

Gruß

Daddy

mkinzler 12. Feb 2010 18:13

Re: SQL-Select während der Ausführung wieder abbrechen
 
Zitat:

Zitat:
Hm, ist hier das "Rüberziehen" der Daten vom Server nicht der Flaschenhals ?


Nein, da so eine Schleife in meinem Programm nicht existiert. Ich rufe ja nur - wie in #1 erwähnt - ClientDataSet.Open auf.
Und die daten werden dann zum Client gebeamt?

daddy 12. Feb 2010 18:45

Re: SQL-Select während der Ausführung wieder abbrechen
 
Zitat:

Und die daten werden dann zum Client gebeamt?
Wohl kaum, aber alles weitere geschieht dann im Rave.

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.

haentschman 12. Feb 2010 19:09

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:

daddy 12. Feb 2010 19:56

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?

daddy 12. Feb 2010 21:26

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

daddy 12. Feb 2010 21:57

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:

sx2008 12. Feb 2010 23:29

Re: SQL-Select während der Ausführung wieder abbrechen
 
Zitat:

Zitat von daddy
Hat also vielleicht doch jemand eine Idee? :gruebel:

Du müsstest dir die fbclient.dll direkt vornehmen.
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:
function isc_dsql_finish(db_handle : PISC_DB_HANDLE): ISC_STATUS;stdcall; external IBASE_DLL;
Die Vermutung liegt nahe dass man isc_dsql_finish() vielleicht schon aufrufen kann, wenn die Query noch gar nicht fertig ist.

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

hoika 13. Feb 2010 06:39

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.

Release Notes

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