김영대님의 자료실에서 'Thread를 사용한 Query 동시에 날리기'를 찾아서 test를 하는중
'Name not unique in this context'라는 에러가 자꾸만 납니다.
Query안에 사용안 SQL문장도 에러가 없는것이고 DB연결도 잘했습니다.
어떻게 된건지 모르겠습니다. 꼭 좀 알려주세요!!!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
DBTables, Db, StdCtrls, Grids, DBGrids, ComCtrls, ADODB;
type
TForm1 = class(TForm)
Database1: TDatabase;
Query2: TQuery;
Query3: TQuery;
DataSource1: TDataSource;
DataSource2: TDataSource;
DataSource3: TDataSource;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
DBGrid3: TDBGrid;
Button1: TButton;
ProgressBar1: TProgressBar;
Session1: TSession;
Query1: TQuery;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TQueryThread = class(TThread)
private
FDatabase: TDataBase;
FQuery: TQuery;
FDatasource: TDatasource;
FQueryException: Exception;
procedure ConnectDataSource;
procedure ShowQryError;
protected
procedure Execute; override;
public
constructor Create(Session: TSession; DataBase:
TDatabase; Query: TQuery; DataSource: TDataSource); virtual;
end;
var
Form1: TForm1;
implementation
constructor TQueryThread.Create(Session: TSession; DataBase:
TDatabase; Query: TQuery; Datasource: TDataSource);
begin
// thread object의 instance를 생성한다
// Create의 파라미터가 False이면 thread를 생성한후 즉시 Execute를 호출하여 실행한다
// " True이면 Resume을 호출하기 전까지 실행하지 않는다
inherited Create(True);
FDatabase := DataBase;
FQuery := Query;
FDataSource := Datasource;
// thread의 실행이 종료하면 자동으로 free되게 설정
FreeOnTerminate := True;
// 실행이 일시 중지된(suspended) thread를 실행한다
Resume;
end;
procedure TQueryThread.Execute;
begin
try
// Query를 open하고 DataSource를 연결한다
FQuery.Open;
// thread간의 충돌을 피하여 ConnectDataSource 를 호촐한다
Synchronize(ConnectDataSource);
except
// Handle the exception
FQueryException := ExceptObject as Exception;
// thread간의 충돌을 피하여 ShowQryError 를 호촐한다
Synchronize(ShowQryError);
// Do not use the properties and methods of other objects directly in the Execute method of a thread.
// Instead, separate the use of other objects into a separate procedure call, and call that procedure
// by passing it as a parameter to the Synchronize method.
end;
end;
// TQuery object를 접근하므로 Synchronize 로 호출해야함
procedure TQueryThread.ConnectDataSource;
begin
// DataSource를 연결한다
// TQuery를 접근하므로 Synchronize 로 호출했음
FDataSource.DataSet := FQuery;
end;
// Application object를 접근하므로 Synchronize 로 호출해야함
procedure TQueryThread.ShowQryError;
begin
// Handle the exception
Application.ShowException(FQueryException);
end;
procedure RunBackgroundQuery(Session: TSession; DataBase: TDataBase;
Query: TQuery; DataSource: TDataSource);
begin
{thread instance 생성}
TQueryThread.Create(Session, Database, Query, DataSource);
end;
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
{병렬처리: 3개의 Query를 thread를 사용하여 open한다}
RunBackgroundQuery(Session1, DataBase1, Query1, Datasource1);
RunBackgroundQuery(Session1, DataBase1, Query2, Datasource2);
RunBackgroundQuery(Session1, DataBase1, Query3, Datasource3);
(* 순차처리: 일반적인 Query Open
Query1.Open;
Query2.Open;
Query3.Open;
*)
for i := 1 to 100 do
ProgressBar1.Position := i;
end;
end.