简单数据库查询操作
上一讲我们学习了数据库编程的基础知识,并对MP3Collect进行了一番改造,使其具有数据库访问能力。在本讲中,我们首先设置三个数据库元件Query1、DataSource1和DBGrid1的属性,接下来学习如何通过Query控件实现简单的数据库查询操作。
● 设置控件属性
Query1控件的用途是查询数据库,获取可以显示在窗体中的数据。Query控件和Table控件一样,它们都是从VCL类TDataSet(数据集元件)中继承来的,都代表数据库中一组记录的集合。不同的是,Table控件代表库中实际存在的一个数据表对象,而Query控件则代表一次查询的结果。Query控件支持通过SQL进行查询,因此比Table控件具有更大的灵活性,它可以同时访问多个数据表,可以灵活访问数据表中的行和列,可以实现十分复杂的条件查询。
SQL的全称是结构化查询语言,它是一种标准的数据库查询语言,具有自己的关键字(SQL中的关键字是不分大小写的,SELECT和Select的作用是相同的)和语法,典型的SQL查询语句如下所示:
SELECT [字段名] FROM [数据表名] WHERE [条件子句]
其中SELECT、FROM和WHERE都是SQL的关键字。SELECT代表查询操作,“字段名”表示返回的记录集中所包含的字段,字段名可以使用通配符*,表示查询的数据表中的所有字段,“数据表名”表示在哪个数据表中进行查询,“条件子句”为查询的条件。
了解了SQL的基本语法后,下面我们来设置Query1控件的SQL属性。在对象监视器中双击Query1控件的SQL属性(该属性为TStrings*类型),打开字符串列表编辑器,在其中输入这样两句“Select * From MP3Info”和“Order by FileName ASC”。注意第二句要另起一行,这样在后面的编程中可以很方便地改变记录的排序方式。这两句合在一起的意思是获取MP3Info数据表中的所有记录,并以FileName字段为基准按升序方式排序。除了指定Query1控件的SQL属性外,还要指定它在哪个数据库中进行查询,将其Database属性设为别名MP3Collect。然后指定其Active属性为true,其它属性值都接受缺省值。
DataSource控件从字面上可翻译为数据源控件,不过它与上一讲介绍的ODBC数据源可不是一回事。DataSource控件是一个中间控件,它位于数据集控件(如Table控件或Query控件)和数据控制控件(如DBGrid控件或DBEdit控件)之间,是联系两类控件的桥梁。Data
Source控件最重要的属性是它的数据集属性DataSet,在对象浏览器中点击该属性右侧的下拉式列表框,可以看到其中列出了Table1和Query1,我们选中Query1,表示DataSource控件从Query1中获取数据。
DBGrid控件是一种常用的数据控制元件,它以表格的方式显示记录,表格中的行表示记录,而列表示记录的字段。所有的数据控制元件都必须和某个DataSource控件相关联,才能获取所需要的数据,因此我们在这里将DBGrid1控件的DataSource属性设为DataSource1。指定DBGrid1的数据来源后,我们可以看到DBGrid1的表格中立即显示出相应的记录了。
缺省情况下,DBGrid1会显示数据集的全部字段,并以字段的名称显示在列标题中,我们可以在设计时通过DBGrid控件的列编辑器修改列的数目、标题以及布局等。在对象浏览器中双击Columns属性,打开列编辑器,此时列编辑器中的内容还是空的,因此我们在列编辑器中点击鼠标右键,选择关联菜单中的“Add All Field”命令,先把数据集中的所有字段添加进来。由于我们不希望将记录的编号显示出来,所以要删除其中的“ID”字段。
接下来我们来设置各列的列标题。首先选中“FileName”列,这时可以在对象浏览器中看到
该列的各种属性,其中FieldName属性为“FileName”,表示该列显示“FileName”字段的内容,列对象的Title属性为复合属性,展开Title属性,将其中的Caption子属性改为“文件名称”,然后设置“FileName”列的列宽度,其缺省的Width属性为-1,表示根据字段的宽度自动设置列宽度,我们可以根据窗体的布局为其重新设置一个实际的值。按照同样的方法,我们继续把“SongName”、“SingerName”的列标题改为“歌曲名称”和“歌手名称”。
设置好DBGrid1控件的列对象的属性后,接下来还要设置它的Options属性,该属性决定了显示记录的方式。展开DBGrid1控件的Options属性,可以看见其中有十多项选项,将其中的dgEditing、dgAlwaysShowEdit和dgMultiSelect三个选项设为false,其余的选项都设为true,如此设置可以屏蔽在DBGrid中直接修改记录以及同时选中多条记录的功能。另外还可以设置DBGrid1的ReadOnly属性为true,使用户不能在网格中进行添加、修改、删除记录的操作。最后,设置DBGrid1的PopupMenu属性为PopupMenu1,为其指定关键菜单。
现在所有元件的属性都设置好了,下面我们来看看访问数据库的具体方法。为了简洁起见,下面的代码中都没有异常处理措施,读者朋友可以根据第13讲的内容自己添加相应的异常处理代码。
● 实现查询功能
Table控件和Query控件都可以实现查询,但Table不支持SQL,只能通过数据表中的索引实现比较简单的检索功能(在后面还会用到Table的查询功能),因此心铃决定用Query1控件进行查询,提供显示在DBGrid1中的数据。
所有的查询都是通过设置Query1控件的SQL属性来完成的。实现显示所有记录的SQL语句最简单,即前面给出的SQL属性。下面是btnShowAllClick事件处理函数的新代码,其中给出了在运行时改变Query控件SQL属性的方法。
void __fastcall TMainForm::btnShowAllClick(TObject *Sender)
{
Query1->Close();//先关闭上一次查询
Query1->SQL->Clear();//清除原来的SQL语句
Query1->SQL->Add("Select * from MP3Info");//添加一个字符串,SQL属性由多个字符串
组合而成
Query1->SQL->Add("Order By FileName ASC");
ColumnToSort=0;//记下当前排序的基准列为“FileName”
m_IsAsc=1;//记下当前排序的方式为升序方式
Query1->Open(); //设置好SQL属性后,打开Query1,获取数据并自动更新DBGrid1
}
在改变Query1的SQL属性之前,首先应将上一次查询关闭。SQL属性是一个TStrings对象指针,它将多个字符串组成一个完整的SQL查询语句,其中的Order By是SQL中的关键字,表示按照某一个字段进行排序,ASC是排序方式关键字,表示升序方式。ColumnToSort和m_IsAsc是MainForm类的成员变量,用于保存排序的基准列号和排序方式,有关排序的内容还要在下一节仔细介绍。设置好SQL属性后,调用Query控件的Open()方法,该方法会通过BDE引擎向数据库进行一次查询操作,获取所需的数据,并自动更新DBGrid1中显示的数据。
条件查询操作需要使用SQL语句中的WHERE条件子句。查询的原理是依次读取三个条件输入框的内容,如果某一条件输入框不为空,则添加一个查询条件。这里使用的查询条件的语法如下所示:
[字段名] Like '带通配符的字符串'
其中[字段名]为要检查的字段,LIKE为SQL的关键字,表示将字段内容与“带通配符的字符串”进行比较,看是否符合给定的模式。“带通配符的字符串”需要用单引号包括起来,常用的通配符有“%”、“?”等。其中“%”表示任意字符串。例如,下面的SQL语句表示从MP3Info中取出所有FileName字段中包括“MP3”字样的记录:
SELECT * FROM MP3Info WHERE FileName Like %MP3%
另外,在MP3Collect中,各个查询条件之间是逻辑与的关系,因此多个查询条件之间要用关键字AND进行连接,表示只有符合所有查询条件的记录才是所需要的记录。下面是btnFindClick事件处理函数的新代码:
void __fastcall TMainForm::btnFindClick(TObject *Sender)
{
Query1->Close();//首先关闭Query1
Query1->SQL->Clear();//清除原有的SQL语句
Query1->SQL->Add("Select * from MP3Info");//表示从数据表中MP3Info中查询
//如果edtFileName不为空,则添加对FileName字段的查询,注意不要漏了其中的单引号
if(!edtFileName->Text.IsEmpty())
Query1->SQL->Add(" where FileName Like '%"+edtFileName->Text+"%'");
//如果edtSongName不为空,则添加对SongName字段的查询,由于整个条件子句中只有
//一个WHERE关键字,多个条件之间需要用AND关键字连接,所以要进行一些特殊处理
if(!edtSongName->Text.IsEmpty())
{
if(Query1->SQL->Count>1)//判断是否已经包含查询条件了
Query1->SQL->Add(" and ");//如果是,则用AND连接本查询条件sql语句查询不包含
else
Query1->SQL->Add(" where ");//否则用WHERE引出查询条件
Query1->SQL->Add("SongName Like '%"+edtSongName->Text+"%'");//添加一个查询条件
}
//如果edtSingerName编辑框中不为空,则添加对SingerName字段的查询
if(!edtSingerName->Text.IsEmpty())
{
if(Query1->SQL->Count>1)//判断是否已经包含查询条件了
Query1->SQL->Add(" and ");//如果是,则用AND连接本查询条件
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论