(也很老了)
在开发数据库软件的过程中,由于实际需求会不断发生变化,数据库结构也将随之改变,这会给文档更新工作带来很大困难。如果能够用软件自动获得数据库的结构信息并生成报告文件,将大大减轻软件的文档工作量。本文介绍了在Delphi中访问数据库结构的方法,希望对各位程序员有所帮助。
1.TSession对象
为了管理应用程序与数据库系统的多重连接,Delphi提供了TSession对象。Delphi中的数据访问对象(Data Access Object)均包含Session属性,用来指向与之对应的TSession对象。如果应用程序需要同时建立对数据库系统(尤其是BDE数据库)的多个连接,就必须定义多个TSession对象,属于不同连接的数据访问对象的Session属性不能相同,否则将无法同时使用。
在数据库应用程序运行时,Delphi会自动生成一个缺省TSession对象,名字为Session,数据访问对象在缺省情况下均与之相连。
TSession对象除了自动管理数据库连接外,还能够取得数据库信息。下面就分别介绍这方面的函数。
2.获取数据库别名(Alias)信息
TSession对象在获取数据库别名方面有3个函数/过程:
procedure TSession.GetAliasNames(List: TStrings);
procedure TSession.GetAliasParams(const AliasName: string; List: TStrings);
function TSession.GetAliasDriverName(const AliasName: string): string;
GetAliasNames用来获得所有的BDE别名名称,结果保存在变量List中;GetAliasParams用来获得某个BDE别名的参数,结果保存在变量List中;GetAliasDriverName用来取得某个BDE别名使用的数据库驱动程序的名字。这3个函数不太复杂,就不多加介绍了。一般情况下,我们只需要使用GetAliasNames即可。
3.获取数据表(Table)信息
在知道了数据库别名后,如何取出该别名对应数据库中包含的数据表呢?可以使用TSession对象中的 GetTableNames过程。该过程描述如下:
procedure TSession.GetTableNames(const DatabaseName, Pattern: string;
Extensions,SystemTables: Boolean; List: TStrings);
各参数意义如下:
DatabaseName:数据库别名;
Pattern:过滤器,用来过滤结果,可以使用通配符。比如“*.dbf”,“t*” 等。如果为空字符串,则表示不需要过滤;
Extensions:为布尔量,表示是否显示数据表扩展名。该参数只对DBF和Paradox数据库有效;
SystemTables:为布尔量,表示是否显示系统数据表;
List:为返回结果,结果按字母顺序排序。
4.获取数据域(Field)和索引(Index)信息
在取得了数据表信息后,应使用TTable对象访问该数据表的具体信息。对应函数如下:
procedure TDataSet.GetFieldNames(List: TStrings);
procedure TTable.GetIndexNames(List: TStrings);
GetFieldNames用来取得数据表中的各个域名,GetIndexNames用来取得数据表中的各个索引名。
另外,可以进一步使用TDataset和TTable中的两个属性TDataSet.FieldDefs.Items[] 和 TTable.IndexDefs.Items[]来访问具体的数据域信息和索引信息。它们分别是由TFieldDef和TIndexDef组成的数组。
TFieldDef描述如下:
| 属性名称 | 类型 | 说明 |
| DataType | TfieldType | 域的数据类型 |
| FieldNo | Integer | 域的序号 |
| InternalCalcField | Boolean | 是否为自动计算域 |
| Name | string | 域名 |
| Precision | Integer | (对于数字类型)数据精度(位数) |
| Required | Boolean | 是否为非空域 |
| Size | Integer | 域的大小 |
TIndexDef描述如下:
| 属性名称 | 类型 | 说明 |
| Expression | String | 索引表达式,只对DBF Expression索引有效 |
| Fields | String | 组成该索引的域,各个域由 分号“;”分隔 |
| Name | String | 索引的名字 |
| Options | TIndexOptions | 索引的类型 |
| Source | String | 若使用*.MDX索引文件,为该文件名 |
TFieldType定义如下:
TFieldType = (ftUnknown, ftString, ftSmallint, ftInteger, ftWord, ftBoolean,
ftFloat,ftCurrency, ftBCD, ftDate, ftTime, ftDateTime, ftBytes, ftVarBytes,
ftAutoInc,ftBlob, ftMemo, ftGraphic, ftFmtMemo, ftParadoxOle, ftDBaseOle,
ftTypedBinary,ftCursor);
TIndexOptions定义如下:
TIndexOptions = set of (ixPrimary, ixUnique, ixDescending, ixExpression,
ixCaseInsensitive);
它们的具体意义可以参见Delphi帮助。
5.使用实例
使用下面的程序片段即可获得指定数据库中指定表的域定义和索引定义。ListBox1、ListBox2 和 ListBox3 为Form中定义的三个列表框,用于显示结果。
Var Alias,TableName:String;
Table1:TTable;
Begin
Alias:='fjs'; TableName:='d*'; //初始化
Session.GetTableNames(Alias, { 别名 }
TableName, { 过滤器 }
True, { 是否显示文件扩展名(对DBF) }
False, { 是否显示系统表 }
ListBox1.Items);
If ListBox1.Items.Count=0 then Begin
MessageDlg('数据库'+Alias+'中没有数据表'+TableName, mtError, [mbOK], 0 );
Exit;
End;
Table1:=TTable.Create(nil);
Table1.DatabaseName :=Alias;
Table1.TableName := ListBox1.Items.Strings[0];
{ 取得表中字段名及索引名 }
Table1.Open;
if Table1.Active then
begin
Table1.GetFieldNames(ListBox2.Items);
Table1.GetIndexNames(ListBox3.Items);
end;