Announcement

Collapse
No announcement yet.

Abbruch einer langandauernden Abfrage von Delphi aus (ADO)

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Abbruch einer langandauernden Abfrage von Delphi aus (ADO)

    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?

  • #2
    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&gt

    Comment

    Working...
    X