ADO多线程数据库查询通常会出现以下问题:

1、CoInitialize 没有调用(CoInitialize was not called);所以,在使用任何dbGo对象前,必须手 调用CoInitialize和CoUninitialize。调用CoInitialize失败会产生"CoInitialize was not called"例外。

2、画布不允许绘画(Canvas does not allow drawing);所以,必须通过Synchronize过程来通知主线程访问主窗体上的任何控件。

3、不能使用主ADO连接(Main TADoConnection cannot be used!);所以,线程中不能使用主线程中TADOConnection对象,每个线程必须创建自己的数据库连接。

Delphi2007安装后在X:\Program Files\Common Files\CodeGear Shared\Data目录下有一个dbdemos.mdb文件,用来作为测试的例子。dbdemos.mdb中的customer表保存了客户信息,orders表中保存了订单信息。

测试程序流程大致是这样的:在主窗体上放TADOConnection和TQuery控件,启动时这个TQuery从Customer表中查出客户编码CustNo和公司名称Company,放到三个Combox框中,分别在三个列表框中选定客户公司名称,按照公司名称所对应的客户代码建立三个线程同时在orders表中查询销售日期SaleDate分别填入ListBox中。

4、COM接口调用时必须有线程自己的接口。

如:在A线程建的COM接口,B线程调用时就提示“应用程序调用一个已为另一线程整理的接口”。这时只要在B线程建立自己独有的COM接口使用就可以了。

 {主窗体代码}
unit Main;
interface
uses Windows, Messages, SysUtils, Variants,
Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB, StdCtrls;
type
TForm2 = class(TForm)
ComboBox1: TComboBox;
ComboBox2: TComboBox;
ComboBox3: TComboBox;
ListBox1: TListBox;
ListBox2: TListBox;
ListBox3: TListBox;
Button1: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private { Private declarations }
public { Public declarations }
end;
var Form2: TForm2;
implementation
uses
ADOThread;
{$R *.dfm} procedure TForm2.Button1Click(Sender: TObject);
const
SQL_CONST='Select SaleDate from orders where CustNo = %d';
var c1,c2,c3:Integer; s1,s2,s3:string;
begin //取得三个选择框客户的编码
c1:=Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
c2:=Integer(ComboBox2.Items.Objects[ComboBox2.ItemIndex]);
c3:=Integer(ComboBox3.Items.Objects[ComboBox3.ItemIndex]); //生成SQL 查询语句
s1:=Format(SQL_CONST,[c1]);
s2:=Format(SQL_CONST,[c2]);
s3:=Format(SQL_CONST,[c3]); //三个线程同时查询
TADOThread.Create(s1,ListBox1,Label1);
TADOThread.Create(s2,ListBox2,Label2);
TADOThread.Create(s3,ListBox3,Label3);
end; procedure TForm2.FormCreate(Sender: TObject);
var
strSQL:string;
begin
strSQL:='SELECT CustNo,Company FROM customer';
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(strSQL);
ADOQuery1.Open;
ComboBox1.Clear;
ComboBox2.Clear;
ComboBox3.Clear; //将客户Company和相关CustNo填到ComboBox中
while not ADOQuery1.Eof do
begin
ComboBox1.AddItem(ADOQuery1.Fields[].asString, TObject(ADOQuery1.Fields[].AsInteger));
ADOQuery1.Next;
end;
ComboBox2.Items.Assign(ComboBox1.Items);
ComboBox3.Items.Assign(ComboBox1.Items); // 默认选中第一个
ComboBox1.ItemIndex := ;
ComboBox2.ItemIndex := ;
ComboBox3.ItemIndex := ;
end;
end.
 {ADO查询多线程单元}
unit ADOThread;
interface
uses
Classes,StdCtrls,ADODB;
type TADOThread = class(TThread)
private { Private declarations }
FListBox:TListBox;
FLabel:TLabel;
ConnString:WideString;
FSQLString:string;
procedure UpdateCount;
protected procedure Execute; override;
public constructor Create(SQL:string;LB:TListBox;Lab:TLabel);
end; implementation
uses
Main,SysUtils,ActiveX;
{ TADOThread } constructor TADOThread.Create(SQL: string; LB: TListBox;Lab:TLabel);
begin
ConnString:=Form2.ADOConnection1.ConnectionString;
FListBox:=LB;
FLabel:=Lab;
FSQLString:=SQL;
Inherited Create(False);
end; procedure TADOThread.Execute;
var
Qry:TADOQuery;
i:Integer;
begin { Place thread code here }
FreeOnTerminate:=True;
CoInitialize(nil); //必须调用(需Uses ActiveX)
Qry:=TADOQuery.Create(nil);
try
Qry.ConnectionString:=ConnString; //必须有自己的连接
Qry.Close;
Qry.SQL.Clear;
Qry.SQL.Add(FSQLString);
Qry.Open;
FListBox.Clear;
for i := to do //为了执行久点重复历遍数据集101次
begin
while not Qry.Eof And not Terminated do
begin
FListBox.AddItem(Qry.Fields[].asstring,nil); //如果不调用Synchronize,会出现Canvas Does NOT Allow Drawing
Synchronize(UpdateCount);
Qry.Next;
end;
Qry.First;
FListBox.AddItem('*******',nil);
end;
finally
Qry.Free;
end;
CoUninitialize;
end; procedure TADOThread.UpdateCount;
begin
FLabel.Caption:=IntToStr(FListBox.Items.Count);
end;
end.

