M
mystarter
Unregistered / Unconfirmed
GUEST, unregistred user!
我是想先构建TExecSQLThread和TOpenSQLThread类。
在这两个基类中,进行线程执行SQL和打开查询。在创建类时,输入参数ADO的连接字符串与SQL字符串,互斥句柄。(ADOThread.pas)
然后,再建类继承自这基类,实现功能。与主线程同步。
(OutPortUnit.pas,这个单元中实现将数据库数据内容通过TStringList输出到文本中。)
但在procedure TOutPortThread.Execute;中
inherited; //这里好象并没有对FADOQuery进行处理
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。
源程序如下:
/////////// 基类 ADOThread.pas
unit ADOThread;
interface
uses
Classes, DB, ADODB, forms,SysUtils,ComCtrls, Windows;
type
TExecSQLThread = class(TThread)
private
FMutex:THandle;
FExecTime:Integer;
FADOConnection: TADOConnection;
FADOQuery: TAdoQuery;
procedure ADOTimeOut;
procedure ADOExecSQL;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; ConnString,StrSQL:string;hMutex:THandle); overload;
destructor Destroy; override;
end;
type
TOpenSQLThread = class(TThread)
private
FMutex:THandle;
FExecTime:Integer;
FADOConnection: TADOConnection;
FADOQuery: TAdoQuery;
procedure ADOTimeOut;
procedure ADOOpenSQL;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; ConnString,StrSQL:string;hMutex:THandle); overload;
destructor Destroy; override;
end;
implementation
constructor TExecSQLThread.Create(CreateSuspended: Boolean; ConnString,
StrSQL:string;hMutex:THandle);
begin
inherited Create(CreateSuspended);
FADOConnection:= TAdoConnection.Create(Application);
FADOConnection.ConnectionString:=ConnString;
FADOConnection.LoginPrompt:=false;
FADOQuery := TAdoQuery.Create(Application);
FADOQuery.SQL.Add(StrSQL);
FExecTime:=0;
FMutex:=hMutex;
self.FreeOnTerminate:=true; //必须加上,否则不能释放内存
end;
destructor TExecSQLThread.Destroy;
begin
FADOQuery.Close;
FADOQuery.Free;
FADOConnection.Close;
FADOConnection.free;
inherited;
end;
procedure TExecSQLThread.Execute;
begin
if WaitForSingleObject(FMutex, INFINITE) = WAIT_OBJECT_0 then
begin
FADOConnection.Open;
ADOExecSQL;
end;
ReleaseMutex(FMutex);
{ Place thread code here }
end;
procedure TExecSQLThread.ADOExecSQL;
begin
try
FExecTime:=FExecTime+1;
if FExecTime<=3 then FADOQuery.ExecSQL
else Synchronize(ADOTimeOut);
except
ADOExecSQL;
end;
end;
procedure TExecSQLThread.ADOTimeOut;
begin
end;
constructor TOpenSQLThread.Create(CreateSuspended: Boolean; ConnString,
StrSQL:string;hMutex:THandle);
begin
inherited Create(CreateSuspended);
FADOConnection:= TAdoConnection.Create(Application);
FADOConnection.ConnectionString:=ConnString;
FADOConnection.LoginPrompt:=false;
FADOQuery := TAdoQuery.Create(Application);
FADOQuery.Connection:=FADOConnection;
FADOQuery.SQL.Add(StrSQL);
FExecTime:=0;
FMutex:=hMutex;
self.FreeOnTerminate:=true; //必须加上,否则不能释放内存
end;
destructor TOpenSQLThread.Destroy;
begin
FADOQuery.Close;
FADOQuery.Free;
FADOConnection.Close;
FADOConnection.free;
inherited;
end;
procedure TOpenSQLThread.ADOOpenSQL;
begin
try
FExecTime:=FExecTime+1;
if FExecTime<=3 then FADOQuery.Open
else Synchronize(ADOTimeOut);
except
ADOOpenSQL;
end;
end;
procedure TOpenSQLThread.ADOTimeOut;
begin
end;
procedure TOpenSQLThread.Execute;
var
filePath,stemp,lines,tmpstr:string;
j:integer;
begin
if WaitForSingleObject(FMutex, INFINITE) = WAIT_OBJECT_0 then
begin
FADOConnection.Open;
ADOOpenSQL;
end;
ReleaseMutex(FMutex);
{ Place thread code here }
end;
end.
下面构建继承类:TOutPortThread
///////////////// InheritUnit.pas
unit InheritUnit;
interface
uses
Classes, DB, ADODB, forms,SysUtils,ComCtrls, Windows, ADOThread;
type
TOutPortThread = class(TOpenSQLThread)
private
FADOQuery:TAdoQuery;
FileName, FStrSQL: string;
list: TStrings;
procedure UpdateProcess;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; aFileName,{文件名} ConnString,StrSQL:{表名} string;hMutex:THandle);
destructor Destroy; override;
end;
Const
ZChar=' ';
implementation
uses
DataImportUnit;
constructor TOutPortThread.Create(CreateSuspended: Boolean; aFileName,
ConnString,StrSQL: string; hMutex:THandle);
begin
inherited Create(CreateSuspended,ConnString,StrSQL,hMutex);
list := TStringList.Create;
FileName:=aFileName;
end;
procedure TOutPortThread.Execute;
var
filePath,stemp,lines,tmpstr:string;
j:integer;
begin
inherited; //这里好象并没有对FADOQuery进行处理
filePath:=ExtractFilePath(Application.ExeName) + FileName;
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。
list.Add('***文件类型:' + FileName + '***');
stemp := '';
for j := 0 to FADOQuery.fields.count - 1 do
begin
if Uppercase(FADOQuery.Fields[j].FullName) <> 'ID' then
if (FADOQuery.Fields[j].DataType <> ftGraphic)
and (FADOQuery.Fields[j].DataType <> ftBlob) then ////跳过Image型
stemp := stemp + FADOQuery.fields[j].FullName + ZChar;
end;
stemp := copy(stemp, 1, length(stemp) - 1);
list.Add(stemp);
FADOQuery.First;
while not eof do
begin
Synchronize(UpdateProcess);
sleep(100);
Lines := '';
for j := 0 to FADOQuery.fields.count - 1 do
begin
if Uppercase(FADOQuery.Fields[j].FullName) <> 'ID' then
if (FADOQuery.Fields[j].DataType <> ftGraphic) and (FADOQuery.Fields[j].DataType <>
ftBlob) then ////跳过Image型
begin
tmpStr := trim(FADOQuery.Fields[j].AsString);
tmpStr := StringReplace(tmpStr, #13 + #10, ' ', [rfReplaceAll]);
Lines := Lines + #39 + tmpStr + #39 + ZChar;
end;
end;
Lines := copy(Lines, 1, length(Lines) - 1);
list.Add(Lines);
FADOQuery.Next;
end;
list.SaveToFile(filePath);
end;
procedure TOutPortThread.UpdateProcess;
var
ProgressBar:TProgressBar;
begin
if FileName='outputfile.txt' then ProgressBar:= FormDataImport.ProgressBarOut
else if FileName='outputfile1.txt' then ProgressBar:= FormDataImport.ProgressBar1
else if FileName='outputfile2.txt' then ProgressBar:= FormDataImport.ProgressBar2
else if FileName='outputfile3.txt' then ProgressBar:= FormDataImport.ProgressBar3;
if ProgressBar.Position >= 100 then
ProgressBar.Position := 0
else
ProgressBar.Position :=
ProgressBar.Position
+ ProgressBar.Step;
application.ProcessMessages; //切换,给其他线程运行时间
end;
destructor TOutPortThread.Destroy;
begin
list.Free;
inherited;
end;
end.
////////////// 调用DataImportUnit.pas
unit DataImportUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, DB, ADODB,Activex;
type
TFormDataImport = class(TForm)
ProgressBarOut: TProgressBar;
Button1: TButton;
ADOConnection1: TADOConnection;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
ProgressBar3: TProgressBar;
ADOConnection2: TADOConnection;
ADOQuery1: TADOQuery;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormDataImport: TFormDataImport;
hMutex: THandle = 0;
implementation
uses
UnitConst,InheritUnit;
{$R *.dfm}
procedure TFormDataImport.Button1Click(Sender: TObject);
begin
hMutex := CreateMutex(nil, False, nil);
TOutPortThread.Create(false,'outputfile.txt',StrConn,'select * from employee',hMutex);
TOutPortThread.Create(false,'outputfile1.txt',StrConn,'select * from authors',hMutex);
TOutPortThread.Create(false,'outputfile2.txt',StrConn,'select * from jobs',hMutex);
TOutPortThread.Create(false,'outputfile3.txt',StrConn,'select * from sales',hMutex);
end;
initialization
CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
CoUninitialize;
end.
而在procedure TOutPortThread.Execute;中
inherited; //这里好象并没有对FADOQuery进行处理
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。
在这两个基类中,进行线程执行SQL和打开查询。在创建类时,输入参数ADO的连接字符串与SQL字符串,互斥句柄。(ADOThread.pas)
然后,再建类继承自这基类,实现功能。与主线程同步。
(OutPortUnit.pas,这个单元中实现将数据库数据内容通过TStringList输出到文本中。)
但在procedure TOutPortThread.Execute;中
inherited; //这里好象并没有对FADOQuery进行处理
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。
源程序如下:
/////////// 基类 ADOThread.pas
unit ADOThread;
interface
uses
Classes, DB, ADODB, forms,SysUtils,ComCtrls, Windows;
type
TExecSQLThread = class(TThread)
private
FMutex:THandle;
FExecTime:Integer;
FADOConnection: TADOConnection;
FADOQuery: TAdoQuery;
procedure ADOTimeOut;
procedure ADOExecSQL;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; ConnString,StrSQL:string;hMutex:THandle); overload;
destructor Destroy; override;
end;
type
TOpenSQLThread = class(TThread)
private
FMutex:THandle;
FExecTime:Integer;
FADOConnection: TADOConnection;
FADOQuery: TAdoQuery;
procedure ADOTimeOut;
procedure ADOOpenSQL;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; ConnString,StrSQL:string;hMutex:THandle); overload;
destructor Destroy; override;
end;
implementation
constructor TExecSQLThread.Create(CreateSuspended: Boolean; ConnString,
StrSQL:string;hMutex:THandle);
begin
inherited Create(CreateSuspended);
FADOConnection:= TAdoConnection.Create(Application);
FADOConnection.ConnectionString:=ConnString;
FADOConnection.LoginPrompt:=false;
FADOQuery := TAdoQuery.Create(Application);
FADOQuery.SQL.Add(StrSQL);
FExecTime:=0;
FMutex:=hMutex;
self.FreeOnTerminate:=true; //必须加上,否则不能释放内存
end;
destructor TExecSQLThread.Destroy;
begin
FADOQuery.Close;
FADOQuery.Free;
FADOConnection.Close;
FADOConnection.free;
inherited;
end;
procedure TExecSQLThread.Execute;
begin
if WaitForSingleObject(FMutex, INFINITE) = WAIT_OBJECT_0 then
begin
FADOConnection.Open;
ADOExecSQL;
end;
ReleaseMutex(FMutex);
{ Place thread code here }
end;
procedure TExecSQLThread.ADOExecSQL;
begin
try
FExecTime:=FExecTime+1;
if FExecTime<=3 then FADOQuery.ExecSQL
else Synchronize(ADOTimeOut);
except
ADOExecSQL;
end;
end;
procedure TExecSQLThread.ADOTimeOut;
begin
end;
constructor TOpenSQLThread.Create(CreateSuspended: Boolean; ConnString,
StrSQL:string;hMutex:THandle);
begin
inherited Create(CreateSuspended);
FADOConnection:= TAdoConnection.Create(Application);
FADOConnection.ConnectionString:=ConnString;
FADOConnection.LoginPrompt:=false;
FADOQuery := TAdoQuery.Create(Application);
FADOQuery.Connection:=FADOConnection;
FADOQuery.SQL.Add(StrSQL);
FExecTime:=0;
FMutex:=hMutex;
self.FreeOnTerminate:=true; //必须加上,否则不能释放内存
end;
destructor TOpenSQLThread.Destroy;
begin
FADOQuery.Close;
FADOQuery.Free;
FADOConnection.Close;
FADOConnection.free;
inherited;
end;
procedure TOpenSQLThread.ADOOpenSQL;
begin
try
FExecTime:=FExecTime+1;
if FExecTime<=3 then FADOQuery.Open
else Synchronize(ADOTimeOut);
except
ADOOpenSQL;
end;
end;
procedure TOpenSQLThread.ADOTimeOut;
begin
end;
procedure TOpenSQLThread.Execute;
var
filePath,stemp,lines,tmpstr:string;
j:integer;
begin
if WaitForSingleObject(FMutex, INFINITE) = WAIT_OBJECT_0 then
begin
FADOConnection.Open;
ADOOpenSQL;
end;
ReleaseMutex(FMutex);
{ Place thread code here }
end;
end.
下面构建继承类:TOutPortThread
///////////////// InheritUnit.pas
unit InheritUnit;
interface
uses
Classes, DB, ADODB, forms,SysUtils,ComCtrls, Windows, ADOThread;
type
TOutPortThread = class(TOpenSQLThread)
private
FADOQuery:TAdoQuery;
FileName, FStrSQL: string;
list: TStrings;
procedure UpdateProcess;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean; aFileName,{文件名} ConnString,StrSQL:{表名} string;hMutex:THandle);
destructor Destroy; override;
end;
Const
ZChar=' ';
implementation
uses
DataImportUnit;
constructor TOutPortThread.Create(CreateSuspended: Boolean; aFileName,
ConnString,StrSQL: string; hMutex:THandle);
begin
inherited Create(CreateSuspended,ConnString,StrSQL,hMutex);
list := TStringList.Create;
FileName:=aFileName;
end;
procedure TOutPortThread.Execute;
var
filePath,stemp,lines,tmpstr:string;
j:integer;
begin
inherited; //这里好象并没有对FADOQuery进行处理
filePath:=ExtractFilePath(Application.ExeName) + FileName;
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。
list.Add('***文件类型:' + FileName + '***');
stemp := '';
for j := 0 to FADOQuery.fields.count - 1 do
begin
if Uppercase(FADOQuery.Fields[j].FullName) <> 'ID' then
if (FADOQuery.Fields[j].DataType <> ftGraphic)
and (FADOQuery.Fields[j].DataType <> ftBlob) then ////跳过Image型
stemp := stemp + FADOQuery.fields[j].FullName + ZChar;
end;
stemp := copy(stemp, 1, length(stemp) - 1);
list.Add(stemp);
FADOQuery.First;
while not eof do
begin
Synchronize(UpdateProcess);
sleep(100);
Lines := '';
for j := 0 to FADOQuery.fields.count - 1 do
begin
if Uppercase(FADOQuery.Fields[j].FullName) <> 'ID' then
if (FADOQuery.Fields[j].DataType <> ftGraphic) and (FADOQuery.Fields[j].DataType <>
ftBlob) then ////跳过Image型
begin
tmpStr := trim(FADOQuery.Fields[j].AsString);
tmpStr := StringReplace(tmpStr, #13 + #10, ' ', [rfReplaceAll]);
Lines := Lines + #39 + tmpStr + #39 + ZChar;
end;
end;
Lines := copy(Lines, 1, length(Lines) - 1);
list.Add(Lines);
FADOQuery.Next;
end;
list.SaveToFile(filePath);
end;
procedure TOutPortThread.UpdateProcess;
var
ProgressBar:TProgressBar;
begin
if FileName='outputfile.txt' then ProgressBar:= FormDataImport.ProgressBarOut
else if FileName='outputfile1.txt' then ProgressBar:= FormDataImport.ProgressBar1
else if FileName='outputfile2.txt' then ProgressBar:= FormDataImport.ProgressBar2
else if FileName='outputfile3.txt' then ProgressBar:= FormDataImport.ProgressBar3;
if ProgressBar.Position >= 100 then
ProgressBar.Position := 0
else
ProgressBar.Position :=
ProgressBar.Position
+ ProgressBar.Step;
application.ProcessMessages; //切换,给其他线程运行时间
end;
destructor TOutPortThread.Destroy;
begin
list.Free;
inherited;
end;
end.
////////////// 调用DataImportUnit.pas
unit DataImportUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, DB, ADODB,Activex;
type
TFormDataImport = class(TForm)
ProgressBarOut: TProgressBar;
Button1: TButton;
ADOConnection1: TADOConnection;
ProgressBar1: TProgressBar;
ProgressBar2: TProgressBar;
ProgressBar3: TProgressBar;
ADOConnection2: TADOConnection;
ADOQuery1: TADOQuery;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
FormDataImport: TFormDataImport;
hMutex: THandle = 0;
implementation
uses
UnitConst,InheritUnit;
{$R *.dfm}
procedure TFormDataImport.Button1Click(Sender: TObject);
begin
hMutex := CreateMutex(nil, False, nil);
TOutPortThread.Create(false,'outputfile.txt',StrConn,'select * from employee',hMutex);
TOutPortThread.Create(false,'outputfile1.txt',StrConn,'select * from authors',hMutex);
TOutPortThread.Create(false,'outputfile2.txt',StrConn,'select * from jobs',hMutex);
TOutPortThread.Create(false,'outputfile3.txt',StrConn,'select * from sales',hMutex);
end;
initialization
CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
CoUninitialize;
end.
而在procedure TOutPortThread.Execute;中
inherited; //这里好象并没有对FADOQuery进行处理
list.Add(FADOQuery.SQL.Text); //这个地方出现错误,FADOQuery好象并没有创建。