-
c语言入门之C++ Builder下数据库报表Master/Detail关系
主从复合结构(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。如此即可分别关联上主从数据表。
因为要浏览显示数据表记录内容,所以需要在窗体上放置两个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关系报表
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下调试通过。
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。如此即可分别关联上主从数据表。
因为要浏览显示数据表记录内容,所以需要在窗体上放置两个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关系报表
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下调试通过。
最新更新
Objective-C语法之代码块(block)的使用
VB.NET eBook
Add-in and Automation Development In VB.NET 2003 (F
Add-in and Automation Development In VB.NET 2003 (8
Add-in and Automation Development in VB.NET 2003 (6
Add-in and Automation Development In VB.NET 2003 (5
AddIn Automation Development In VB.NET 2003 (4)
AddIn And Automation Development In VB.NET 2003 (2)
Addin and Automation Development In VB.NET 2003 (3)
AddIn And Automation Development In VB.NET 2003 (1)
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
武装你的WEBAPI-OData入门
武装你的WEBAPI-OData便捷查询
武装你的WEBAPI-OData分页查询
武装你的WEBAPI-OData资源更新Delta
5. 武装你的WEBAPI-OData使用Endpoint 05-09
武装你的WEBAPI-OData之API版本管理
武装你的WEBAPI-OData常见问题
武装你的WEBAPI-OData聚合查询
OData WebAPI实践-OData与EDM
OData WebAPI实践-Non-EDM模式