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. unit ADOThread;
  2.  
  3. interface
  4.  
  5. uses
  6. Classes,StdCtrls,ADODB;
  7.  
  8. type
  9. TADOThread = class(TThread)
  10. private
  11. { Private declarations }
  12. FListBox:TListBox;
  13. FLabel:TLabel;
  14. ConnString:WideString;
  15. FSQLString:string;
  16. procedure UpdateCount;
  17. protected
  18. procedure Execute; override;
  19. public
  20. constructor Create(SQL:string;LB:TListBox;Lab:TLabel);
  21. end;
  22.  
  23. implementation
  24.  
  25. uses Main,SysUtils,ActiveX;
  26.  
  27. { TADOThread }
  28.  
  29. constructor TADOThread.Create(SQL: string; LB: TListBox;Lab:TLabel);
  30. begin
  31. ConnString:=Form2.ADOConnection1.ConnectionString;
  32. FListBox:=LB;
  33. FLabel:=Lab;
  34. FSQLString:=SQL;
  35. Inherited Create(False);
  36. end;
  37.  
  38. procedure TADOThread.Execute;
  39. var
  40. Qry:TADOQuery;
  41. i:Integer;
  42. begin
  43. { Place thread code here }
  44. FreeOnTerminate:=True;
  45. CoInitialize(nil); //必须调用(需Uses ActiveX)
  46. Qry:=TADOQuery.Create(nil);
  47. try
  48. Qry.ConnectionString:=ConnString; //必须有自己的连接
  49. Qry.Close;
  50. Qry.SQL.Clear;
  51. Qry.SQL.Add(FSQLString);
  52. Qry.Open;
  53. FListBox.Clear;
  54. for i := 0 to 100 do //为了执行久点重复历遍数据集101次
  55. begin
  56. while not Qry.Eof And not Terminated do
  57. begin
  58. FListBox.AddItem(Qry.Fields[0].asstring,nil);
  59. //如果不调用Synchronize,会出现Canvas Does NOT Allow Drawing
  60. Synchronize(UpdateCount);
  61. Qry.Next;
  62. end;
  63. Qry.First;
  64. FListBox.AddItem('*******',nil);
  65. end;
  66. finally
  67. Qry.Free;
  68. end;
  69. CoUninitialize;
  70. end;
  71.  
  72. procedure TADOThread.UpdateCount;
  73. begin
  74. FLabel.Caption:=IntToStr(FListBox.Items.Count);
  75. end;
  76.  
  77. end.

  

  1. unit Main;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, DB, ADODB, StdCtrls;
  8.  
  9. type
  10. TForm2 = class(TForm)
  11. ComboBox1: TComboBox;
  12. ComboBox2: TComboBox;
  13. ComboBox3: TComboBox;
  14. ListBox1: TListBox;
  15. ListBox2: TListBox;
  16. ListBox3: TListBox;
  17. Button1: TButton;
  18. ADOConnection1: TADOConnection;
  19. ADOQuery1: TADOQuery;
  20. Label1: TLabel;
  21. Label2: TLabel;
  22. Label3: TLabel;
  23. procedure FormCreate(Sender: TObject);
  24. procedure Button1Click(Sender: TObject);
  25. private
  26. { Private declarations }
  27. public
  28. { Public declarations }
  29. end;
  30.  
  31. var
  32. Form2: TForm2;
  33.  
  34. implementation
  35.  
  36. uses ADOThread;
  37.  
  38. {$R *.dfm}
  39.  
  40. procedure TForm2.Button1Click(Sender: TObject);
  41. const
  42. SQL_CONST='Select SaleDate from orders where CustNo = %d';
  43. var
  44. c1,c2,c3:Integer;
  45. s1,s2,s3:string;
  46. begin
  47. //取得三个选择框客户的编码
  48. c1:=Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex]);
  49. c2:=Integer(ComboBox2.Items.Objects[ComboBox2.ItemIndex]);
  50. c3:=Integer(ComboBox3.Items.Objects[ComboBox3.ItemIndex]);
  51. //生成SQL 查询语句
  52. s1:=Format(SQL_CONST,[c1]);
  53. s2:=Format(SQL_CONST,[c2]);
  54. s3:=Format(SQL_CONST,[c3]);
  55. //三个线程同时查询
  56. TADOThread.Create(s1,ListBox1,Label1);
  57. TADOThread.Create(s2,ListBox2,Label2);
  58. TADOThread.Create(s3,ListBox3,Label3);
  59. end;
  60.  
  61. procedure TForm2.FormCreate(Sender: TObject);
  62. var
  63. strSQL:string;
  64. begin
  65. strSQL:='SELECT CustNo,Company FROM customer';
  66. ADOQuery1.Close;
  67. ADOQuery1.SQL.Clear;
  68. ADOQuery1.SQL.Add(strSQL);
  69. ADOQuery1.Open;
  70. ComboBox1.Clear;
  71. ComboBox2.Clear;
  72. ComboBox3.Clear;
  73. //将客户Company和相关CustNo填到ComboBox中
  74. while not ADOQuery1.Eof do
  75. begin
  76. ComboBox1.AddItem(ADOQuery1.Fields[1].asString,
  77. TObject(ADOQuery1.Fields[0].AsInteger));
  78. ADOQuery1.Next;
  79. end;
  80. ComboBox2.Items.Assign(ComboBox1.Items);
  81. ComboBox3.Items.Assign(ComboBox1.Items);
  82. // 默认选中第一个
  83. ComboBox1.ItemIndex := 0;
  84. ComboBox2.ItemIndex := 0;
  85. ComboBox3.ItemIndex := 0;
  86. end;
  87.  
  88. end.{ADO查询多线程单元}

  

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

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

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

  2. 教程-Delphi多线程数据库查询(ADO)

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

  3. Delphi多线程数据库查询(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. ADO多线程数据库总结

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

  6. android 多线程数据库读写分析与优化

    最新需要给软件做数据库读写方面的优化,之前无论读写,都是用一个 SQLiteOpenHelper.getWriteableDataBase() 来操作数据库,现在需要多线程并发读写,项目用的是2.2的 ...

  7. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

  8. 利用C#实现分布式数据库查询

    随着传统的数据库.计算机网络和数字通信技术的飞速发展,以数据分布存储和分布处理为主要特征的分布式数据库系统的研究和开发越来越受到人们的关注.但由于其开发较为复杂,在一定程度上制约了它的发展.基于此,本 ...

  9. python操作oracle数据库-查询

    python操作oracle数据库-查询 参照文档 http://www.oracle.com/technetwork/cn/articles/dsl/mastering-oracle-python- ...

随机推荐

  1. 提高modem的core dump级别

    zhangze@zhangze-OptiPlex-7040:~/e2_8939-E2-2104026-CTA/device/qcom/common$ git showcommit be2b5cb33a ...

  2. 【原创】重装Windows系统后Android studio无需重装,直接迁移

    每次重装Windows系统后重装各种开发环境让人苦不堪言,比如VS2013 +补丁,没有个小半天根本搞不定! 对与Android的开发者,同样安装JDK+Android Studio + Adnroi ...

  3. 电商系统架构总结1(EF)

    最近主导了一个电商系统的设计开发过程,包括前期分析设计,框架搭建,功能模块的具体开发(主要负责在线支付部分),成功上线后的部署维护,运维策略等等全过程. 虽然这个系统不是什么超大型的电商系统 数亿计的 ...

  4. 请求(Request)的参数(Param)里包含特殊字符(#等)的正确处理方式

    当调用restful接口,并且url中有参数传过去时,比如http://test.com?param=woshi#miaoyinga. 后台在使用@RequestParam("param&q ...

  5. uva-10282-枚举

    题意:语言翻译, 直接map即可 #include "pch.h" #include <string> #include<iostream> #includ ...

  6. javafx链接实现

    方式一: Desktop.getDesktop().browse(new URI(manualUrl)); 在linux环境bug 方式二: 转载自:https://stackoverflow.com ...

  7. python文件读取和写入案例

    python文件读取和写入案例  直接上代码吧 都是说明 百度上找了很多,最终得出思路 没有直接可以读取修改的扩展,只能先读取,然后复制一份,然后在复制出来的文件里面追加保存 然后删除读的那个,但是缺 ...

  8. 13. 字符串转为json对象或json数组

    ##########1.json字符串转json数组########### var str="[{name:'zhangsan',age:'24'},{name:'lisi',age:'30 ...

  9. 恺撒密码 I Python实现

    '''恺撒密码 I描述凯撒密码是古罗马凯撒大帝用来对军事情报进行加解密的算法,它采用了替换方法对信息中的每一个英文字符循环替换为字母表序列中该字符后面的第三个字符,即,字母表的对应关系如下:原文:A ...

  10. 03.设计模式_抽象工厂模式(Abstract Fcatory)

    抽象工厂模式:创建一些列相关或者互相依赖的对象的接口,而无需指定他们具体的类, 1.创建工厂Factory: package patterns.design.factory; import java. ...