我这个例子没有进度条,因为没办法分析SQL语句,然后知道要返回多少个结果。如果想加进度条,可以在DataSource的onDataChange里加,也可以在Thread的Execute里加,看你的情况而定。线程结束的方法是这样的,这样才能在查询正在执行的时候中断。
QueryThread.Suspend;
QueryThread.Free;线程的代码:unit TQueryThread_Unit;interfaceuses
  Classes,dbtables,db,Dialogs,Sysutils,DBGrids;type
  TSQLModelType = (stSelect,stExecute,stProcSelect);  TQueryThread = class(TThread)
  private
    { Private declarations }
    FQuery : TQuery;
    FSession : TSession;
    FDataBase : TDataBase;
    FDataSource : TDataSource;
    WarningMessage :String;
    procedure SetDBGrid;
    procedure ShowWarning;
  protected
    procedure Execute; override;
  public
    SQLText : String;
    SQLModel : TSQLModelType ;
    DBGrid : TDBGrid;
    constructor Create(AOwner:TComponent);
    destructor Destroy;override;
  end;implementationconstructor TQueryThread.Create(AOwner:TComponent);
begin
{一个Database只能让一个线程执行查询,所以要自己Create一个Session,
一个DataBase,一个Query,和一个DataSource,DataSource也是须的,
要不然在DBGrid指针的移动时候会等待直到SQL查询完毕。
如果有DataSource就不用等。线程会慢慢把数据放入DataSource,
然后在DBGrid上显示出来。}
    FSession := TSession.Create(AOwner) ;
    FSession.AutoSessionName := true ;
    FSession.KeepConnections := true ;
    FSession.Open;    FDataBase := TDatabase.Create(AOwner) ;
    FDataBase.SessionName := FSession.SessionName ;
    FDataBase.DatabaseName := 'DB_'+FSession.SessionName ;
    FDataBase.DriverName := 'MSSQL' ; {使用MS SQL Server作为后台数据库}
    FDataBase.LoginPrompt := False ;
    FDataBase.Params.Add('DATABASE NAME=test') ;{使用 SQL Server上的Test库}
    FDataBase.Params.Add('USER NAME=sa') ;
    FDataBase.Params.Add('PASSWORD=') ;
    FDataBase.Params.Add('SERVER NAME=dep') ;{这里请改为自己的服务器名字}    FQuery := TQuery.Create(AOwner) ;
    FQuery.SessionName := FSession.SessionName ;
    FQuery.DatabaseName := FDataBase.DatabaseName ;    FDataSource := TDataSource.Create( AOwner );
    FDataSource.DataSet := FQuery ;    FreeOnTerminate := False ;
    WarningMessage := '' ;
    SQLModel := stSelect ;
    inherited Create( True );
end;destructor TQueryThread.Destroy;
begin
    FSession.Close;
    //一定要先CloseFSession,然后才Free,要不然会等待直到SQL查询完毕。
    FSession.Free;
    FQuery.Free;
    FDataBase.Free;
    FDataSource.Free;
end;procedure TQueryThread.SetDBGrid;
Begin
    DBGrid.DataSource := FDataSource ;
end;procedure TQueryThread.ShowWarning;
Begin
    MessageDlg(  WarningMessage , mtWarning , [mbOK] ,0 );
end;procedure TQueryThread.Execute;
Var
    i : integer;
begin
try
    if SQLText = ''  then
    begin
        WarningMessage := '没有指定SQL查询语句.';
        Synchronize( ShowWarning );
    end
    else if (DBGrid = nil) then
    begin
        WarningMessage := '没有指定DBGrid.';
        Synchronize( ShowWarning );
    end
    else
    begin
        FQuery.Close;
        FQuery.SQL.Text := SQLText ;
        case SQLModel of
          stSelect ,stProcSelect:
                     Begin
                        FQuery.Open;
                        Synchronize( SetDBGrid );
                     End;
          stExecute: Begin
                        FQuery.ExecSQL;
                     End;
        end;
    end;
except
    on E:EDBEngineError do
    Begin
        WarningMessage := '数据库运行出错。' + #13 + '错误代码:' ;
        for  i:= 0 to E.ErrorCount -1 do
            WarningMessage := WarningMessage + #13+ IntToStr( E.Errors[i].ErrorCode ) +': ' + E.Errors[i].Message;
        Synchronize( ShowWarning );
    End
    else
        raise;
end;
end;end.