怎么将用线程查询出来的数据显示出来? ( 积分: 30 )

  • 主题发起人 主题发起人 MingWord
  • 开始时间 开始时间
M

MingWord

Unregistered / Unconfirmed
GUEST, unregistred user!
D7+ADO+SQL
我用线程进行数据库查询,但是所得的数据一闪而过,可能是线程释放了的关系,TADOConnection和TADOQuery是动态创建和连接的.查询之后将Query连上DataSource,但是ShowMessage作为停留,发现数据已经查询出来了,但是当关闭了ShowMessage,数据跟着消失.怎么解决好?
unit UThread;
interface
uses
Classes,ADODB,DB,ActiveX,Dialogs;
type
SelectData = class(TThread)
private
{ Private declarations }
Quer:TADOQuery;
Conn:TADOConnection;
Sour: TDataSource;
Conn1,Conn2:String;
SQL:String;
procedure ConnSource;
protected
procedure Execute;
override;
public
constructor Cteate(Suspendec:Boolean;NeedSQL:String;DASource:TDataSource);
destructor Destroy;override;
end;

implementation
procedure SelectData.ConnSource;
begin
Sour.DataSet:=Quer;
//ShowMessage('成功');//弹出这个窗口时,数据已经显示,但之后就消失.
end;
constructor selectdata.Cteate(Suspendec:Boolean;NeedSQL:String;DASource:TDataSource);
begin
CoInitialize(nil);
Inherited create(Suspended);
FreeOnTerminate:=True;
try
Conn:=TADOConnection.Create(nil);
// Quer:=Query;
Quer:=TADOQuery.Create(nil);
Sour:=DASource;
Quer.Connection:=Conn;
Conn1:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Wonder;Data Source=.;Use Procedure for Prepare=1;';
Conn2:='Auto Translate=True;Packet Size=4096;Workstation ID=NEWPOWER-DGI211;Use Encryption for Data=False;Tag with column collation when possible=False';
With Conndo
begin
Loginprompt:=False;
KeepConnection:=True;
ConnectionString:=Conn1+conn2;
end;
SQL:=NeedSQL;
except
ShowMessage('数据连接出错');
end;
end;

destructor SelectData.Destroy;
begin
Conn.Free;
Quer.Free;
Sour.Free;
CoUnInitialize;
inherited Destroy;
end;

procedure SelectData.Execute;
var
i:integer;
begin
try
Conn.Open;
Quer.Close;
Quer.SQL.Clear;
Quer.SQL.Text:=SQL;
Quer.Open;
Synchronize(ConnSource);
except
ShowMessage('数据库连接错误');
end;
{ Place thread code here }
end;

end.

调用.
function ShowFive(AHandle:THandle;Form:TForm;TypeID:String;OutNum:Integer):Longint;
var
SQL1:String;
begin
frmFive:=TfrmFive.Create(Form);
frmFive.FHandle:=AHandle;
NowTypeID:=TypeID;
NowOutNum:=OutNum;
result:=Longint(frmFive);
frmFive.Show;
SQL1:='Select * From vshowfivec where typeid='+NowTypeID;
SelectData.Cteate(false,SQL1,frmFive.DAShowFive);
end;
 
D7+ADO+SQL
我用线程进行数据库查询,但是所得的数据一闪而过,可能是线程释放了的关系,TADOConnection和TADOQuery是动态创建和连接的.查询之后将Query连上DataSource,但是ShowMessage作为停留,发现数据已经查询出来了,但是当关闭了ShowMessage,数据跟着消失.怎么解决好?
unit UThread;
interface
uses
Classes,ADODB,DB,ActiveX,Dialogs;
type
SelectData = class(TThread)
private
{ Private declarations }
Quer:TADOQuery;
Conn:TADOConnection;
Sour: TDataSource;
Conn1,Conn2:String;
SQL:String;
procedure ConnSource;
protected
procedure Execute;
override;
public
constructor Cteate(Suspendec:Boolean;NeedSQL:String;DASource:TDataSource);
destructor Destroy;override;
end;

