---- 在数据库管理系统中,查询的方式主要有以下几种: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 |