Cancelar execução de uma stored procedure?

Firebird

04/07/2011

Pessoal estou chamando uma SP atavez do comando EXECUTE de um Query, porém as vezes ela demora muito para ser executado e gostaria de saber se tem como eu criar um botão no delphi para cancelar esta sp?


Adriano Dolce

Adriano Dolce

Curtidas 0

Respostas

Adriano Dolce

Adriano Dolce

04/07/2011

Estou tentando usar uma threads mais não conheço muito bem como posso executar a thread

Fiz assim
unit U_ThreadExecute;

interface

uses
  Classes, Windows, SysUtils, DB, Forms, Messages, Dialogs,
  Controls, IBDatabase, IBCustomDataSet, IBQuery, U_DataModule, ActiveX;

type
  ThreadExecute = class(TThread)
  private
    { Private declarations }
  protected
    procedure Execute; override;
  public
    constructor ExecutarProcedure(Query: TIBQuery);
  end;

implementation

{ Important: Methods and properties of objects in VCL can only be used in a
  method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure ThreadExecute.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; }

{ ThreadExecute_Estrela }

constructor ThreadExecute_Estrela.ExecutarProcedure(Query: TIBQuery);
begin
  inherited Create(True);
  FreeOnTerminate := True;
  Resume;
end;

procedure ThreadExecute_Estrela.Execute;
var
  Query : TIBQuery;
begin
  CoInitialize(nil);
  try
    Query := TIBQuery.Create(nil);
    Query.Database := Interbase.IBDatabase;
    Query.Transaction := Interbase.IBTr_Application;
    try
      with Query do
      begin
        Close;
        if not Interbase.IBTr_Application.InTransaction then
          Interbase.IBTr_Application.StartTransaction;

        Close;
        Sql.Text := 'Execute Procedure SP_ATUALIZA_DADOS';
        ExecSQL;
        Interbase.IBTr_Application.Commit;
        raise Exception.Create('Processo concluído');
      end;
    except
      on e:Exception do
      begin
        Interbase.IBTr_Application.Rollback;
        raise Exception.Create('Erro! Falha ao executar. Processo encerrado.'+e.Message);
      end;
    end;
  finally
    CoUninitialize;
  end;
  { Place thread code here }
end;

end.


e chamo assim
ThreadExecute.ExecutarProcedure(IBQuery);


Mais coloquei uma mensagem para quando terminasse
raise Exception.Create('Processo concluído');

Só q não esta aparecendo, para nesla linha
ExecSQL;

E fica por aqui mesmo.



GOSTEI 0
Adriano Dolce

Adriano Dolce

04/07/2011

mudei aqui esta thread, mais ela trava no [b]ExecSQL[/b] da procedure EXECUTE da Thread.

unit U_Thread_Execute;

interface

uses
  Classes, Windows, SysUtils, DB, Forms, Messages, Dialogs,
  Controls, IBDatabase, IBCustomDataSet, IBQuery, ActiveX,
  SyncObjs;

type
  Thread_Execute = class(TThread)
  private
    FBanco, FSQL, FSenha: String;
    SessaoCritica: TCriticalSection;
    FConn: TIBDatabase;
    FTrans: TIBTransaction;
    FQuery: TIBQuery;
    { Private declarations }
  protected
    procedure Execute; override;
  public
    constructor Create(Banco, SQL, Senha: String);
    destructor Destroy; override;
  end;

implementation


{ Thread_Execute }
constructor Thread_Execute.Create(Banco, SQL, Senha: String);
begin
  inherited Create(True);
  FBanco := Banco;
  FSQL := SQL;
  FreeOnTerminate := True;

  FConn:= TIBDatabase.Create(Application);
  FTrans:= TIBTransaction.Create(FConn);
  FQuery:= TIBQuery.Create(FConn);
  if Trim(FSenha) = EmptyStr then
    FSenha := 'masterkey';
  FConn.Params.Values['password']:= FSenha;
  FConn.Params.Values['user_name']:= 'SYSDBA';
  FConn.LoginPrompt := False;
  FConn.SQLDialect := 3;

  FTrans.DefaultDatabase := FConn;
  FConn.DefaultTransaction := FTrans;
  FTrans.Params.Add('read_committed');
  FTrans.Params.Add('rec_version');
  FTrans.Params.Add('nowait');
  FTrans.DefaultDatabase := FConn;
  FTrans.DefaultAction := TARollback;

  FQuery.Database := FConn;
  FQuery.Transaction := FTrans;

end;

destructor Thread_Execute.Destroy;
begin
  FConn.Free;
  inherited;
end;

procedure Thread_Execute.Execute;
begin
  CoInitialize(nil);
  try
    try
      FConn.DatabaseName := FBanco;

      SessaoCritica:= TCriticalSection.Create;
      SessaoCritica.Enter;
      try
        FConn.Connected := True;
      finally
        SessaoCritica.Leave;
      end;
      with FQuery do
      begin
        if not FTrans.InTransaction then
          FTrans.StartTransaction;

        Close;
        SQL.Clear;
        SQL.Text := FSQL;
        SessaoCritica.Enter;
        try
          ExecSQL;
        finally
          SessaoCritica.Leave;
        end;
        FTrans.Commit;
        ShowMessage('Processo concluído');
      end;
    except
      on e:Exception do
      begin
        FTrans.Rollback;
        raise Exception.Create('Erro! Falha ao executar. Processo encerrado.'+e.Message);
      end;
    end;
    FConn.Close;
  finally
    CoUninitialize;
  end;
  { Place thread code here }
end;

end.


E chamando assim
Thrd := Thread_Execute.Create(CaminhoBanco, sSQLSProcedure, Senha);
Thrd.Resume;


Mais este desgranhento não quer funcionar.

As variaveis caminho do banco sSQLSProcedure e Senha estão corretos.
GOSTEI 0
Adriano Dolce

Adriano Dolce

04/07/2011

Pessoal, será que tem como ao menos eu colocar uma mensagem de calculo de percentual do processo sendo executado na SP dentro do aplicativo?

Igual fazemos com um loop, usando gauge, progressbar... estas coisas ai.

Sem usar o Thred, dentro do aplicativo mesmo, pois ja que demora mesmo para executar a SP, que ao menos o usuario fique vendo o percentual ja processado, para não achar que travou a maquina.

Obrigado pessoal.
GOSTEI 0
POSTAR