C++ Builder下数据库报表Master/Detail干系成果的实现
副标题#e#
主从复合布局(Master/Detail)是基于"一对多"的干系,在一个数据库表中提供具体的信息,而这个表是通过另一个数据库表的外来要害字会见相关记录的。基于主从复合布局,我们可以在欣赏一个表中的数据时,同时给出另一个表中与这个记录相关的所有记录信息。Borland C++Builder提供了TTable 和TQuery范例的数据库控件,可以利便地实现数据库表的Master/Detail干系,本文即以BCB中自带的示例数据库BCDEMOS为例来说明如何回收差异要领实现数据表的主从复合布局干系,以数据欣赏成果为例:即在欣赏主数据表Customer.db(客户信息)记录的同时,显示从数据表Orders.db(客户定单信息)中与其相关的所有记录的具体信息。
TTable控件相关的根基属性简介如下:DatabaseName:配置要打开的数据库别名或数据库目次路径;TableName:配置所要关联打开的数据库表文件名;Active:配置为true时数据库表文件自动打开,不然需要用代码在措施中打开数据表。TQuery控件的根基属性:DatabaseName:配置要打开的数据库别名或数据库目次路径;SQL:Tstring范例,所要执行的SQL数据查询语句,可以直接在工具调查器(Object Inspector)中双击打开SQL属性举办编辑,Active:配置为true时自动打开查询数据库表文件,不然需要用代码在措施中打开查询数据表。两者与M/D相关的属性将在下边团结示例加以表明。
一、TTable控件关联主、从表实现Master/Detail干系报表
Master/Detail干系最简朴的实现要领是用两个TTable控件别离与主表及从表关联。别离起名为TableMaster和TableDetail,配置TableMaster的DatabaseName为BCDEMOS,TableName为Customer.db;配置TableMaster的DatabaseName为BCDEMOS,TableName为Orders.db。如此即可别离关联上主从数据表。
#p#副标题#e#
因为要欣赏显示数据表记录内容,所以需要在窗体上安排两个TDBGrid范例的控件DBGridMaster、DBGridDetail以显示M/D干系主从表的相应记录内容;安排两个TDataSource范例的控件DataSourceMaster、DataSourceDetail以指明数据源。配置DataSourceMaster的DataSet属性为TableMaster,DataSourceDetail的DataSet属性为TableDetail,别离指向主从数据表。配置DBGridMaster的DataSource属性为DataSourceMaster,DBGridDetail的DataSource属性为DataSourceDetail。
实现Master/Detail干系的要害在于从表关联控件TableDetail的MasterSource属性和MasterFields属性:前者指向了一个TDataSource控件,该控件DataSet属性应该指向Master/Detail干系的Master表;后者则指定主表和从表的关联字段,需要双击打开"Field Link Designer"对话框举办配置事情,选择从表和主表的相应关联字段添加到"Joined Fields"(关联字段)中即可。本例中以主表(Customer.db客户信息)及从表(Orders.db定单信息)的CustNo(客户号)字段为关联字段,故配置TableDetail的MasterSource属性为DataSourceMaster,指向主表;MasterFields属性为CustNo关联字段。
假如TableMaster和TableDetail的Active属性为false,则需双击窗体Form1空缺处,添加以下两句黑体字代码到TForm1::FormCreate()事件句柄中去:
TableMaster->Active = true;TableDetail->Active = true;
运行措施,即可在DBGridMaster、DBGridDetail中欣赏到Master/Detail干系主从表的相关数据记录。
二、TQuery控件实现Master/Detail干系报表
TQuery控件和TTable控件之间的主要不同在于TQuery控件通过SQL属性所赋的SQL指令语句来动态会见数据库,TTable控件则是静态和数据表相关联。TQuery控件可以同时对多个数据库表举办关联会见,TTable控件则只能关联查询单一的数据库表。和TTable控件对比,TQuery控件因为SQL语言的机动性和相对巨大性,更适合应用在多层、大型、网络数据库系统中。
2.1、
TTable控件关联主表、TQuery控件关联从表实现Master/Detail干系报表
窗体Form1上删去TableDetail控件,安排TQuery范例控件QueryDetail,修改DataSourceDetail的DataSet属性为QueryDetail,其余控件属性稳定。TQuery控件可以对会见范畴设定限制条件,依此即可实现M/D干系的成果。设定QueryDetail的DatabaseName为BCDEMOS,SQL属性为:"Select OrderNo,CustNo,SaleDate,EmpNo From Orders Where Orders.CustNo=:CustNo"。
即可取出从表中所有CustNo字段与主表CustNo字段沟通的记录集而且只显示四个限定的字段信息实现Master/Detail干系,另一要害在于从表关联控件QueryDetail的DataSource属性和Params属性:前者指向了一个TDataSource控件,该控件DataSet属性应该指明SQL指令参数的数据来历;后者则设定SQL指令中的参数,需要双击打开"QueryDetail Parameters"对话框举办配置事情,选择相应的SQL指令中参数配置正确即可。本例中以主表(Customer.db客户信息)的CustNo(客户号)字段作为SQL指令的参数,故配置QueryDetail的DataSource属性为DataSourceMaster,指向主表;Params属性为CustNo关联字段作参数。
注:SQL指令中参数名前必然要加冒号作为前缀,以加以区分。 添加以下两句黑体字代码到TForm1::FormCreate()事件句柄中去:
TableMaster->Active = true;QueryDetail->Active = true;
运行措施,即可在DBGridMaster、DBGridDetail中欣赏到Master/Detail干系主从表的相关数据记录,留意从表的栅格数据记录只显示有限定的四个字段信息。
若QueryDetail的SQL属性为:"Select*From Orders Where Orders.CustNo = :CustNo",不限定从从表取出的字段名。
2.2、TQuery控件关联主、从表实现Master/Detail干系报表
#p#分页标题#e#
Master/Detail干系更机动的实现要领是主表及从表都与TQuery控件关联,别离起名为QueryMaster和QueryDetail。配置QueryMaster和QueryDetail的DatabaseName都为BCDEMOS;QueryMaster的SQL属性为:"Select*From Customer ",DataSource和Params属性均为空,如此即可关联上主数据表,获得和用TableMaster控件一样的结果;QueryDetail的其余属性和2.1中沟通。相应的,别离改DataSourceMaster和DataSourceDetail的DataSet属性指向QueryMaster和QueryDetail。
注:由于TQuery控件是以动态方法会见数据表的,故在只用TQuery控件关联主从表时,设计时从表关联控件QueryDetail的Active属性必需配置为false,不然运行时BDE会陈诉堕落信息。
添加以下两句黑体字代码到TForm1::FormCreate()事件句柄中去:
QueryMaster->Active = true;QueryDetail->Active = true;
运行措施,即可在DBGridMaster、DBGridDetail中欣赏到与2.1沟通结果的Master/Detail干系主从表相关记录信息。
三、单心环境下TQuery控件实现Master/Detail干系汇总、分类报表
在流水功课系统或及时监控系统中,经常要求及时存储当前记录信息到单一的数据表文件中去,而过后再对其举办干系汇总、分类、入库等事情。TTable控件因为只能对单表举办操纵,所以在这种单心环境下实现Master/Detail干系汇总、分类等成果的要求只能用TQuery控件实现。仍以Orders.db(定单信息表)举例说明如何机动操作TQuery控件的SQL指令属性。
在窗体Form1上安排TQuery 控件QueryMaster和QueryDetail,其它的控件属性稳定。配置QueryMaster和QueryDetail的DatabaseName都为BCDEMOS;QueryMaster的SQL属性为:
"SELECT DISTINCT CustNo, SUM( ItemsTotal )ItemsTotalAll,SUM( Freight ) FreightAll, SUM( AmountPaid ) AmoutPaidAll FROM Orders GROUP BY CustNo ORDER BY
CustNo",DataSource和Params属性均为空,发生M/D干系中的主表;QueryDetail的的SQL属性设为:"Select OrderNo,CustNo,PaymentMethod,ItemsTotal,TaxRate,Freight,AmountPaid From Orders Where Orders.CustNo = :CustNo",DataSource属性为DataSourceMaster,指向主表;Params属性以CustNo关联字段作参数。相应的,DataSourceMaster和DataSourceDetail的DataSet属性别离指向QueryMaster和QueryDetail。
示例措施的SQL指令实现了以下成果:以表中每个客户的客户号、定货总值、货运总费、付款总数为记录的字段,从定单信息表中提取出相应信息汇总作为主表;以表中每个定单记录的定单号、客户号、付款方法、提货代价、税率、运费、付款数为记录的字段,从定单信息表中提取相应的信息作为从表;主从表的关联字段CustNo(客户号)通过SQL指令的参数来通报。最终的功效即实现了在DBGridMaster控件上显示出每个客户总的定货信息,在DBGridDetail控件上显示出相应客户的限定字段的具体定货信息记录的成果。
添加以下两句黑体字代码到TForm1::FormCreate()事件句柄中去:
QueryMaster->Active
= true;QueryDetail->Active =
true;
运行措施,即可在DBGridMaster、DBGridDetail中欣赏到Master/Detail干系主从表相关记录信息。
综上所述,对付一般的Master/Detail干系应用,用TTable控件就足以应付了,而要实现更进一步的成果,如多层M/D干系、长途网络数据库操纵、多表互关联范例、单表M/D干系的数据库编程,则需要用到TQuery控件,操作SQL指令的机动性对数据库举办操纵。巨大成果的Master/Detail干系数据库编程可在本文的基本上参考相应的书籍以及BCB的联机辅佐实现。
本文措施在C++Builder 3.0/ PWin95,C++Builder 4.0/ PWin98下调试通过。