ADO多线程数据库总结
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接口使用就可以了。
{主窗体代码}
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.
{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.
ADO多线程数据库总结的更多相关文章
- ADO多线程数据库查询
{ADO查询多线程单元} unit ADOThread; interface uses Classes,StdCtrls,ADODB; type TADOThread = class(TThread) ...
- 【转】Delphi多线程学习(9):多线程数据库查询(ADO)
原文:http://www.cnblogs.com/djcsch2001/articles/2382559.html ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用 ...
- 教程-Delphi多线程数据库查询(ADO)
ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...
- Delphi多线程数据库查询(ADO)
ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...
- 多线程数据库查询(ADO)
ADO多线程数据库查询通常会出现3个问题: 1.CoInitialize 没有调用(CoInitialize was not called):所以,在使用任何dbGo对象前,必须手 调用CoIniti ...
- android 多线程数据库读写分析与优化
最新需要给软件做数据库读写方面的优化,之前无论读写,都是用一个 SQLiteOpenHelper.getWriteableDataBase() 来操作数据库,现在需要多线程并发读写,项目用的是2.2的 ...
- 用ADO操作数据库的方法步骤(ZT)
http://www.cppblog.com/changshoumeng/articles/113437.html 学习ADO时总结的一些经验 用ADO操作数据库的方法步骤 ADO接口简介 ADO库包 ...
- ADO.Net 数据库 删除
删除数据库里的信息和之前增加,修改大同小异,其写法更加简单,也是把SQL语句写为删除语句 删除一条数据,只需要获取并接收到这条数据唯一的能够代表这条数据的信息,比如主键 代码演示: using Sys ...
- ADO.Net 数据库修改
数据库的修改方法和增加一样,只是把增加语句换成了修改语句,后面执行语句是相同的 首先也是需要获取并接收输入的要修改的哪个数据以及修改后的数据 代码演示: using System; using Sys ...
随机推荐
- SwingWorker
Swing应用程序员常见的错误是误用Swing事件调度线程(Event DispatchThread,EDT).他们要么从非UI线程访问UI组件:要么不考虑事件执行顺序:要么不使用独立任务线程而在ED ...
- mysql中update+select
mysql中不支持嵌套查询后更新操作. 但是可以使用inner join来解决自身的更新问题,参考如下例子: update hera_job a inner join( ),'"') as ...
- 【转】 Windows下配置Git
[转自]http://blog.csdn.net/exlsunshine/article/details/18939329 1.从git官网下载windows版本的git:http://git-scm ...
- Visual Studio TFS Branching and Merging Guidance
Origin URL:https://msdn.microsoft.com/en-us/magazine/gg598921.aspx Bill Heys and Willy-Peter Schaub ...
- Tensorflow读写TFRecords文件
在使用slim之类的tensorflow自带框架的时候一般默认的数据格式就是TFRecords,在训练的时候使用TFRecords中数据的流程如下:使用input pipeline读取tfrecord ...
- [OpenCV] Samples 18: Load image and check its attributes
本篇内容: * 图片读取 * 图片高宽 * 图片ROI * 图片缩放 Ref: http://blog.csdn.net/u012005313/article/details/51943442 官网2 ...
- [React] 13 - Redux: react-redux
Ref: Redux 入门教程(三):React-Redux 的用法 组件拆分规范 使用 React-Redux,需要掌握额外的 API,并且要遵守它的组件拆分规范. React-Redux 将所有组 ...
- SQL Server -- stuff 函数
STUFF 删除指定长度的字符并在指定的起始点插入另一组字符. 语法 STUFF ( character_expression , start , length , character_express ...
- 【代码审计】XYHCMS V3.5任意文件下载漏洞分析
0x00 环境准备 XYHCMS官网:http://www.xyhcms.com/ 网站源码版本:XYHCMS V3.5(2017-12-04 更新) 程序源码下载:http://www.xyhc ...
- C#利用反射实现两个类的对象之间相同属性的值的复制
http://blog.csdn.net/u013093547/article/details/53584591 今天在拷贝对象的时候,看着代码实在是有点烦,一堆一样的代码,还是找找有没有直接反射拷贝 ...