✅ 操作成功!

BCB讲座第十五讲简单数据库查询操作

发布时间:2023-12-15 作者:admin 来源:讲座

2023年12月15日发(作者:)

BCB讲座第十五讲简单数据库查询操作

简单数据库查询操作

上一讲我们学习了数据库编程的基础知识,并对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控件)之间,是联系两类控件的桥梁。DataSource控件最重要的属性是它的数据集属性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->y())

Query1->SQL->Add(" where FileName Like '%"+edtFileName->Text+"%'");

//如果edtSongName不为空,则添加对SongName字段的查询,由于整个条件子句中只有

//一个WHERE关键字,多个条件之间需要用AND关键字连接,所以要进行一些特殊处理

if(!edtSongName->y())

{

if(Query1->SQL->Count>1)//判断是否已经包含查询条件了

Query1->SQL->Add(" and ");//如果是,则用AND连接本查询条件

else

Query1->SQL->Add(" where ");//否则用WHERE引出查询条件

Query1->SQL->Add("SongName Like '%"+edtSongName->Text+"%'");//添加一个查询条件

}

//如果edtSingerName编辑框中不为空,则添加对SingerName字段的查询

if(!edtSingerName->y())

{

if(Query1->SQL->Count>1)//判断是否已经包含查询条件了

Query1->SQL->Add(" and ");//如果是,则用AND连接本查询条件

else

Query1->SQL->Add(" where ");//否则用WHERE引出查询条件

Query1->SQL->Add("SingerName Like '%"+edtSingerName->Text+"%'");//添加一个查询条件

}

Query1->SQL->Add(" Order By FileName ASC");//添加排序子句

ColumnToSort=0;//记下当前排序的基准列为“FileName”

m_IsAsc=1;//记下当前排序的方式为升序方式

Query1->Open();

}

 实现排序

前面我们已经用到了SQL语言的排序子句,排序子句是由关键词Order By引出的,其后跟一个或多个字段,表示以某个字段为基准进行排序,如果有多个字段,则先按第一个字段进行排序,如果出现第一个字段的内容相同,再按第二个字段排序,依此类推。另外还可以用ASC(升序方式)和DESC(降序方式)规定其排序的方式。

我们在TMainForm中添加了一个成员变量m_IsAsc,用于保存当前排序的方式,注意应在窗体的初始化函数FormCreate中将m_IsAsc初始化为1。下面是菜单命令mnuSortByFileName的命令处理函数:

void __fastcall TMainForm::mnuSortByFileNameClick(TObject *Sender)

{

if(ColumnToSort!=0)//如果以前不是按FileName字段排序,则改为按FileName字段排序

{

Query1->Close();

Query1->SQL->Delete(Query1->SQL->Count-1);//清除原来的排序子句

Query1->SQL->Add("Order By FileName ASC");//添加新的排序子句

ColumnToSort=0;//记下当前排序的基准列为“FileName”

m_IsAsc=1; //记下当前排序的方式为升序方式

Query1->Open();

}

else //否则切换排序的方式

{

Query1->Close();

Query1->SQL->Delete(Query1->SQL->Count-1);

if(m_IsAsc)

Query1->SQL->Add("Order By FileName DESC");//如果原来是升序,改为降序

else

Query1->SQL->Add("Order By FileName Asc");//如果原来是降序,改为升序

m_IsAsc=1-m_IsAsc;//改变m_IsAsc的值,反映排序方式的改变

Query1->Open();//打开Query1

}

}

另外两个排序菜单命令的处理函数mnuSortBySongNameClick和mnuSortBySingerNameClick的实现方法与mnuSortByFileNameClick很类似,就交给读者朋友自己完成吧。

最后,还要响应DBGrid1的OnTitleClick事件,允许用户通过单击DBGrid1的列标题来改变排序的方式。下面是DBGrid1TitleClick函数的新代码:

void __fastcall TMainForm::DBGrid1TitleClick(TColumn *Column)

{

switch(Column->Index)//用户点击的列号

{

case 0://如果是第一列,则按FileName进行排序

mnuSortByFileNameClick(NULL);

break;

case 1: //如果是第二列,则按SongName进行排序

mnuSortBySongNameClick(NULL);

break;

case 2: //如果是第三列,则按SingerName进行排序

mnuSortBySingerNameClick(NULL);

break;

}

}

本讲我们学习了利用Query控件和SQL语句实现简单数据库查询的方法,SQL实际上是数据库编程的核心内容之一,因此心铃建议想进一步学习数据库开发的读者朋友一定要掌握好SQL的语法和用法。在下一讲中,我们将学习简单的数据库编辑操作,即添加、修改和删除记录的方法。

BCB讲座第十五讲简单数据库查询操作

👁️ 阅读量:0