---- 在數據庫管理系統中,查詢的方式主要有以下幾種:1.固定字段的單一查詢。2.可選擇字段的單一查詢。3.限制若干個字段的多重查詢。4.可任意選擇字段的多重查詢。前兩種也稱為單條件查詢,后兩種稱為多重(或多條件)查詢。在實際中,系統(實為程序員)提供給用戶的查詢方式以單條件查詢為多,即使提供了多條件方式,通常也只有兩或三個條件,因為編寫多重查詢是一項非常棘手且煩瑣的事情。實際上,利用表格Grid功能,就能輕松地實現多重查詢。本人以Delphi為例,介紹具體的實現方法。這種思想,也同樣適合于其他的編程語言(如Visual Foxpro)。
----程序主要按如下三個功能來實現:
設置DBGrid; 生成查詢條件(語句); 執行查詢。 ----具體步驟如下:
----⑴新建一工程文件,取名為PDBGrid.dpr;
----⑵給單元文件取名為UDBGrid.pas,在其相應的表單(取名為frmDBGrid)中添加如下控件并編寫相應的代碼:
----其中Table2(記錄查詢條件的數據集)對應的表 CxComm.db的結構定義如下:
----表單的FormActivate事件代碼如下:
procedure TfrmDBGrid.FormActivate(Sender: TObject); begin if Table2.Active then Table2.Close; Table2.EmptyTable; //清空條件 Table1.Open; Table2.Open; end;
Button1(設置DBGrid)的Click事件代碼如下: procedure TfrmDBGrid.Button1Click(SenderTObject); begin MySetDBGrid(Table1,DBGrid2); // MySetDBGrid為自定義過程 //以Table1為數據源,DBGrid2為記錄篩選(查詢)條件的表格 end;
Button2(生成查詢)的Click事件代碼如下: procedureTfrmDBGrid.Button2Click(Sender:TObject); begin if MyCreate_SQL(Table1,Table2,Query1) //MyCreate_SQL為自定義函數 //由指定數據來源表生成SQL,存入Query1 then begin Memo1.Lines.Clear; Memo1.Lines:=(Query1.SQL); Memo1.Modified:=false; end end;
Button3(執行查詢)的Click事件代碼如下: procedureTfrmDBGrid.Button3Click(Sender:TObject); begin with Query1,SQL do begin Close; if Memo1.Modified //用戶可修改SQL語句 then SQL:=Memo1.Lines; try ExecSQL; Open; except //捕捉錯誤并處理 begin MessageBeep(0); Application.MessageBox(‘錯誤的SQL語句!', ‘確認',MB_OK+MB_ICONSTOP); Close; end; end //try end; end; //執行SQL
----自定義過程MySetDBGrid (設置DBGrid)的代碼如下:
procedure TfrmDBGrid.MySetDBGrid (sTable:TTable;tjDBGrid:TDBGrid); //參數說明:sTable為數據(包括字段、記錄)來源表 // tjDBGrid為記錄篩選(查詢)條件的表格 var i:byte; begin //設置查詢項目 if not sTable.Active then sTable.Open; tjDBGrid.Columns[0].PickList.Clear; for i:=0 to sTable.FieldCount-1 do //記錄數(即字段數) begin tjDBGrid.Columns[0].PickList.Add (sTable.Fields[i].FieldName); end; //for //設置關系(=,<>,>,>=,<,<=) 及邏輯(AND,OR) tjDBGrid.Columns[1].PickList.Text:=‘='+#13+ ‘<>'+#13+‘>'+#13+‘>='+#13+‘<'+#13+ ‘<=';tjDBGrid.Columns[3].PickList.Text:=‘AND'+#13+ ‘OR'; end;//設置DBGrid
----自定義函數MyCreate_SQL (生成查詢)的代碼如下:
function TfrmDBGrid.MyCreate_SQL (sTable,tjTable:TTable;tjQuery:TQuery):boolean; //參數說明:sTable為數據(包括字段、記錄)來源表 // tjTable為記錄篩選(查詢)條件的表 // tjQuery記錄SQL語句 var i:byte; lsDate:TDate; //檢測日期格式用 sLj,sFilter,sFieldName:string; //分別表示:邏輯關系、篩選條件、字段名 begin Result:=true; //生成“篩選條件"語句 with tjQuery,SQL do begin Close; Clear; DatabaseName:=sTable.DatabaseName; //設置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:=‘'; //臨時記錄篩選條件 First; for i:=0 to RecordCount-1 do begin sLj:=Fields[3].AsString; //邏輯關系AND,OR //(字段名0>1實際值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列為關系 end; ftFloat, //浮點型處理 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(‘錯誤的日期格式!’, ‘確認',MB_OK+MB_ICONSTOP); Result:=false; //返回錯誤標志 break; end;//try 日期格式判斷 end; //此處可增加對其他類型數據的處理 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; //處理篩選條件
----另外,需要進行如下說明:
... Type ... procedure MySetDBGrid(sTable:TTable; tjDBGrid:TDBGrid); function MyCreate_SQL(sTable,tjTable: TTable;tjQuery:TQuery):boolean; private { Private declarations } ...
----值得說明的是,⑴為簡化程序,邏輯關系只提供了AND 和OR兩種,但為了允許用戶修改SQL語句,如:在多條件之間增加括號來改變運算順序等,增加了Memo控件;⑵在實際系統中,為方便用戶的操作,可增加幾個Button(按鈕),功能分別是對Table2的“增加”、“刪除”,這樣用戶界面會更友好些。
----利用這種方法來設置查詢,條件個數是無限制的,且在屏幕上不會占據太大的空間,程序員實現起來要簡單得多了。
|