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

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中。

 1 {主窗体代码}
2 unit Main;
3 interface
4 uses Windows, Messages, SysUtils, Variants,
5 Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB, StdCtrls;
6 type
7 TForm2 = class(TForm)
8 ComboBox1: TComboBox;
9 ComboBox2: TComboBox;
10 ComboBox3: TComboBox;
11 ListBox1: TListBox;
12 ListBox2: TListBox;
13 ListBox3: TListBox;
14 Button1: TButton;
15 ADOConnection1: TADOConnection;
16 ADOQuery1: TADOQuery;
17 Label1: TLabel;
18 Label2: TLabel;
19 Label3: TLabel;
20 procedure FormCreate(Sender: TObject);
21 procedure Button1Click(Sender: TObject);
22 private { Private declarations }
23 public { Public declarations }
24 end;
25 var Form2: TForm2;
26 implementation
27 uses
28 ADOThread;
29 {$R *.dfm}
30
31 procedure TForm2.Button1Click(Sender: TObject);
32 const
33 SQL_CONST='Select SaleDate from orders where CustNo = %d';
34 var c1,c2,c3:Integer; s1,s2,s3:string;
35 begin //取得三个选择框客户的编码
36 c1:=Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
37 c2:=Integer(ComboBox2.Items.Objects[ComboBox2.ItemIndex]);
38 c3:=Integer(ComboBox3.Items.Objects[ComboBox3.ItemIndex]); //生成SQL 查询语句
39 s1:=Format(SQL_CONST,[c1]);
40 s2:=Format(SQL_CONST,[c2]);
41 s3:=Format(SQL_CONST,[c3]); //三个线程同时查询
42 TADOThread.Create(s1,ListBox1,Label1);
43 TADOThread.Create(s2,ListBox2,Label2);
44 TADOThread.Create(s3,ListBox3,Label3);
45 end;
46
47 procedure TForm2.FormCreate(Sender: TObject);
48 var
49 strSQL:string;
50 begin
51 strSQL:='SELECT CustNo,Company FROM customer';
52 ADOQuery1.Close;
53 ADOQuery1.SQL.Clear;
54 ADOQuery1.SQL.Add(strSQL);
55 ADOQuery1.Open;
56 ComboBox1.Clear;
57 ComboBox2.Clear;
58 ComboBox3.Clear; //将客户Company和相关CustNo填到ComboBox中
59 while not ADOQuery1.Eof do
60 begin
61 ComboBox1.AddItem(ADOQuery1.Fields[1].asString, TObject(ADOQuery1.Fields[0].AsInteger));
62 ADOQuery1.Next;
63 end;
64 ComboBox2.Items.Assign(ComboBox1.Items);
65 ComboBox3.Items.Assign(ComboBox1.Items); // 默认选中第一个
66 ComboBox1.ItemIndex := 0;
67 ComboBox2.ItemIndex := 0;
68 ComboBox3.ItemIndex := 0;
69 end;
70 end.
 1 {ADO查询多线程单元}
