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

    1.maven配置 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www ...

  2. 定义#define

                                                    定义符号常量   当我们不止一次用到某个符号常量时,常选择对符号变量进行定义,这样就能当成一般常量来用. ...

  3. C语言学习笔记frist---输入两个数比较大小

    C#学习中,问道艰辛,今自C学起,第一个函数学习:输入两个数比较大小,仅作练习: #include "stdafx.h" #include<stdio.h> // 包含 ...

  4. Delphi获取系统服务描述信息

    program Project1; {$APPTYPE CONSOLE} uses Windows, WinSvc; type SERVICE_DESCRIPTION = packed record ...

  5. Java 并发专题 :FutureTask 实现预加载数据 在线看电子书、浏览器浏览网页等

    继续并发专题~ FutureTask 有点类似Runnable,都可以通过Thread来启动,不过FutureTask可以返回执行完毕的数据,并且FutureTask的get方法支持阻塞. 由于:Fu ...

  6. logstash grok正则调试

    logstash 正则调试: nginx 配置: log_format main '$remote_addr [$time_local] "$request" '; logstas ...

  7. uva540 Team Queue by sixleaves

    这道题目.主要是对队列的灵活应用.其实就是一道模拟题目,只要你洞察出题目的本质就十分简单.题目意思大体是有多组测试数据,每组的一开始是一个数字t,代表一共有多少的团队,接着是t行输入,每一行都由一个数 ...

  8. 杭电oj 2037 今年暑假不AC

    Tips:贪心算法的典型应用,可以按照节目结束时间由小到大排序,(至于结束时间相同的,有些人说按开始时间早的排序,不过个人认为不必处理,因为结束时间一样,两个之中要么都没有,要么必有一个)然后再依次进 ...

  9. 通过P-SMR看State Machine Replication

    在一个复制系统中,为了保持一致性,各个replicated server是串行运行.这样性能上就会比仅仅有一台server的系统慢,由于仅仅有一台server能够进行并行处理.假设在复制系统中各个se ...

  10. paip.vs2010 或.net 4.0安装出错解决大法.

    paip.vs2010 或.net 4.0安装出错解决大法. 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.cs ...