unit Unit1; 
  
  interface 
  
  uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, 
    Dialogs, DBTables, Db; 
  
  const 
    WM_OPENDATASET = WM_USER + 1; 
    WM_EXECUTESQL  = WM_USER + 2; 
  
  type 
    TThreadDataSet = class(TThread) 
    private 
      procedure WMOpenDataSet(Msg: TMsg); 
      procedure WMExecSQL(Msg: TMsg); 
    protected 
      procedure Execute; override; 
    public 
      procedure Open(DataSet: TDataSet); 
      procedure ExecSQL(DataSet: TDataSet); 
    end; 
  
    TForm1 = class(TForm) 
      procedure FormCreate(Sender: TObject); 
      procedure FormDestroy(Sender: TObject); 
    private 
      { Private declarations } 
  FThread : TThreadDataSet; 
    public 
      { Public declarations } 
    end; 
  
  var 
    Form1: TForm1; 
  
  implementation 
  
  {$R *.DFM} 
  
  procedure TThreadDataSet.ExecSQL(DataSet: TDataSet); 
  begin 
    PostThreadMessage(ThreadID, WM_EXECUTESQL, Integer(DataSet), 0); 
  end; 
  
  procedure TThreadDataSet.Execute; 
  var 
    Msg : TMsg; 
  
  begin 
    FreeOnTerminate := True; 
    PeekMessage(Msg, 0, WM_USER, WM_USER, PM_NOREMOVE); 
  
    while not Terminated do begin 
      if GetMessage(Msg, 0, 0, 0) then 
         case Msg.Message of 
           WM_OPENDATASET: WMOpenDataSet(Msg); 
           WM_EXECUTESQL:  WMExecSQL(Msg); 
         end; 
    end; 
  end; 
  
  procedure TThreadDataSet.Open(DataSet: TDataSet); 
  begin 
    PostThreadMessage(ThreadID, WM_OPENDATASET, Integer(DataSet), 0); 
  end; 
  
  procedure TThreadDataSet.WMExecSQL(Msg: TMsg); 
  var 
    Qry : TQuery; 
  
  begin 
    try 
      Qry := TQuery(Msg.wParam); 
      try 
        Qry.Open; 
      except 
        Qry.ExecSQL; 
      end; 
    except 
      On E: Exception do 
         ShowMessage(E.Message); 
    end; 
  end; 
  
  procedure TThreadDataSet.WMOpenDataSet(Msg: TMsg); 
  var 
    Ds : TDataSet; 
  
  begin 
    try 
      Ds := TDataSet(Msg.wParam); 
      Ds.Open; 
    except 
      On E: Exception do 
         ShowMessage(E.Message); 
    end; 
  end; 
  
  // --------------------------------------- // 
  
  procedure TForm1.FormCreate(Sender: TObject); 
  begin 
    FThread  := TThreadDataSet.Create(False); 
    FThread.Open(Table1);   // Opening a dataset (table or query) 
    FThread.ExecSQL(Query1);  // Executing a SQL 
  end; 
  
  procedure TForm1.FormDestroy(Sender: TObject); 
  begin 
    FThread.Terminate; 
  end; 
  
  end.