bcb資料庫
#include "objbase.h" //牽涉到COM對象,必須包含此頭文件
AnsiString srcmdb="c:\\test.mdb"; //原文件名(壓縮之前)
AnsiString destmdb="c:\\test2.mdb"; //目標文件名(壓縮之後)
CoInitialize(NULL); //初始化COM對象
AnsiString src = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+srcmdb; //連接字串
AnsiString dest = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+destmdb;
Variant AdoObj = Variant::CreateObject("JRO.JetEngine");
AdoObj.OleProcere("CompactDatabase",src.c_str(),dest.c_str());
AdoObj.Clear();
CoUninitialize();
DeleteFile(srcmdb) ; //刪除原文件,如果不放心可以不刪除留個備份,但需要改名
RenameFile(destmdb,srcmdb); //將壓縮後的文件改成原文件名
Ⅱ 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下調試通過。