---- 在數(shù)據(jù)庫(kù)管理系統(tǒng)中,查詢的方式主要有以下幾種:1.固定字段的單一查詢。2.可選擇字段的單一查詢。3.限制若干個(gè)字段的多重查詢。4.可任意選擇字段的多重查詢。前兩種也稱為單條件查詢,后兩種稱為多重(或多條件)查詢。在實(shí)際中,系統(tǒng)(實(shí)為程序員)提供給用戶的查詢方式以單條件查詢?yōu)槎,即使提供了多條件方式,通常也只有兩或三個(gè)條件,因?yàn)榫帉懚嘀夭樵兪且豁?xiàng)非常棘手且煩瑣的事情。實(shí)際上,利用表格Grid功能,就能輕松地實(shí)現(xiàn)多重查詢。本人以Delphi為例,介紹具體的實(shí)現(xiàn)方法。這種思想,也同樣適合于其他的編程語(yǔ)言(如Visual Foxpro)。
----程序主要按如下三個(gè)功能來(lái)實(shí)現(xiàn):
設(shè)置DBGrid; 生成查詢條件(語(yǔ)句); 執(zhí)行查詢。 ----具體步驟如下:
----⑴新建一工程文件,取名為PDBGrid.dpr;
----⑵給單元文件取名為UDBGrid.pas,在其相應(yīng)的表單(取名為frmDBGrid)中添加如下控件并編寫相應(yīng)的代碼:
----其中Table2(記錄查詢條件的數(shù)據(jù)集)對(duì)應(yīng)的表 CxComm.db的結(jié)構(gòu)定義如下:
----表單的FormActivate事件代碼如下:
procedure TfrmDBGrid.FormActivate(Sender: TObject); begin if Table2.Active then Table2.Close; Table2.EmptyTable; //清空條件 Table1.Open; Table2.Open; end;
Button1(設(shè)置DBGrid)的Click事件代碼如下: procedure TfrmDBGrid.Button1Click(SenderTObject); begin MySetDBGrid(Table1,DBGrid2); // MySetDBGrid為自定義過(guò)程 //以Table1為數(shù)據(jù)源,DBGrid2為記錄篩選(查詢)條件的表格 end;
Button2(生成查詢)的Click事件代碼如下: procedureTfrmDBGrid.Button2Click(Sender:TObject); begin if MyCreate_SQL(Table1,Table2,Query1) //MyCreate_SQL為自定義函數(shù) //由指定數(shù)據(jù)來(lái)源表生成SQL,存入Query1 then begin Memo1.Lines.Clear; Memo1.Lines:=(Query1.SQL); Memo1.Modified:=false; end end;
Button3(執(zhí)行查詢)的Click事件代碼如下: procedureTfrmDBGrid.Button3Click(Sender:TObject); begin with Query1,SQL do begin Close; if Memo1.Modified //用戶可修改SQL語(yǔ)句 then SQL:=Memo1.Lines; try ExecSQL; Open; except //捕捉錯(cuò)誤并處理 begin MessageBeep(0); Application.MessageBox(‘錯(cuò)誤的SQL語(yǔ)句!', ‘確認(rèn)',MB_OK+MB_ICONSTOP); Close; end; end //try end; end; //執(zhí)行SQL
----自定義過(guò)程MySetDBGrid (設(shè)置DBGrid)的代碼如下:
procedure TfrmDBGrid.MySetDBGrid (sTable:TTable;tjDBGrid:TDBGrid); //參數(shù)說(shuō)明:sTable為數(shù)據(jù)(包括字段、記錄)來(lái)源表 // tjDBGrid為記錄篩選(查詢)條件的表格 var i:byte; begin //設(shè)置查詢項(xiàng)目 if not sTable.Active then sTable.Open; tjDBGrid.Columns[0].PickList.Clear; for i:=0 to sTable.FieldCount-1 do //記錄數(shù)(即字段數(shù)) begin tjDBGrid.Columns[0].PickList.Add (sTable.Fields[i].FieldName); end; //for //設(shè)置關(guān)系(=,<>,>,>=,<,<=) 及邏輯(AND,OR) tjDBGrid.Columns[1].PickList.Text:=‘='+#13+ ‘<>'+#13+‘>'+#13+‘>='+#13+‘<'+#13+ ‘<=';tjDBGrid.Columns[3].PickList.Text:=‘AND'+#13+ ‘OR'; end;//設(shè)置DBGrid
----自定義函數(shù)MyCreate_SQL (生成查詢)的代碼如下:
function TfrmDBGrid.MyCreate_SQL (sTable,tjTable:TTable;tjQuery:TQuery):boolean; //參數(shù)說(shuō)明:sTable為數(shù)據(jù)(包括字段、記錄)來(lái)源表 // tjTable為記錄篩選(查詢)條件的表 // tjQuery記錄SQL語(yǔ)句 var i:byte; lsDate:TDate; //檢測(cè)日期格式用 sLj,sFilter,sFieldName:string; //分別表示:邏輯關(guān)系、篩選條件、字段名 begin Result:=true; //生成“篩選條件"語(yǔ)句 with tjQuery,SQL do begin Close; Clear; DatabaseName:=sTable.DatabaseName; //設(shè)置Query1的別名 Add(‘Select * from '+sTable.TableName); end; with tjTable do //查詢(篩選)條件表 begin if not Active then Open; if IsEmpty then begin Application.MessageBox(‘未選擇篩選條件!', ‘確定',MB_OK+MB_ICONEXCLAMATION); Exit; end; tjQuery.SQL.Add(‘Where ');//含有篩選條件 sFilter:=‘'; //臨時(shí)記錄篩選條件 First; for i:=0 to RecordCount-1 do begin sLj:=Fields[3].AsString; //邏輯關(guān)系A(chǔ)ND,OR //(字段名0>1實(shí)際值2) sFilter:=sFilter+‘('; sFilter:=sFilter+Fields[0].AsString+ Fields[1].AsString; sFieldName:=Fields[0].AsString; //取第1列的字段名 case Table1.FieldByName(sFieldName).DataType of ftString: begin //字符型處理 sFilter:=sFilter+“”+Fields[2].AsString+“” //第2列為關(guān)系 end; ftFloat, //浮點(diǎn)型處理 ftAutoInc, //自增型 ftSmallInt, //短整型 ftInteger, //整型 ftCurrency: begin //貨幣型 sFilter:=sFilter+Fields[2].AsString; end; ftDate: begin //日期型處理 try lsDate:=StrToDate(Fields[2].AsString); sFilter:=sFilter+“”+FormatDateTime (‘mm/dd/yyyy',StrToDate(Fields[2].AsString))+“”; except Application.MessageBox(‘錯(cuò)誤的日期格式!’, ‘確認(rèn)',MB_OK+MB_ICONSTOP); Result:=false; //返回錯(cuò)誤標(biāo)志 break; end;//try 日期格式判斷 end; //此處可增加對(duì)其他類型數(shù)據(jù)的處理 end;//case sFilter:=sFilter+‘)'; if sLj<>‘' then begin if RecNo<>RecordCount //且“非最后行"的記錄 then sFilter:=sFilter+Fields[3].AsString; //And|Or; end else break; Next end; end; //not IsEmpty(篩選)非空 tjQuery.SQL.Add(sFilter); //保存查詢條件 end; //處理篩選條件
----另外,需要進(jìn)行如下說(shuō)明:
... Type ... procedure MySetDBGrid(sTable:TTable; tjDBGrid:TDBGrid); function MyCreate_SQL(sTable,tjTable: TTable;tjQuery:TQuery):boolean; private { Private declarations } ...
----值得說(shuō)明的是,⑴為簡(jiǎn)化程序,邏輯關(guān)系只提供了AND 和OR兩種,但為了允許用戶修改SQL語(yǔ)句,如:在多條件之間增加括號(hào)來(lái)改變運(yùn)算順序等,增加了Memo控件;⑵在實(shí)際系統(tǒng)中,為方便用戶的操作,可增加幾個(gè)Button(按鈕),功能分別是對(duì)Table2的“增加”、“刪除”,這樣用戶界面會(huì)更友好些。
----利用這種方法來(lái)設(shè)置查詢,條件個(gè)數(shù)是無(wú)限制的,且在屏幕上不會(huì)占據(jù)太大的空間,程序員實(shí)現(xiàn)起來(lái)要簡(jiǎn)單得多了。
|