線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1990
推到 Plurk!
推到 Facebook!

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

 
axsoft
版主


發表:681
回覆:1056
積分:969
註冊:2002-03-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2002-07-24 16:52:04 IP:61.218.xxx.xxx 未訂閱

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

作者 :大陸西安 SkyRabbit 資料來源: http://bcbdev.myetang.com/bcjq/bcjq074.htm 主從復合結構(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下調試通過。 (西安SkyRabbit) 時間就是金錢---[ 發問前請先找找舊文章]
系統時間:2024-03-29 15:50:19
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!