Barra de progresso de instrução SQL

Delphi

10/12/2004

É possivel colocar uma barra de progresso para mostrar o tempo de processamento de uma instrução SQL. Utilizo D7/ADO/SQL Server.


Rjun

Rjun

Curtidas 0

Respostas

Bruno_fantin

Bruno_fantin

10/12/2004

Não...

Nem o banco sabe quantos porcentos já foi... Seu programa menos ainda...


GOSTEI 0
Bon Jovi

Bon Jovi

10/12/2004

O q vc pode fazer é dar um select q traga o COUNT e depois trazer aos poucos (usando midas) a grande massa de dados q está necessitando colocar na máquina cliente.

Só um problema q vejo, se na produção da empresa tiver atualizações muito intensas, o COUNT feito antes pode nao bater com a quantidade de registros que estao sendo abertos, fazendo ficar incorreto o Max da barra de progresso.

Exemplo, usando midas/ClientDataSet (+ ADO ou qualquer outro):

procedure AbreClientDataSet(AClientDataSet: TClientDataSet; APacketRecords: integer; AProgressBar: TProgressBar; ACount: integer);
var
  FormRepaint: TCustomForm;
begin
  if not Assigned(AClientDataSet) then
    Exit;

  if Assigned(AProgressBar) then
  begin
    AProgressBar.Position := 0;
    AProgressBar.Max := ACount;
  end;

  Screen.Cursor := crHourGlass;
  try
    if AClientDataSet.Active then
      AClientDataSet.Close;
    AClientDataSet.PacketRecords := APacketRecords;
    AClientDataSet.Open;
    
    while (AClientDataSet.GetNextPacket <> 0) do
    begin
      if Assigned(AProgressBar) then
      begin
        FormRepaint := Forms.GetParentForm(AProgressBar);
        AProgressBar.Position := AClientDataSet.RecordCount;
        if Assigned(FormRepaint) then
          FormRepaint.Update;
      end;      
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;


Ve aí, só compilei, to sem base aqui pra rodar.

Tem tb o evento OnFetchProgress do ADODataSet/ADOQuery, nunca usei e nem sei se ele pode te ajudar nesse caso, não sei na prática em que situação ele ocorre.


GOSTEI 0
Bon Jovi

Bon Jovi

10/12/2004

Complementando exemplo...

... SELECT COUNT(ID_PRODUTO) FROM PRODUTO
Count := ....;
//Exemplo: Count veio igual a 100000

//trará do servidor de 200 em 200....
AbreClientDataSet(ClientDataSet1, 200, ProgressBar1, Count);


GOSTEI 0
Rjun

Rjun

10/12/2004

Foi nessa solução que pensei, usando onAsyncNonBloking e OnFetchProgress e usando o Select Count para pegar o total de registros da tabela. Minha dúvida agora, seria se o select count poderia criar um gargalo na aplicação.


GOSTEI 0
Bon Jovi

Bon Jovi

10/12/2004

´Minha dúvida agora, seria se o select count poderia criar um gargalo na aplicação.´

O count é rápido. Sendo um bom servidor não há risco, o count vai ser processado lá e apenas uma linha será trafegada pela rede.

Vc sabe como fazer pra ocorrer o OnFetchProgress? Gostaria de saber. Aí nele nem precisaria ver o count, só fazer algo assim:

procedure TForm1.ADODataSet1FetchProgress(DataSet: TCustomADODataSet;
  Progress, MaxProgress: Integer; var EventStatus: TEventStatus);
begin
  ProgressBar1.Max := MaxProgress;
  ProgressBar1.Position := Progress;
  Self.Update;
end;



GOSTEI 0
Rjun

Rjun

10/12/2004

A primeira vista, pensei que poderia fazer da maneira que você está falando, Bon Jovi, mas acontece que o parâmetro MaxProgress não traz o total de registros da tabela, e sim o número de registros que ele puxa em uma operação. (Pelo menos foi o que eu pude enteder). Acho que o OnFetchProgress ocorre a cada leitura desse bloco.


GOSTEI 0
POSTAR