2 unit ADOThread;
3 interface
4 uses
5 Classes,StdCtrls,ADODB;
6 type TADOThread = class(TThread)
7 private { Private declarations }
8 FListBox:TListBox;
9 FLabel:TLabel;
10 ConnString:WideString;
11 FSQLString:string;
12 procedure UpdateCount;
13 protected procedure Execute; override;
14 public constructor Create(SQL:string;LB:TListBox;Lab:TLabel);
15 end;
16
17 implementation
18 uses
19 Main,SysUtils,ActiveX;
20 { TADOThread }
21
22 constructor TADOThread.Create(SQL: string; LB: TListBox;Lab:TLabel);
23 begin
24 ConnString:=Form2.ADOConnection1.ConnectionString;
25 FListBox:=LB;
26 FLabel:=Lab;
27 FSQLString:=SQL;
28 Inherited Create(False);
29 end;
30
31 procedure TADOThread.Execute;
32 var
33 Qry:TADOQuery;
34 i:Integer;
35 begin { Place thread code here }
36 FreeOnTerminate:=True;
37 CoInitialize(nil); //必须调用(需Uses ActiveX)
38 Qry:=TADOQuery.Create(nil);
39 try
40 Qry.ConnectionString:=ConnString; //必须有自己的连接
41 Qry.Close;
42 Qry.SQL.Clear;
43 Qry.SQL.Add(FSQLString);
44 Qry.Open;
45 FListBox.Clear;
46 for i := 0 to 100 do //为了执行久点重复历遍数据集101次
47 begin
48 while not Qry.Eof And not Terminated do
49 begin
50 FListBox.AddItem(Qry.Fields[0].asstring,nil); //如果不调用Synchronize,会出现Canvas Does NOT Allow Drawing
51 Synchronize(UpdateCount);
52 Qry.Next;
53 end;
54 Qry.First;
55 FListBox.AddItem('*******',nil);
56 end;
57 finally
58 Qry.Free;
59 end;
60 CoUninitialize;
61 end;
62
63 procedure TADOThread.UpdateCount;
64 begin
65 FLabel.Caption:=IntToStr(FListBox.Items.Count);
66 end;
67 end.

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

http://www.cnblogs.com/FKdelphi/p/4654473.html

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. delphi 多线程3

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

  8. Delphi多线程详解

    (整理自网络) Delphi多线程处理 1-1多线程的基本概念 WIN 98/NT/2000/XP 是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU 运行时间和资源,或者 ...

  9. delphi 控件查询

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

随机推荐

  1. 整理:GET与POST的区别

    1.根据HTTP规范,GET用于信息获取,而且应该是安全的和幂等的. (1).所谓安全的意味着该操作用于获取信息而非修改信息.换句话说,GET 请求一般不应产生副作用.就是说,它仅仅是获取资源信息,就 ...

  2. http status 400,http 400,400 错误

    转载:http://blog.csdn.net/xu_zh_h/article/details/2294233 4 请求失败4xx 4xx应答定义了特定服务器响应的请求失败的情况.客户端不应当在不更改 ...

  3. UVA 12563 Jin Ge Jin Qu hao

    dp-背包 开始用普通dp写了一发发现没法确定最大时间... 后来看到大牛机智的写法,嗯...dp表示当前状态能否成立:然后从条件最好的状态开始遍历,直到这个状态成立然后退出遍历. 具体的看代码吧.. ...

  4. Node.js HTTP 使用详解

    对于初学者有没有发觉在查看Node.js官方API的时候非常简单,只有几个洋文描述两下子,没了,我第一次一口气看完所以API后,对于第一个示例都有些懵,特别是参数里的request和response, ...

  5. VirtualBox 上安装CentOS 6.5

    目标:1.在VirtualBox中安装CentOS2.配置虚拟机网络,实现:    a.主机联网后,宿机能够通过主机上网    b.不管主机联网与否,主机都能SSH登录宿机,并且主宿机能互相传送文件 ...

  6. vmware配置安装JDK、Tomcat以及项目部署

    1.安装JDK1.7 JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html 安 ...

  7. HDOJ-1003 Max Sum(最大连续子段 动态规划)

    http://acm.hdu.edu.cn/showproblem.php?pid=1003 给出一个包含n个数字的序列{a1,a2,..,ai,..,an},-1000<=ai<=100 ...

  8. Object-C自定义对象NSLog输入信息

    http://blog.cnrainbird.com/index.php/2012/07/19/object-c_zi_ding_yi_dui_xiang_nslog_shu_ru_you_yong_ ...

  9. bzoj 维护序列seq(双标记线段树)

    Seq 维护序列seq Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 4184  Solved: 1518[Submit][Status][Discus ...

  10. Oracle 存储过程之通用分页查询

    在数据库中书写通用分页存储过程,有利于代码的维护以及执行效率的提升 create or replace procedure Sp_QueryDatePage ( tableName in varcha ...