程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++ Builder下數據庫報表Master/Detail關系功能的實現

C++ Builder下數據庫報表Master/Detail關系功能的實現

編輯:關於C++

主從復合結構(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下調試通過。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved