微信公众号 
图码生活

每天发布有五花八门的文章,各种有趣的知识等,期待您的订阅与参与
电脑报 1992-2001 十年文章全集
电脑报 1992-2001 十年文章全集
包含从 1992 年 - 2001 年间,两万余篇期刊文章,查询最少输入两个字符
随便看看
读取中
读取中
标题在Delphi中简单实现多重查询
栏目软件世界
作者陈建兵
发布2000年第39期
  在数据库应用系统中,查询是一项必不可少的功能。查询功能是直接体现系统功能的一项重要指标。查询的方式主要有以下几种:1.固定字段的单一查询;2.可选择字段的单一查询;3.限制若干个字段的多重查询;4.可任意选择字段的多重查询。前两种也称为单条件查询,后两种称为多重(或多条件)查询。在实际中,系统提供给用户的查询方式以单条件查询为多,即使提供了多条件方式,通常也只两或三个条件,因为编写多重查询是一项非常棘手且繁琐的事情。实际上,利用表格(Grid)的功能,就能轻松地实现多重查询。本人以Delphi为例,介绍具体的实现方法,但这种思想,也同样适合于其它的编程语言(如 Visual Foxpro)。另外,为使程序方便“移植”,本人把各功能模块化,使其更具有通用性。
  程序主要按如下三个步骤来实现:
  1.设置DBGrid
  2.生成查询条件(语句)
  3.执行查询
  具体步骤如下:
  (1)新建一工程文件,取名为PDBGrid.dpr;
  (2)给单元文件取名为UDBGrid.pas,在其相应的表单(取名为frmDBGrid)中添加如

表1中的控件并编写相应的代码:
  其中,Table2(记录查询条件的数据集)对应的表CxComm. db的结构定义如

表2:
  表单的FormActivate事件代码如下:
  procedure  TfrmDBGrid.FormActivate(Sender: TObject);
  begin
  if Table2.Active then Table2.Close;
  Table2.EmptyTable; //清空条件
  Table1.Open;
  Table2.Open;
  end;
  Buttonl(设置DBGrid)的Click事件代码如下:
  procedure TfrmDBGrid.Button1Click(Sender:TObject);
  begin
   MysetDBGrid(Table1,DBGrid2); //MySetDBGrid为自定义过程
  //以Table为数据源,DBGrid2为记录筛选(查询)条件的表格
  end;
  Button2(生成查询)的Click事件代码如下:
  procedure
  TfrmDBGrid.Button2Click(Sender:TObject);
  begin
  if   MyCreate_SQL(Table1,Table2,Query1) //MyCreate_SQL为自定义函数
  //由指定数据来源表来生成SQL,存入Query1
  then begin
  Memol.Lines.Clear;
  Memol.Lines: = (Queryl.SQL);
  Memol.Modified: = false;
  end
  end;
  Button3(执行查询)的Click事件代码如下:
  procedure
  TfrmDBGrid.Button3Click(Sender: TObject);
  begin
  with Queryl,SQL do
   begin
  Close;
   if Memol.Modified//用户可修改SQL语句
  then SQL: = Memol.Lines;
  try
   ExecSQL;
   Open;
   except//捕捉错误并处理
  begin
  MessageBeep(0);
  Applicalion.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;
  //设置关系(=,<> ,>,>=,<,<=,)及逻辑(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 "" +sTableName+ "");
  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+sFilter[0].AsString+Fields[1].AsString;
  sFildName: = Fields[0].AsString; //取第1列的字段名
   case
  Tablel1.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 sFliter: = 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 ]
   …
  值得说明的是:
  1.为从一定程序上简化程序,逻辑关系只提供了AND和OR两种,但允许用户修改SQL语句,如:在多条件之间增加括号来改变运算顺序等,使得查询功能更加强大,因此增加了Memo 控件;
  2.在实际系统中,为方便用户的操作,可增加几个Button(按钮),功能分别是对Table2的“增加”、“删除”等,这样用户界面会更友好些。
  利用这种方法来设置查询,条件个数是无限制的,且在屏幕上不会占据太大的空间,程序员实现起来要简单得多了。以上程序在中文Win98/中文 Delphi5.0运行通过。