unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, DBCtrls, Grids, DBGrids, ExtCtrls,
ActiveX // CoInitialize
;
type
TCallbackProc = procedure (aMessage: string; aMessageInfo: Integer = 0) of object;
TCallbackThread = class(TThread)
private
FCallBack : TCallbackProc;
FCallbackMsg : string;
FCallbackMsgInfo: integer;
procedure SynchedCallback;
protected
procedure DoCallback(aMsg: string; aMsgInfo: integer = 0); virtual;
property Callback: TCallbackProc read FCallback;
public
constructor Create(aCallback: TCallbackProc; CreateSuspended: Boolean = False); reintroduce; virtual;
end;
TExecStoredProcThread = class(TCallbackThread)
private
fSQLQuery : TStrings;
fConnectionString: string;
fDatasource : TDatasource;
fADOQuery : TADOQuery;
fADOConnection : TADOConnection;
protected
procedure Execute; override;
public
constructor Create(aCallback: TCallbackProc; aConnectionString, aSQLQuery: string; aDataSource: TDataSource); reintroduce; virtual;
destructor Destroy; override;
end;
TForm1 = class(TForm)
Panel1 : TPanel;
DBGrid1 : TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1 : TDataSource;
StartQuery : TButton;
Memo1 : TMemo;
procedure StartQueryClick(Sender: TObject);
private
{ Private declarations }
fExecStoredProcThread: TExecStoredProcThread;
procedure StoredProcCallback(aMessage: string; aMessageInfo: Integer = 0);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.StartQueryClick(Sender: TObject);
begin
if not Assigned(fExecStoredProcThread) then
begin
fExecStoredProcThread := TExecStoredProcThread.Create(StoredProcCallback, 'Provider=MSDASQL.1;Persist Security Info=False;Data Source=Employee Database', Memo1.Lines.Text, DataSource1);
end;
end;
{ TCallbackThread }
constructor TCallbackThread.Create(aCallback: TCallbackProc;
CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
FCallback := aCallback;
end;
procedure TCallbackThread.DoCallback(aMsg: string; aMsgInfo: integer);
begin
FCallbackMsg := aMsg;
FCallbackMsgInfo := aMsgInfo;
Synchronize(SynchedCallback);
end;
procedure TCallbackThread.SynchedCallback;
begin
if Assigned(FCallback) then
FCallBack(FCallbackMsg, FCallbackMsgInfo);
end;
{ TExecStoredProcThread }
constructor TExecStoredProcThread.Create(aCallback: TCallbackProc;
aConnectionString, aSQLQuery: string; aDataSource: TDataSource);
begin
inherited Create(aCallback);
CoInitialize(nil);
fConnectionString := aConnectionString;
fSQLQuery := TStringList.Create;
fSQLQuery.Text := aSQLQuery;
fADOConnection := TADOConnection.Create(nil);
fADOConnection.ConnectionString := aConnectionString;
fADOConnection.LoginPrompt := FALSE;
fADOConnection.Provider := 'MSDASQL.1';
fDataSource := aDataSource;
end;
destructor TExecStoredProcThread.Destroy;
begin
FreeAndNil(fADOConnection);
FreeAndNil(fSQLQuery);
inherited Destroy;
end;
procedure TExecStoredProcThread.Execute;
begin
DoCallback('Starting threaded procedure');
try
fADOConnection.Connected := TRUE;
try
DoCallback('Connected threaded procedure');
try
fADOQuery.CommandTimeout := 3600; // 1 hour
fADOQuery.SQL.Clear;
fADOQuery.SQL.AddStrings(fSQLQuery);
fADOQuery.Active := TRUE;
fADOQuery.ExecSQL;
DoCallback('Threaded procedure executed Ok, 1');
except
on E: Exception do
DoCallback('Error in running threaded procedure: '#13#10 + E.Message, 20);
end;
finally
fADOConnection.Connected := FALSE;
end;
DoCallback('Disconnected threaded procedure');
except
on E: Exception do
DoCallback('Error in connecting threaded procedure: '#13#10 + E.Message, 10);
end;
DoCallback('Finished threaded procedure');
end;
procedure TForm1.StoredProcCallback(aMessage: string;
aMessageInfo: Integer);
begin
Memo1.Lines.Add('>>> '+aMessage);
end;
end.
procedure TExecStoredProcThread.Execute;
begin
CoInitialize(nil);
DoCallback('Starting threaded procedure');
try
fADOConnection.Connected := TRUE;
try
DoCallback('Connected threaded procedure');
try
fADOQuery.CommandTimeout := 3600; // 1 hour
fADOQuery.SQL.Clear;
fADOQuery.SQL.AddStrings(fSQLQuery);
fADOQuery.Active := TRUE;
fADOQuery.ExecSQL;
DoCallback('Threaded procedure executed Ok, 1');
except
on E: Exception do
DoCallback('Error in running threaded procedure: '#13#10 + E.Message, 20);
end;
finally
fADOConnection.Connected := FALSE;
end;
DoCallback('Disconnected threaded procedure');
except
on E: Exception do
DoCallback('Error in connecting threaded procedure: '#13#10 + E.Message, 10);
end;
DoCallback('Finished threaded procedure');
CoUninitialize;
end;
fADOQuery.DataSource := fDatasource; // <------ forgot this
fADOQuery.CommandTimeout := 3600; // 1 hour
fADOQuery.SQL.Clear;
fADOQuery.SQL.AddStrings(fSQLQuery);
fADOQuery.Active := TRUE;
fADOQuery.ExecSQL;
DoCallback('Threaded procedure executed Ok, 1');
TfrmPreview = class(TForm)
vtData: TVirtualTable;
end;
procedure TfrmPreview.FlashTaskbarButton;
var
FWinfo: FlashWInfo;
begin
FWinfo.cbSize := 20;
FWinfo.hwnd := Handle; // Handle of Window to flash
FWinfo.dwflags := FLASHW_ALL;
FWinfo.ucount := 3; // number of times to flash
FWinfo.dwtimeout := 0; // speed in ms, 0 default blink cursor rate
FlashWindowEx(FWinfo); // make it flash!
end;
procedure TfrmPreview.LoadData(ds: TDataset);
var I: Integer;
begin
viewData.BeginUpdate;
try
if Assigned(ds) then
begin
vtData.Assign(ds);
vtData.Active := True;
viewData.DataController.CreateAllItems;
for I := 0 to viewData.ColumnCount-1 do
begin
viewData.Columns[I].DataBinding.ValueTypeClass := TcxStringValueType;
viewData.Columns[I].PropertiesClass := TcxTextEditProperties;
end;
end else
viewData.ClearItems;
finally
viewData.EndUpdate;
end;
viewData.BeginUpdate;
try
viewData.ApplyBestFit;
finally
viewData.EndUpdate;
end;
FlashTaskbarButton;
end;
procedure TfrmPreview.QueryFinished(Sender: TObject; aQry: TDacQuery; ErrorMessage: string);
begin
if Assigned(aQry) and not fBThreadTerminated then
begin
if ErrorMessage <> '' then
begin
pnlErrorMessage.Visible := True;
lblErrMessage.Caption := ErrorMessage;
end else
LoadData(aQry.Dataset);
end;
end;
procedure TfrmPreview.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, DBCtrls, Grids, DBGrids, ExtCtrls,
ActiveX // CoInitialize
;
type
TCallbackProc = procedure (aMessage: string; aMessageInfo: Integer = 0) of object;
TCallbackThread = class(TThread)
private
FCallBack : TCallbackProc;
FCallbackMsg : string;
FCallbackMsgInfo: integer;
procedure SynchedCallback;
protected
procedure DoCallback(aMsg: string; aMsgInfo: integer = 0); virtual;
property Callback: TCallbackProc read FCallback;
public
constructor Create(aCallback: TCallbackProc; CreateSuspended: Boolean = False); reintroduce; virtual;
end;
TExecStoredProcThread = class(TCallbackThread)
private
fConnectionString: string;
fADOConnection : TADOConnection;
fADOQuery : TADOQuery;
protected
procedure Execute; override;
public
constructor Create(aCallback: TCallbackProc; aConnectionString: string; Query: TADOQuery); reintroduce; virtual;
destructor Destroy; override;
end;
TForm1 = class(TForm)
Panel1 : TPanel;
DBGrid1 : TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1 : TDataSource;
StartQuery : TButton;
Memo1 : TMemo;
ADOQuery1: TADOQuery;
procedure StartQueryClick(Sender: TObject);
private
{ Private declarations }
fExecStoredProcThread: TExecStoredProcThread;
procedure StoredProcCallback(aMessage: string; aMessageInfo: Integer = 0);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.StartQueryClick(Sender: TObject);
begin
if not Assigned(fExecStoredProcThread) then
begin
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Assign(Memo1.Lines);
ADOQuery1.DataSource := DataSource1;
fExecStoredProcThread := TExecStoredProcThread.Create(StoredProcCallback, 'Provider=MSDASQL.1;Persist Security Info=False;Data Source=Employee Database', ADOQuery1);
end;
end;
{ TCallbackThread }
constructor TCallbackThread.Create(aCallback: TCallbackProc;
CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
FCallback := aCallback;
end;
procedure TCallbackThread.DoCallback(aMsg: string; aMsgInfo: integer);
begin
FCallbackMsg := aMsg;
FCallbackMsgInfo := aMsgInfo;
Synchronize(SynchedCallback);
end;
procedure TCallbackThread.SynchedCallback;
begin
if Assigned(FCallback) then
FCallBack(FCallbackMsg, FCallbackMsgInfo);
end;
{ TExecStoredProcThread }
constructor TExecStoredProcThread.Create(aCallback: TCallbackProc; aConnectionString: string; Query: TADOQuery);
begin
inherited Create(aCallback);
fConnectionString := aConnectionString;
fADOQuery := Query;
fADOConnection := TADOConnection.Create(nil);
fADOConnection.ConnectionString := aConnectionString;
fADOConnection.LoginPrompt := FALSE;
fADOConnection.Provider := 'MSDASQL.1';
end;
destructor TExecStoredProcThread.Destroy;
begin
FreeAndNil(fADOConnection);
inherited Destroy;
end;
procedure TExecStoredProcThread.Execute;
begin
CoInitialize(nil);
DoCallback('Starting threaded procedure');
try
fADOConnection.Connected := TRUE;
try
DoCallback('Connected threaded procedure');
try
fADOQuery.Connection := fADOConnection;
fADOQuery.CommandTimeout := 3600; // 1 hour
fADOQuery.Active := TRUE;
fADOQuery.ExecSQL;
DoCallback('Threaded procedure executed Ok, 1');
except
on E: Exception do
DoCallback('Error in running threaded procedure: '#13#10 + E.Message, 20);
end;
finally
fADOConnection.Connected := FALSE;
end;
DoCallback('Disconnected threaded procedure');
except
on E: Exception do
DoCallback('Error in connecting threaded procedure: '#13#10 + E.Message, 10);
end;
DoCallback('Finished threaded procedure');
CoUninitialize;
end;
procedure TForm1.StoredProcCallback(aMessage: string;
aMessageInfo: Integer);
begin
Memo1.Lines.Add('>>> '+aMessage);
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DB, ADODB, DBCtrls, Grids, DBGrids, ExtCtrls,
ActiveX // CoInitialize
;
type
TCallbackProc = procedure (aMessage: string; aMessageInfo: Integer = 0) of object;
TCallbackThread = class(TThread)
private
FCallBack : TCallbackProc;
FCallbackMsg : string;
FCallbackMsgInfo: integer;
procedure SynchedCallback;
protected
procedure DoCallback(aMsg: string; aMsgInfo: integer = 0); virtual;
property Callback: TCallbackProc read FCallback;
public
constructor Create(aCallback: TCallbackProc; CreateSuspended: Boolean = False); reintroduce; virtual;
end;
TExecStoredProcThread = class(TCallbackThread)
private
fADOConnection : TADOConnection;
fADOQuery : TADOQuery;
protected
procedure Execute; override;
public
constructor Create(aCallback: TCallbackProc; Connection: TADOConnection; Query: TADOQuery); reintroduce; virtual;
destructor Destroy; override;
end;
TForm1 = class(TForm)
Panel1 : TPanel;
DBGrid1 : TDBGrid;
DBNavigator1: TDBNavigator;
DataSource1 : TDataSource;
StartQuery : TButton;
Memo1 : TMemo;
ADOQuery1: TADOQuery;
ADOConnection1: TADOConnection;
CancelQuery: TButton;
procedure StartQueryClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure CancelQueryClick(Sender: TObject);
private
{ Private declarations }
fExecStoredProcThread: TExecStoredProcThread;
procedure StoredProcCallback(aMessage: string; aMessageInfo: Integer = 0);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.StartQueryClick(Sender: TObject);
begin
if not Assigned(fExecStoredProcThread) then
begin
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Assign(Memo1.Lines);
fExecStoredProcThread := TExecStoredProcThread.Create(StoredProcCallback, ADOConnection1, ADOQuery1);
end
else Memo1.Lines.Add('!!!! A thread is still running ... cannot execute');
end;
{ TCallbackThread }
constructor TCallbackThread.Create(aCallback: TCallbackProc;
CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True;
FCallback := aCallback;
end;
procedure TCallbackThread.DoCallback(aMsg: string; aMsgInfo: integer);
begin
FCallbackMsg := aMsg;
FCallbackMsgInfo := aMsgInfo;
Synchronize(SynchedCallback);
end;
procedure TCallbackThread.SynchedCallback;
begin
if Assigned(FCallback) then
FCallBack(FCallbackMsg, FCallbackMsgInfo);
end;
{ TExecStoredProcThread }
constructor TExecStoredProcThread.Create(aCallback: TCallbackProc; Connection: TADOConnection; Query: TADOQuery);
begin
inherited Create(aCallback);
fADOQuery := Query;
fADOConnection := Connection;
end;
destructor TExecStoredProcThread.Destroy;
begin
//
inherited Destroy;
end;
procedure TExecStoredProcThread.Execute;
begin
CoInitialize(nil);
DoCallback('Starting threaded procedure');
try
fADOConnection.Connected := TRUE;
try
DoCallback('Connected threaded procedure');
try
fADOQuery.Connection := fADOConnection;
fADOQuery.CommandTimeout := 3600; // 1 hour
fADOQuery.Active := TRUE;
fADOQuery.ExecSQL;
DoCallback('Threaded procedure executed Ok, 1');
except
on E: Exception do
DoCallback('Error in running threaded procedure: '#13#10 + E.Message, 20);
end;
finally
// fADOConnection.Connected := FALSE;
end;
DoCallback('Disconnected threaded procedure');
except
on E: Exception do
DoCallback('Error in connecting threaded procedure: '#13#10 + E.Message, 10);
end;
DoCallback('Finished threaded procedure');
CoUninitialize;
end;
procedure TForm1.StoredProcCallback(aMessage: string;
aMessageInfo: Integer);
begin
Memo1.Lines.Add('>>> '+aMessage);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
DataSource1.DataSet := ADOQuery1;
DBGrid1.DataSource := DataSource1;
DBNavigator1.DataSource := DataSource1;
end;
procedure TForm1.CancelQueryClick(Sender: TObject);
begin
ADOConnection1.Connected := FALSE;
fExecStoredProcThread.Terminate;
fExecStoredProcThread := nil;
end;
the cancel button stops the thread
here is a way with a stored procedure
https://www.experts-exchange.com/questions/23759011/How-to-implement-TimOut-for-stored-procedure-execution.html