implementation
procedure SelectData.ConnSource;
begin
Sour.DataSet:=Quer;
//ShowMessage('成功');//弹出这个窗口时,数据已经显示,但之后就消失.
end;
constructor selectdata.Cteate(Suspendec:Boolean;NeedSQL:String;DASource:TDataSource);
begin
CoInitialize(nil);
Inherited create(Suspended);
FreeOnTerminate:=True;
try
Conn:=TADOConnection.Create(nil);
// Quer:=Query;
Quer:=TADOQuery.Create(nil);
Sour:=DASource;
Quer.Connection:=Conn;
Conn1:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Wonder;Data Source=.;Use Procedure for Prepare=1;';
Conn2:='Auto Translate=True;Packet Size=4096;Workstation ID=NEWPOWER-DGI211;Use Encryption for Data=False;Tag with column collation when possible=False';
With Conndo
begin
Loginprompt:=False;
KeepConnection:=True;
ConnectionString:=Conn1+conn2;
end;
SQL:=NeedSQL;
except
ShowMessage('数据连接出错');
end;
end;

destructor SelectData.Destroy;
begin
Conn.Free;
Quer.Free;
Sour.Free;
CoUnInitialize;
inherited Destroy;
end;

procedure SelectData.Execute;
var
i:integer;
begin
try
Conn.Open;
Quer.Close;
Quer.SQL.Clear;
Quer.SQL.Text:=SQL;
Quer.Open;
Synchronize(ConnSource);
except
ShowMessage('数据库连接错误');
end;
{ Place thread code here }
end;

end.

调用.
function ShowFive(AHandle:THandle;Form:TForm;TypeID:String;OutNum:Integer):Longint;
var
SQL1:String;
begin
frmFive:=TfrmFive.Create(Form);
frmFive.FHandle:=AHandle;
NowTypeID:=TypeID;
NowOutNum:=OutNum;
result:=Longint(frmFive);
frmFive.Show;
SQL1:='Select * From vshowfivec where typeid='+NowTypeID;
SelectData.Cteate(false,SQL1,frmFive.DAShowFive);
end;
 
FreeOnTerminate:=True;
改成False,再手动结束,是不是可以?
 
把FreeOnTerminate:=True改成
FreeOnTerminate:=False;这样数据是可以显示,但是用AThread.Terminate 显示的数据又不能消除了。这样的话,内存有释放吗?
 
在你要显示的窗体Form1上建一个ADODataSet1,用它克隆下来线程的ADODataSet2:
Form1.ADODataSet1.Clone(ADODataSet2);
再用DBGrid显示ADODataSet1的数据即可。
 
你得sour没有create,在destroy的时候free看着很奇怪。
我觉得你不用这个东西,直接在ConnSource里调用主线程的DataSource就可以啊
然后写个OnTerimate的,再把主线程的DataSource的DataSet置成nil
CoInitialize(nil);

CoUnInitialize;
似乎也不用写吧
 
呵呵...当初教我学Delphi的那位老兄叫我不要用ADODataSet,所以我一直都是用ADOQuery,用ADOQuery代替行的吗?
我曾将ADOQuery传入构造函数内,但是也不行.
// Quer:=Query;
 
我在线程单元中加入了这样一个事件,
procedure SelectData.ConnSource2;
begin
Sour.DataSet:=nil;
end;
但是在线程内加入
constructor selectdata.Cteate(Suspendec:Boolean;NeedSQL:String;DASource:TDataSource);
begin
CoInitialize(nil);
Inherited create(Suspended);
FreeOnTerminate:=true;
OnTerminate:=ConnSource2;//加上这句,不能通过编译
怎么加上去的?
不能通过编译
 
用clone就可以了,没必要搞OnTerminate事件
constructor selectdata.Create(Suspendec:Boolean;NeedSQL:String;DASource:Tadoquery);
//创建时传入主线程的一个adoquery
procedure SelectData.ConnSource;
begin
Sour.clone(Quer);
end;
 
迷糊,可不可以详细一点:
将DASource:TDataSource改成了DASource:Tadoquery;但是Sour.clone(Quer);是啥意思来的?我的Sour定义是TDataSource呀?
 
晕,你把Sour定义成tadoquery;
constructor selectdata.Create(Suspendec:Boolean;NeedSQL:String;DASource:Tadoquery);
begin
...
sour:=DASource;
...
end;
 
