C++ Builder下數(shù)據(jù)庫報表Master/Detail關(guān)系技巧的完成
發(fā)表時間:2024-02-16 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]主從復(fù)合結(jié)構(gòu)(Master/Detail)是基于“一對多”的關(guān)系,在一個數(shù)據(jù)庫表中提供詳細(xì)的信息,而這個表是通過另一個數(shù)據(jù)庫表的外來關(guān)鍵字訪問相關(guān)記錄的。基于主從復(fù)合結(jié)構(gòu),我們可以在瀏覽一個表中的數(shù)據(jù)時,同時給出另一個表中與這個記錄相關(guān)的所有記錄信息! orland C++Builder提供了...
主從復(fù)合結(jié)構(gòu)(Master/Detail)是基于“一對多”的關(guān)系,在一個數(shù)據(jù)庫表中提供詳細(xì)的信息,而這個表是通過另一個數(shù)據(jù)庫表的外來關(guān)鍵字訪問相關(guān)記錄的;谥鲝膹(fù)合結(jié)構(gòu),我們可以在瀏覽一個表中的數(shù)據(jù)時,同時給出另一個表中與這個記錄相關(guān)的所有記錄信息。
Borland C++Builder提供了TTable 和TQuery類型的數(shù)據(jù)庫控件,可以方便地實現(xiàn)數(shù)據(jù)庫表的Master/Detail關(guān)系,本文即以BCB中自帶的示例數(shù)據(jù)庫BCDEMOS為例來說明如何采用不同方法實現(xiàn)數(shù)據(jù)表的主從復(fù)合結(jié)構(gòu)關(guān)系,以數(shù)據(jù)瀏覽功能為例:即在瀏覽主數(shù)據(jù)表Customer.db(客戶信息)記錄的同時,顯示從數(shù)據(jù)表Orders.db(客戶定單信息)中與其相關(guān)的所有記錄的詳細(xì)信息。
TTable控件相關(guān)的基本屬性簡介如下:DatabaseName:設(shè)置要打開的數(shù)據(jù)庫別名或數(shù)據(jù)庫目錄路徑;TableName:設(shè)置所要關(guān)聯(lián)打開的數(shù)據(jù)庫表文件名;Active:設(shè)置為true時數(shù)據(jù)庫表文件自動打開,否則需要用代碼在程序中打開數(shù)據(jù)表。TQuery控件的基本屬性:DatabaseName:設(shè)置要打開的數(shù)據(jù)庫別名或數(shù)據(jù)庫目錄路徑;SQL:Tstring類型,所要執(zhí)行的SQL數(shù)據(jù)查詢語句,可以直接在對象觀察器(Object Inspector)中雙擊打開SQL屬性進(jìn)行編輯,Active:設(shè)置為true時自動打開查詢數(shù)據(jù)庫表文件,否則需要用代碼在程序中打開查詢數(shù)據(jù)表。兩者與M/D相關(guān)的屬性將在下邊結(jié)合示例加以解釋。
一、 TTable控件關(guān)聯(lián)主、從表實現(xiàn)Master/Detail關(guān)系報表
Master/Detail關(guān)系最簡單的實現(xiàn)方法是用兩個TTable控件分別與主表及從表關(guān)聯(lián)。分別起名為TableMaster和TableDetail,設(shè)置TableMaster的DatabaseName為BCDEMOS,TableName為Customer.db;設(shè)置TableMaster的DatabaseName為BCDEMOS,TableName為Orders.db。如此即可分別關(guān)聯(lián)上主從數(shù)據(jù)表。
因為要瀏覽顯示數(shù)據(jù)表記錄內(nèi)容,所以需要在窗體上放置兩個TDBGrid類型的控件DBGridMaster、DBGridDetail以顯示M/D關(guān)系主從表的相應(yīng)記錄內(nèi)容;放置兩個TDataSource類型的控件DataSourceMaster、DataSourceDetail以指明數(shù)據(jù)源。設(shè)置DataSourceMaster的DataSet屬性為TableMaster,DataSourceDetail的DataSet屬性為TableDetail,分別指向主從數(shù)據(jù)表。設(shè)置DBGridMaster的DataSource屬性為DataSourceMaster,DBGridDetail的DataSource屬性為DataSourceDetail。
實現(xiàn)Master/Detail關(guān)系的關(guān)鍵在于從表關(guān)聯(lián)控件TableDetail的MasterSource屬性和MasterFields屬性:前者指向了一個TDataSource控件,該控件DataSet屬性應(yīng)該指向Master/Detail關(guān)系的Master表;后者則指定主表和從表的關(guān)聯(lián)字段,需要雙擊打開“Field Link Designer”對話框進(jìn)行設(shè)置工作,選擇從表和主表的相應(yīng)關(guān)聯(lián)字段添加到“Joined Fields”(關(guān)聯(lián)字段)中即可。本例中以主表(Customer.db客戶信息)及從表(Orders.db定單信息)的CustNo(客戶號)字段為關(guān)聯(lián)字段,故設(shè)置TableDetail的MasterSource屬性為DataSourceMaster,指向主表;MasterFields屬性為CustNo關(guān)聯(lián)字段。
如果TableMaster和TableDetail的Active屬性為false,則需雙擊窗體Form1空白處,添加以下兩句黑體字代碼到TForm1::FormCreate()事件句柄中去:
TableMaster->Active = true; TableDetail->Active = true;
運行程序,即可在DBGridMaster、DBGridDetail中瀏覽到Master/Detail關(guān)系主從表的相關(guān)數(shù)據(jù)記錄。
二、 TQuery控件實現(xiàn)Master/Detail關(guān)系報表
TQuery控件和TTable控件之間的主要差別在于TQuery控件通過SQL屬性所賦的SQL指令語句來動態(tài)訪問數(shù)據(jù)庫,TTable控件則是靜態(tài)和數(shù)據(jù)表相關(guān)聯(lián)。TQuery控件可以同時對多個數(shù)據(jù)庫表進(jìn)行關(guān)聯(lián)訪問,TTable控件則只能關(guān)聯(lián)查詢單一的數(shù)據(jù)庫表。和TTable控件相比,TQuery控件因為SQL語言的靈活性和相對復(fù)雜性,更適合應(yīng)用在多層、大型、網(wǎng)絡(luò)數(shù)據(jù)庫系統(tǒng)中。
2.1、 TTable控件關(guān)聯(lián)主表、TQuery控件關(guān)聯(lián)從表實現(xiàn)Master/Detail關(guān)系報表
窗體Form1上刪去TableDetail控件,放置TQuery類型控件QueryDetail,修改DataSourceDetail的DataSet屬性為QueryDetail,其余控件屬性不變。TQuery控件可以對訪問范圍設(shè)定限制條件,依此即可實現(xiàn)M/D關(guān)系的功能。設(shè)定QueryDetail的DatabaseName為BCDEMOS,SQL屬性為:
“ Select OrderNo,CustNo,SaleDate,EmpNo From Orders Where Orders.CustNo=:CustNo”。
即可取出從表中所有CustNo字段與主表CustNo字段相同的記錄集并且只顯示四個限定的字段信息實現(xiàn)Master/Detail關(guān)系,另一關(guān)鍵在于從表關(guān)聯(lián)控件QueryDetail的DataSource屬性和Params屬性:前者指向了一個TDataSource控件,該控件DataSet屬性應(yīng)該指明SQL指令參數(shù)的數(shù)據(jù)來源;后者則設(shè)定SQL指令中的參數(shù),需要雙擊打開“QueryDetail Parameters”對話框進(jìn)行設(shè)置工作,選擇相應(yīng)的SQL指令中參數(shù)設(shè)置正確即可。本例中以主表(Customer.db客戶信息)的CustNo(客戶號)字段作為SQL指令的參數(shù),故設(shè)置QueryDetail的DataSource屬性為DataSourceMaster,指向主表;Params屬性為CustNo關(guān)聯(lián)字段作參數(shù)。
注:SQL指令中參數(shù)名前一定要加冒號作為前綴,以加以區(qū)分。
添加以下兩句黑體字代碼到TForm1::FormCreate()事件句柄中去:
TableMaster->Active = true;QueryDetail->Active = true;
運行程序,即可在DBGridMaster、DBGridDetail中瀏覽到Master/Detail關(guān)系主從表的相關(guān)數(shù)據(jù)記錄,注意從表的柵格數(shù)據(jù)記錄只顯示有限定的四個字段信息。
若QueryDetail的SQL屬性為:“ Select * From Orders Where Orders.CustNo = :CustNo ”,不限定從從表取出的字段名。
2.2、 TQuery控件關(guān)聯(lián)主、從表實現(xiàn)Master/Detail關(guān)系報表
Master/Detail關(guān)系更靈活的實現(xiàn)方法是主表及從表都與TQuery控件關(guān)聯(lián),分別起名為QueryMaster和QueryDetail。設(shè)置QueryMaster和QueryDetail的DatabaseName都為BCDEMOS;QueryMaster的SQL屬性為:“ Select * From Customer ”,DataSource和Params屬性均為空,如此即可關(guān)聯(lián)上主數(shù)據(jù)表,得到和用TableMaster控件一樣的效果;QueryDetail的其余屬性和2.1中相同。相應(yīng)的,分別改DataSourceMaster和DataSourceDetail的DataSet屬性指向QueryMaster和QueryDetail。
注:由于TQuery控件是以動態(tài)方式訪問數(shù)據(jù)表的,故在只用TQuery控件關(guān)聯(lián)主從表時,設(shè)計時從表關(guān)聯(lián)控件QueryDetail的Active屬性必須設(shè)置為false,否則運行時BDE會報告出錯信息。
添加以下兩句黑體字代碼到TForm1::FormCreate()事件句柄中去:
QueryMaster->Active = true;QueryDetail->Active = true;
運行程序,即可在DBGridMaster、DBGridDetail中瀏覽到與2.1相同效果的Master/Detail關(guān)系主從表相關(guān)記錄信息。
三、單表情況下TQuery控件實現(xiàn)Master/Detail關(guān)系匯總、分類報表
在流水作業(yè)系統(tǒng)或?qū)崟r監(jiān)控系統(tǒng)中,常常要求實時存儲當(dāng)前記錄信息到單一的數(shù)據(jù)表文件中去,而事后再對其進(jìn)行關(guān)系匯總、分類、入庫等工作。TTable控件因為只能對單表進(jìn)行操作,所以在這種單表情況下實現(xiàn)Master/Detail關(guān)系匯總、分類等功能的要求只能用TQuery控件實現(xiàn)。仍以O(shè)rders.db(定單信息表)舉例說明如何靈活利用TQuery控件的SQL指令屬性。
在窗體Form1上放置TQuery 控件QueryMaster和QueryDetail,其它的控件屬性不變。設(shè)置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屬性均為空,產(chǎn)生M/D關(guān)系中的主表;QueryDetail的的SQL屬性設(shè)為:
“ Select OrderNo,CustNo,PaymentMethod,ItemsTotal,TaxRate,Freight,AmountPaid From Orders Where Orders.CustNo = :CustNo ”,DataSource屬性為DataSourceMaster,指向主表;Params屬性以CustNo關(guān)聯(lián)字段作參數(shù)。相應(yīng)的,DataSourceMaster和DataSourceDetail的DataSet屬性分別指向QueryMaster和QueryDetail。
示例程序的SQL指令實現(xiàn)了以下功能:以表中每個客戶的客戶號、定貨總值、貨運總費、付款總數(shù)為記錄的字段,從定單信息表中提取出相應(yīng)信息匯總作為主表;以表中每個定單記錄的定單號、客戶號、付款方式、提貨價值、稅率、運費、付款數(shù)為記錄的字段,從定單信息表中提取相應(yīng)的信息作為從表;主從表的關(guān)聯(lián)字段CustNo(客戶號)通過SQL指令的參數(shù)來傳遞。最終的結(jié)果即實現(xiàn)了在DBGridMaster控件上顯示出每個客戶總的定貨信息,在DBGridDetail控件上顯示出相應(yīng)客戶的限定字段的詳細(xì)定貨信息記錄的功能。
添加以下兩句黑體字代碼到TForm1::FormCreate()事件句柄中去:
QueryMaster->Active = true;QueryDetail->Active = true;
運行程序,即可在DBGridMaster、DBGridDetail中瀏覽到Master/Detail關(guān)系主從表相關(guān)記錄信息。
綜上所述,對于一般的Master/Detail關(guān)系應(yīng)用,用TTable控件就足以應(yīng)付了,而要實現(xiàn)更進(jìn)一步的功能,如多層M/D關(guān)系、遠(yuǎn)程網(wǎng)絡(luò)數(shù)據(jù)庫操作、多表互關(guān)聯(lián)類型、單表M/D關(guān)系的數(shù)據(jù)庫編程,則需要用到TQuery控件,利用SQL指令的靈活性對數(shù)據(jù)庫進(jìn)行操作。復(fù)雜功能的Master/Detail關(guān)系數(shù)據(jù)庫編程可在本文的基礎(chǔ)上參考相應(yīng)的書籍以及BCB的聯(lián)機幫助實現(xiàn)。
本文程序在C++ Builder 3.0/ PWin95,C++ Builder 4.0/ PWin98下調(diào)試通過。