线程里的数据库查询问题。(50分)

  • 主题发起人 coolingxyz
  • 开始时间
C

coolingxyz

Unregistered / Unconfirmed
GUEST, unregistred user!
unit search;
interface
uses
Classes, ComCtrls, ADODB, Dialogs;
type
TSearch = class(TThread)
private
{ Private declarations }
SearchName : String;
protected
procedure Execute;
override;
Public
constructor Create(ccName : String);
Destructor Destroy;
Override;
end;
implementation
uses main;
constructor TSearch.Create(ccName : String);
begin
SearchName := ccName;
inherited Create(False);
end;
procedure TSearch.Execute;
Var
RootNode, JjNode : TTreeNode;
i : Integer;
ADOQuery1 : TADOQuery;
IpStr, Port, Jjid, ccid : String;
begin
FreeOnTerminate := True;
//线程做完后终止
ADOQuery1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+
main.MyPath +'db/fhwg.mdb;Jet OLEDB:Database Password='+''
+';Persist Security Info=False';
//编译能通过,但是运行的时候出错。错误见下面。
With ADOQuery1do
begin
sql.Clear;
sql.Add('Select * From ccName where 命名 = ' + SearchName);
try
open;
except
MessageDlg( '打开数据库出错!', mtError, [mbOK], 0 );
exit;
end;
if Not Eof and Not Bof then
begin
IpStr := Fields[1].AsString;
Port := Fields[2].AsString;
Jjid := Fields[3].AsString;
ccid := Fields[4].AsString;
end else
begin
MessageDlg( '没有这条记录!请确定你是否输入正确。', mtError, [mbOK], 0 );
exit;
end;
end;
// RootNode := Main.FrmFh.TvwFh.Items.GetFirstNode;
// For
end;
Destructor TSearch.Destroy;
begin
SearchName := '';
inherited Destroy;
end;
end.

运行时出错提示是:“Project wangguan.exe raised exception class EAccessViolation with
message 'Access violation at address 004E45DA in moudule 'wangguan.exe'.Read of address
00000038 '. Process stopped. Use Step or Run to continue.”。
我在其他窗体里这么用ADOQuery是可以用的。线程里为什么出错呀?
 
我只有这么一点分数了,大家帮我看看吧。我找不到问题了。
 
你的TADOQuery控件没有创建!!!!
试试加上下面的代码:
ADOQuery1 :=TADOQuery.Create(nil);
 
问题还是有的呀。
我在一个窗体里这么用是可以的,我没有放控件到窗体,也是这么动态创建的。
是不是在窗体上和线程里用是不同的呀?
 
问题还有?
那你再试 试这个办法,
窗体上放一个TADOQuery,你把这个TADOQuery以引用的形式传递到线程里,再在线程里用呢?
 
试试将Execute中的代码放在另一个函数中(FreeOnTerminate := True;
//线程做完后终止
以下的代码),在Execute中加入代码Synchronize(函数名),不要忘了创建ADOQuery1
 
Synchronize方法还是在主程序里执行的吧,那这样线程的作用是不是就体现不出来了?
 
我在线程里访问数据库,很多时候都是这样的,没你这样的问题:)
真不知道你的具体情况:(
 
问题解决了。csdn上问来的。

unit search;
interface
uses
Classes, ComCtrls, DB, ADODB, Dialogs, ActiveX;
type
TSearch = class(TThread)
private
{ Private declarations }
SearchName : String;
ErrorStr : String;
protected
procedure Execute;
override;
Procedure ShowError;
Public
constructor Create(ccName : String);
Destructor Destroy;
Override;
end;

implementation
uses main;
constructor TSearch.Create(ccName : String);
begin
SearchName := ccName;
inherited Create(False);
end;

procedure TSearch.Execute;
Var
RootNode, JjNode : TTreeNode;
i : Integer;
ADOQuery1 : TADOQuery;
IpStr, Port, Jjid, ccid : String;
begin
{ Place thread code here }
FreeOnTerminate := True;
//线程做完后终止
try
CoInitialize(nil);
try
ADOQuery1 := TADOQuery.Create(Nil);
ADOQuery1.ConnectionString := 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source='+
main.MyPath +'db/fhwg.mdb;Jet OLEDB:Database Password='+''
+';Persist Security Info=False';
With ADOQuery1do
begin
sql.Clear;
sql.Add('Select * From CcName where 命名=''' + SearchName +'''');
try
open;
except
ErrorStr := '打开数据库出错!';
Synchronize(ShowError);
exit;
end;

if Not Bof then
first;
if Not Eof then
begin
IpStr := Fields[1].AsString;
Port := Fields[2].AsString;
Jjid := Fields[3].AsString;
ccid := Fields[4].AsString;
end else
begin
ErrorStr := '没有这条记录!请确定您是否输入正确。';
Synchronize(ShowError);
exit;
end;

end;
finally
ADOQuery1.Free;
end;
finally
CoUninitialize;
end;
// RootNode := Main.FrmFh.TvwFh.Items.GetFirstNode;
// For
end;

Destructor TSearch.Destroy;
begin
SearchName := '';
inherited Destroy;
end;

Procedure TSearch.ShowError;
begin
MessageDlg( ErrorStr, mtError, [mbOK], 0 );
end;

end.
 
多人接受答案了。
 
顶部