谢谢迷糊兄,真的可行,但是还有一点不太明白,我想请教一下.你教的做法是不是将动态创建的ADOQuery对换成传入的ADOQuery控件?这样的话,线程是不是已经释放?传入的ADOQuery控件用的连接是他原来的连接,还是动态创建的连接?
unit UThread;
interface
uses
Classes,ADODB,DB,ActiveX,Dialogs;
type
SelectData = class(TThread)
private
{ Private declarations }
Quer:TADOQuery;
Conn:TADOConnection;
Sour:TADOQuery;
//Sour: TDataSource;
Conn1,Conn2:String;
SQL:String;
procedure ConnSource;
protected
procedure Execute;
override;
public
constructor Cteate(Suspendec:Boolean;NeedSQL:String;AQuery:TADOQuery{DASource:TDataSource});
destructor Destroy;override;
end;

implementation
procedure SelectData.ConnSource;
begin
Sour.Clone(Quer);
//Sour.DataSet:=Quer;
end;
constructor selectdata.Cteate(Suspendec:Boolean;NeedSQL:String;AQuery:TADOQuery{;DASource:TDataSource});
begin
CoInitialize(nil);
Inherited create(Suspended);
FreeOnTerminate:=true;
try
Conn:=TADOConnection.Create(nil);
Sour:=AQuery;
Quer:=TADOQuery.Create(nil);
// Sour:=DASource;
Quer.Connection:=Conn;
Conn1:='Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Wonder;Data Source=.;Use Procedure for Prepare=1;';
Conn2:='Auto Translate=True;Packet Size=4096;Workstation ID=NEWPOWER-DGI211;Use Encryption for Data=False;Tag with column collation when possible=False';
With Conndo
begin
Loginprompt:=False;
KeepConnection:=True;
ConnectionString:=Conn1+conn2;
end;
SQL:=NeedSQL;
except
ShowMessage('数据连接出错');
end;
end;

destructor SelectData.Destroy;
begin
Conn.Free;
Quer.Free;
CoUnInitialize;
inherited Destroy;
end;

procedure SelectData.Execute;
var
i:integer;
begin
try
Conn.Open;
Quer.Close;
Quer.SQL.Clear;
Quer.SQL.Text:=SQL;
Quer.Open;
Synchronize(ConnSource);
except
ShowMessage('数据库连接错误');
end;
{ Place thread code here }
end;

end.
 
用了迷糊的方法,的确可以显示数据,而且根据条件切换显示数据真的好爽[:)]
但是又出现了一个问题,那显示数据的表格就像易碎的瓷娃娃,碰不得了,一碰就跳出错误框"对象关闭时,不允许操作",这是怎么回事呀?[:(]
 
我一直这样用,没出现你说的错误啊,不过这个数据集是只读的,不能编辑。
另外,clone是将动态创建的adoquery中的数据复制到传入的adoquery中,你动态创建的那个已经释放了。
 
我需要的就是显示,不需要编辑,但是用于显示数据的cxGrid不能碰,一碰就出现错误:Project Wonder.exe raised exception class EOleException with message'对象关闭时,不允许操作.'.Process stopped.Use Step of Run to continue.
我真的找不到错误为何会出现的,"对象关闭时",是什么对象在关闭?我想应该是数据库的关系吧??????
大家帮帮我吧?我真是毫无头绪.
 
我没用过cxGrid所以不知道是不是他的原因,你先把传入的ADOQUERY设成READONLY看管不管用
 
不行呀,用我D7自带的DBGrid,设置它为READONLY属性,但是连显示还没有显示完成就出现这个错误,ADOQUERY设成READONLY的.
我想问一下迷糊,你的TADOConnection是不是也是动态创建的?会不会是TADOConnection被释放的问题?
 
是析构函数的问题,
destructor SelectData.Destroy;
begin
// Conn.Free;
Quer.Free;
CoUnInitialize;
inherited Destroy;
end;
清除Conn.Free;时,不再出现错误,但是动态创建的连接没有释放,那我不是每调用一次连接,就得创建一个连接,如果调用多了的话,那不是完蛋??
唉~~~~线程怎么那么多锁碎的问题呀.
迷糊兄,再帮帮忙,你是怎么处理你的连接的?
 
多人接受答案了。
 
后退
顶部