There are 3 problems with ADO multithreaded database queries:
1. CoInitialize is not called (CoInitialize is not called), so you must call CoInitialize and CoUninitialize before using any Dbgo object. Failure to invoke CoInitialize results in an exception of "CoInitialize is not called".
2. Canvas is not allowed to paint (canvas does not allow drawing); Therefore, the main thread must be notified through the synchronize process to access any control on the master form.
3. You cannot use the main ADO connection (main tadoconnection cannot be used!); Therefore, threads cannot use tadoconnection objects in the main thread, and each thread must create its own database connection.
Delphi2007 after installation there is a Shared\data file in the X:\Program Files\Common Files\codegear Dbdemos.mdb directory, which is used as an example of testing. The Customer table in Dbdemos.mdb holds the client information, and the order information is saved in the Orders table.
The test program flow is basically this: put the tadoconnection and Tquery controls on the main form, and at startup this tquery isolate the customer code CUSTNO and company name from the Customers table, put it in three combox boxes, Select the customer company name in three list boxes, establish three threads according to the customer code corresponding to the company name, and query the sales date in the Orders table Saledate respectively into the listbox.
1 {main form code} 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 ; button1:tbutton;15 adoconnection1:tadoconnection;16 Adoquery1:tadoquery; label1:tlabel;18 label2:tlabel;19 label3:tlabel;20 Procedure formcreate (sender:tobject); Procedure Button1Click (sender:tobject); private {Private declarations}23 public {public Declarations}24 end;25 var form2:tform2;26 implementation27 uses28 adothread;29 {$R *.dfm}30 procedure Tform2.button1click (Sender: TObject); const sql_const= ' Select saledate from orders where Custno =%d '; var C1,c2,c3:integer; S1,S2,S3:STRING;35 begin//Get three selection box customer's code C1:=integer (Combobox1.items.objects[combobox1.itemindex]); Notoginseng C2:=integer (COmbobox2.items.objects[combobox2.itemindex]); C3:=integer (Combobox3.items.objects[combobox3.itemindex]); Generate SQL Query Statement S1:=format (SQL_CONST,[C1]); S2:=format (Sql_const,[c2]); S3:=format (SQL_CONST,[C3]); Three threads simultaneously query Tadothread.create (S1,LISTBOX1,LABEL1), Tadothread.create (S2,listbox2,label2), Tadothread.create ( S3,LISTBOX3,LABEL3) end;46 procedure tform2.formcreate (sender:tobject); var49 strsql:string;50 begin51 strSQL : = ' SELECT custno,company from customer '; adoquery1.close;53 adoquery1.sql.clear;54 ADOQuery1.SQL.Add (strSQL); 55 adoquery1.open;56 combobox1.clear;57 combobox2.clear;58 combobox3.clear; Fill in the ComboBox with the customer company and related Custno adoquery1.eof do60 begin61 ComboBox1.AddItem (adoquery1.fields[1].asst Ring, TObject (Adoquery1.fields[0]. Asinteger) adoquery1.next;63 end;64 ComboBox2.Items.Assign (combobox1.items); ComboBox3.Items.Assign (Combob Ox1. Items); The first Combobox1.itemindex is selected by default: = 0;67 ComboBox2.itemindex: = 0;68 Combobox3.itemindex: = 0;69 end;70 end.
1 {ADO Query multithreaded unit} 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 Ex Ecute; Override;14 Public constructor Create (Sql:string;lb:tlistbox; Lab:tlabel); end;16 implementation18 uses19 main,sysutils,activex;20 {tadothread}21 constructor tadothread.c Reate (sql:string; Lb:tlistbox; Lab:tlabel); Begin24 connstring:=form2.adoconnection1.connectionstring;25 flistbox:=lb;26 FLabel:=Lab;27 FSQLStr Ing:=sql;28 inherited Create (False) end;30 procedure tadothread.execute;32 var33 qry:tadoquery;34 i:integer;35 Begin {Place thread code here}36 freeonterminate:=true;37 CoInitialize (nil); Must call (need uses ActiveX) qry:=tadoquery.create (nil); try40 qry.connectionstring:=connstring; Must have its own connection to the qry.close;42 Qry.SQL.Clear;QRY.SQL.ADD (fsqlstring), qry.open;45 flistbox.clear;46 for I: = 0 to +//in order to perform a long repetition of the data set 101 times 47 Begin48 while not qry.eof and not Terminated do49 begin50 Flistbox.additem (qry.fields[0].asstring,nil ); If you do not call Synchronize, the canvas Does not allow Drawing51 Synchronize (Updatecount) will appear; qry.next;53 end;54 Qry.first;55 flistbox.additem (' ******* ', nil); end;57 finally58 qry.free;59 end;60 couninitial ize;61 end;62 procedure tadothread.updatecount;64 begin65 flabel.caption:=inttostr (FListBox.Items.Count); end;67 End.
The results of the program run can see three threads executing simultaneously. The first 32 thread conditions are the same as the results of a query.
Http://www.cnblogs.com/FKdelphi/p/4654473.html
Delphi Multi-Threaded database query (ADO)