Wie kann ich von Delphi (5) aus eine Abfrage, die zuvor z.B. über eine Query oder Stored Procedure gestartet wurde, auf dem SQL-Server abbrechen. Oder anders ausgedrückt, wie programmiere ich die Funktionalität des Abbrechen-Knopps im Query Analyzer von Delphi aus? Weiß jemand Rat?
Announcement
Collapse
No announcement yet.
Abbruch einer langandauernden Abfrage von Delphi aus (ADO)
Collapse
X
-
Hallo,
>..Funktionalität des Abbrechen-Knopps im Query Analyzer...
man muss an dieser Stelle penibel zwischen den beiden Phasen der Ausführung unterscheiden: <br>
a) Ergebnismenge der SELECT-Abfrage wird vom SQL-Server aufgebaut <br>
b) Ergebnismenge wird vom SQL-Server zum Client-Rechner übertragen<br>
Nur die Phase b) kann abgebrochen werden (d.h. die Phase a) wird in jedem Fall vollständig abgearbeitet).
Das folgende Beispiel für das Abbrechen der Phase B im eigenen Delphi-Programm stammt aus meinem Buch <i>ADO und Delphi</i>. Immer dann, wenn via <b>ADODataSet1.ExecuteOptions := [eoAsyncFetchNonBlocking]</b> das asynchrone Laden angefordert wird, können wird in der Ereignisbehandlungsmethode für <b>FetchProgress</b> den Ladevorgang abbrechen:
<pre>
{ ************************************************** **************
Typ : Hauptformular
Autor : Andreas Kosch
Compiler : Delphi 5 Enterprise
Betriebssystem : Windows 2000
Begonnen am : 22.12.2000
Beschreibung : Beispiel für das asynchrone Öffnen einer
Datenmenge, wobei der Ladevorgang abgebrochen
werden kann. Allerdings ist dies nur dann
erfolgreich, wenn in OnFetchProgress direkt
DataSet.RecordSet.Cancel aufgerufen wird,
der Aufruf von DataSet.Cancel ist wirkungslos
************************************************** ************** }
unit AsyncCancelFrm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Db, Grids, DBGrids, ADODB, ComCtrls, ActnList, Menus;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
ADODataSet1: TADODataSet;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
ButtonOpen: TButton;
ButtonClose: TButton;
Label1: TLabel;
EditLocate: TEdit;
StatusBar1: TStatusBar;
ActionList1: TActionList;
MainMenu1: TMainMenu;
MFile: TMenuItem;
MFClose: TMenuItem;
ActionExit: TAction;
ActionOpen: TAction;
ActionClose: TAction;
MDatabase: TMenuItem;
MDOpen: TMenuItem;
MDClose: TMenuItem;
CheckBoxAsync: TCheckBox;
ButtonCancel: TButton;
procedure EditLocateChange(Sender: TObject);
procedure ActionList1Update(Action: TBasicAction;
var Handled: Boolean);
procedure ActionExitExecute(Sender: TObject);
procedure ActionOpenExecute(Sender: TObject);
procedure ActionCloseExecute(Sender: TObject);
procedure ButtonCancelClick(Sender: TObject);
procedure ADODataSet1FetchProgress(DataSet: TCustomADODataSet;
Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
private
{ Private-Deklarationen }
FCancelAsyncLoad : Boolean;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ActionList1Update(Action: TBasicAction;
var Handled: Boolean);
begin
ButtonOpen.Enabled := not ADODataSet1.Active;
ButtonClose.Enabled := ADODataSet1.Active;
Handled := True;
end;
procedure TForm1.EditLocateChange(Sender: TObject);
var
sTxt : String;
begin
sTxt := EditLocate.Text;
if sTxt <> '' then
with ADODataSet1 do
Locate('PLZ', sTxt, [loCaseInsensitive, loPartialKey]);
end;
procedure TForm1.ActionExitExecute(Sender: TObject);
begin
Close
end;
procedure TForm1.ActionOpenExecute(Sender: TObject);
begin
FCancelAsyncLoad := False;
if CheckBoxAsync.Checked then
ADODataSet1.ExecuteOptions := [eoAsyncFetchNonBlocking]
else
ADODataSet1.ExecuteOptions := [];
ADODataSet1.Active := True;
end;
procedure TForm1.ButtonCancelClick(Sender: TObject);
begin
FCancelAsyncLoad := True;
end;
procedure TForm1.ActionCloseExecute(Sender: TObject);
begin
ADODataSet1.Active := False;
end;
procedure TForm1.ADODataSet1FetchProgress(DataSet: TCustomADODataSet;
Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
begin
StatusBar1.SimpleText := Format('%d Datensätze geladen',
[DataSet.RecordCount]);
if FCancelAsyncLoad then
DataSet.RecordSet.Cancel; // DataSet.Cancel ist wirkungslos !
Application.ProcessMessages;
end;
end.
</pre>
Comment