程序运行结果可以看到三个线程同时执行。第一第三两个线程条件一样,查询的结果也一样。

教程-Delphi多线程数据库查询(ADO)的更多相关文章

  1. Delphi多线程数据库查询(ADO)

    ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...

  2. 【转】Delphi多线程学习(9):多线程数据库查询(ADO)

    原文:http://www.cnblogs.com/djcsch2001/articles/2382559.html ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用 ...

  3. 多线程数据库查询(ADO)

    ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...

  4. ADO多线程数据库查询

    {ADO查询多线程单元} unit ADOThread; interface uses Classes,StdCtrls,ADODB; type TADOThread = class(TThread) ...

  5. Delphi多线程下的ADO编程

    前言: 几个月前接到一个任务:将一后台程序访问数据库的方式从BDE改为ADO,原因是由于业务量的增加,通过BDE不论是向数据库写入数据还是从数据库中读出数据的速度都变得无法忍受,大家都知道ADO在数据 ...

  6. ADO多线程数据库总结

    ADO多线程数据库查询通常会出现以下问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...

  7. Spring Security教程(二):自定义数据库查询

    Spring Security教程(二):自定义数据库查询   Spring Security自带的默认数据库存储用户和权限的数据,但是Spring Security默认提供的表结构太过简单了,其实就 ...

  8. delphi 多线程3

     多线程程序设计 我们知道,win95或winNT都是“多线程”的操作系统,在DELPHI .中,我们可以充分利用这一特性,编写出“多线程”的应用程序. 对以往在DOS或16位windows下写程序的 ...

  9. delphi 控件查询

    //老古董,以前这些东西太多了,收藏的没过来,只好粘贴至此,当然不是本人整理的. delphi 控件查询:http://www.torry.net/ http://www.jrsoftware.org ...

随机推荐

  1. 视图--bai

    /*视图的必要性 create view population_all_view as select xxxx 详细信息 from qgck where rownum<500 -- sql语句不 ...

  2. iOS 8 定位失败问题

    首先plist定义两个string:  NSLocationWhenInUseUsageDescription NSLocationAlwaysUsageDescription 然后调用 [self. ...

  3. 【Selenium】自动化调试后C盘越来越大

    在本机调试了一段时间自动化脚本后发现C盘占用越来越大,增长速度比较明显 通过360等工具清理系统垃圾表明并不好使 最后在系统临时文件中看到大量因为调试或不正常结束而Driver而产生的临时文件 具体方 ...

  4. Provider Communication with Apple Push Notification Service

    This chapter describes the interfaces that providers use for communication with Apple Push Notificat ...

  5. POJ1177+线段树+扫描线

    思路: 以y的值进行离散化 根据x的值 对每一条y轴边进行处理,如果是"左边"则插入,是"右边"则删除. /* 扫描线+线段树+离散化 求多个矩形的周长 */ ...

  6. Android笔记5-与USB HID 设备通信(一)

    1.了解 支持USB 主机(host)或者从机(accessary )模式最终是取决于设备的硬件,而与平台版本无关.我们可以通过usesfeature这个方法来查询自己的设备是否支持USB主从.   ...

  7. Android list1去除list2中的元素

    public static void main(String[] args) { List<String> firList = new ArrayList<String>(); ...

  8. spring声明式事务 同一类内方法调用事务失效

    只要避开Spring目前的AOP实现上的限制,要么都声明要事务,要么分开成两个类,要么直接在方法里使用编程式事务 [问题] Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring ...

  9. wcf service library

    创建wcf服务库的时候,系统自动生成的代码 // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”. [ServiceContract] publ ...

  10. Sublime Text个性化设置

    个性化格式化代码快捷键 其余快捷键设置方法类似,但注意不要与软件自带快捷键冲突 选择Preferences,点击Key Bingdings - User 在打开的文件中添加,其中ctrl+alt+sp ...