Delphi中进行复杂查询的通用方法
本文介绍了一种在Delphi中进行数据库复杂查询的通用方法。
一、 前言
任何用到数据库的
软件都离不开查询,通过查询可以查看数据库中的所有满足条件的记录。对于复杂查询如果方法不当会使
问题更加复杂化。作者通过用
Delphi设计几个数据库系统查询,提炼出设计过程中一套通用而简单的方法,运用这套方法可以根据不同的需要快速完成复杂查询,节省大量开发时间。
二、 实现方法
一个数据库中有多个数据表,可单独查询,也可几个表进行关联查询。在Delphi中设计查询
程序离不开TQuery组件,TQuery组件最重要的属性是SQL,通过指定SQL来进行查询。
2.1
设计查询窗体
在一个窗体中完成所有查询,用一个DBGrid显示所有查询结果。
在ToolBar或SpeedBar放两个按钮,命名为“查询”和“查看所有记录”,其中“查询”完成查看指定条件的记录, “查看所有记录” 完成查看所有记录。用PageControl的两个TabSheet分别放置“查询内容及条件”和“查询结果”。第一个TabSheet内放置
查询数据表的名称和查询条件。数据表名称可以用RadioGroup,查询条件可以根据实际情况用一系列的GroupBox包含的Label、Combo、DateTimePicker(用于日期型字段的查询)、TextBox等等来设计;第二个TabSheet放置一个DBGrid显示所有查询结果,如果需要打印还可以在ToolBar或SpeedBar里放两个按钮,命名为“打印预览”、“ 打印”,再用一个StatusBar来显示一些附加信息,如记录的数量等,这里不再叙述。
添加一个DataModule,在里面加入一个Database、若干个Query和一个DataSource。查询窗体中DBGrid的DataSource属性是DataModule的DataSource,通过在代码中指定DataSource的DataSet属性让DBGrid显示不同的查询结果。设置Database的相关属性连接实际的数据库,根据要查询的内容设计Query的SQL属性,格式是“SELECT TableName.FieldName AS AliasName,…FROM TableName…”,注意不要带WHERE和ORDER子句。指定的AliasName可以是中文,以便在DBGrid中的标题上显示中文字段名。
2.2指定查询条件值的范围
在指定查询条件时,为了操作方便,通常列出所有可能的查询条件值的范围。用ComboBox而不是LookupComboBox来指定,因为后者会显示重复的记录。在查询窗体的OnCreate事件中加入这些代码。可以在DataModule增加procedure InitComboBox来实现这一功能。请参考以下代码:
procedure TDM.InitComboBox(FieldName, TableName: String; Cb: TComboBox);
var
Qry:TQuery;
begin
Qry:=TQuery.Create(self); //动态创建Query
Qry.DatabaseName:=Database1.DatabaseName;
//清除重复记录
Qry.SQL.Add('SELECT DISTI
NCT '+FieldName+' FROM '+TableName);
Qry.Open;
Cb.Items.Clear;
Cb.Items.Add('<所有>'); //第一项表示“所有”,若选择此项,不以此字段作为条件
while not Qry.Eof do
begin
Cb.Items.Add(Qry.Fields[0].AsString);
Qry.Next;
end;
Cb.ItemIndex:=0;Qry.Free;
end;
2.3得到查询条件
查询条件格式为:FieldName Opr Value。可以准备若干重载函数。
例如对于文本型字段,Val是上节中的ComboBox的Text。
procedure GetSql(SQL:TStrings;FieldName:String;Val:String);
begin
if Val <>'<所有>' then
SQL.Add(Format('%s = ''%s''',[FieldName,Val]));
end;
对于日期型字段,
procedure GetSql(SQL:TStrings;FieldName:String;dFrom,dTo:TDateTime);
begin
SQL.Add(Format('%s BETWEEN #%s# AND #%s#',[FieldName,
FormatDateTime('YYYY-MM-DD',dFrom),FormatDateTime('YYYY-MM-DD',dTo)]));
end;
对于数字型字段可能还有“<”、“>”、“=”等操作,可仿照以上函数。
2.4删除已有条