【转】Delphi多线程学习(9):多线程数据库查询(ADO)
原文:http://www.cnblogs.com/djcsch2001/articles/2382559.html
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中。
{主窗体代码}
- 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[1].asString,
- TObject(ADOQuery1.Fields[0].AsInteger));
- ADOQuery1.Next;
- end;
- ComboBox2.Items.Assign(ComboBox1.Items);
- ComboBox3.Items.Assign(ComboBox1.Items);
- // 默认选中第一个
- ComboBox1.ItemIndex := 0;
- ComboBox2.ItemIndex := 0;
- ComboBox3.ItemIndex := 0;
- 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 := 0 to 100 do //为了执行久点重复历遍数据集101次
- begin
- while not Qry.Eof And not Terminated do
- begin
- FListBox.AddItem(Qry.Fields[0].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多线程学习(9):多线程数据库查询(ADO)的更多相关文章
- C#多线程学习(一) 多线程的相关概念(转)
什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序中的一个执行流,每个线程都有自己的专有寄 ...
- C#多线程学习(一) 多线程的相关概念
什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序中的一个执行流,每个线程都有自己的专有寄 ...
- [转载]C#多线程学习(一) 多线程的相关概念
原文地址:http://www.cnblogs.com/xugang/archive/2008/04/06/1138856.html 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的 ...
- C#多线程学习(四) 多线程的自动管理(线程池)
在多线程的程序中,经常会出现两种情况: 一种情况: 应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应 这一般使用ThreadPo ...
- MySQL学习基础之一 — 数据库查询
廖大神的练手神器:在线SQL: https://www.liaoxuefeng.com/wiki/1177760294764384/1179611432985088 运行MySQL等实际的数据库软件, ...
- Java学习笔记 DbUtils数据库查询和log4j日志输出 使用
DbUtils使用 QueryRunner DbUtils中定义了一个数据库操作类QueryRunner,所有的数据库操作CRUD都是通过此类来完成. 此类是线程安全的 方法名 对应sql语句 exc ...
- C++并发与多线程学习笔记--多线程数据共享问题
创建和等待多个线程 数据和共享问题分析 只读的数据 有读有写 其他案例 共享数据的保护案例代码 创建和等待多个线程 服务端后台开发就需要多个线程执行不同的任务.不同的线程执行不同任务,并返回执行结果. ...
- 学习练习 java数据库查询小题
10. 查询Score表中的最高分的学生学号和课程号.(子查询或者排序) 11. 查询每门课的平均成绩. 12.查询Score表中至少有5名学生选修的并以3开头的课程的平均分数. 13.查询分数大于7 ...
- C#多线程学习(五) 多线程的自动管理(定时器)
Timer类:设置一个定时器,定时执行用户指定的函数. 定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数. 初始化一个Timer对象: Timer timer ...
- 【转】C#多线程学习
C#多线程学习(一) 多线程的相关概念 什么是进程?当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程?线程是程序 ...
随机推荐
- 【转】linux_fdisk命令详解
转自:http://www.cnblogs.com/xiaofengkang/archive/2011/06/06/2073579.html fdisk -l 可以列出所有的分区,包括没有挂上的分区和 ...
- cefSharp在XP下使得程序崩溃记录
前言:这是一个奇葩的问题,到现在自己还没有搞明白问题出现在哪里,但是从问题总算是解决了,希望看到此文章的大牛,如果知道问题出在什么地方,可以告知一下. [一个在XP系统下面应用程序崩溃问题] 资源: ...
- 转 毛笔字教程ps
跟大家分享一下毛笔字怎么做出来的,主要通过字体和素材叠加,十分简单,喜欢的一起练习.做完记得交作业. 先看看最终效果: 在网上是不是经常看这些碉堡了的毛笔感觉是不是很羡慕啊,现在我就教大家怎么做出这样 ...
- CodeIgniter 3.0+ 部署linux环境 session报错
codeigniter Message: mkdir(): Invalid path Filename: drivers/Session_files_driver.php 看起来像权限问题,在默认情况 ...
- arm tiny6410双网卡桥接问题
这几天做实验,想用arm tiny6410板子做个mesh网络节点.该板子本身自带一个lan网卡,我自己配了一个tp-link的usb无线网卡.其中wlan网卡工作在adhoc模式下,作为mesh骨干 ...
- JS获得月最后一天和js得到一个月最大天数
<html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>标题页</title ...
- UIActivityViewController 自定义选项
UIActivityViewController 自定义选项 重写 UIActivity 类 建议下载github上源码学习一下 https://github.com/samvermette/SVWe ...
- linux rar工具
rar系统工具: wget http://www.rarlab.com/rar/rarlinux-3.8.0.tar.gz tar -zxvf rarlinux-3.8.0.tar.gz cd rar ...
- Time vs Story Points Estimation [转]
One of the most common questions we get is whether to estimate in time or points. It seems like poin ...
- MySQL 5.5 服务器变量详解二(转)
add by zhj:在MySQL5.6中对一些参数有增删改,详见http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html ...