四种类型的标准数据集构件,分别是TTable、TQuery、TStoredProc和TclientDataSet
这些数据集构件都是从一个共同的基类TDataSet继承下来的.
这几个类之间的继承关系可以用图来表示
TDataSet是所有数据集的抽象基类,它的大部分属性和方法是虚拟的或抽象的。
上图对应控制面板
TDataSet的属性和方法可以分为这么几大块:打开和关闭数据集、浏览记录、编辑数据、书签管理、控制连接、访问字段、记录缓冲区管理、过滤、事件。
开和关闭数据集
在对数据集进行任何操作之前,首先要打开数据集。要打开数据集,可以把Active属性设为True,例如:
CustTable.Active := True;
也可以调用Open函数,例如:CustQuery.Open;
要关闭数据集,可以把Active属性设为False或者调用Close函数。
数据集的状态
数据集的状态(State属性)决定了当前能够对数据集进行的操作,例如,当数据集已经关闭,它的状态是dsInactive,此时就不能访问数据集的任何数据。
State属性是只读的,下面列出了State属性可能的值:
.dsInactive 数据集已关闭,不能访问它的数据;
.dsBrowse 数据集已打开,可以浏览数据但不能修改数据;
.dsEdit 此时为编辑状态,可以修改数据;
.dsInsert 此时可以插入一条新的记录;
.dsSetKey 只适用于TTable和TClientDataSet,此时可以设置范围和键值,并且可以调用GotoKey函数;
.dsCalcFields 正在处理OnCalcFields事件,此时不能修改非计算字段的值;
.dsCurValue 内部使用;
.dsNewValue 内部使用;
.dsOldValue 内部使用;
.dsFilter 正在进行过滤操作。
当一个数据集刚刚打开的时候,它的State属性被设为dsBrowse
要使数据集进入dsBrowse、dsEdit、dsInsert或dsSetKey状态,就得调用相应的方法。
如果把Active属性设为False,或者调用Close,将使数据集进入dsInactive状态。例如,下面两行代码是等价的:
CustTable.Active := False;
CustTable.Close;
Eof和Bof属性
TDataSet有两个只读的属性Eof和Bof,分别用于判断是否到了数据集的末尾和开头。在遍历数据集的所有记录时经常要用到这两个属性。
如果Eof属性返回True,表示现在已到了数据集的末尾。
进行下列操作时会把Eof属性设为True:
.打开一个空的数据集;
.调用了Last;
.调用了Next,而现在已经在数据集的最后一条记录;
.调用了SetRange,而范围是无效的。
除了上述情况外,Eof属性都将返回False。
演示了在遍历数据集的所有记录时怎样暂时禁止数据控件跟着刷新。
CustTable.DisableControls;
Try
CustTable.First;
While not CustTable.EOF Do
Begin
...
CustTable.Next;
End;
Finally
CustTable.EnableControls;
End;
DisableControls禁止刷新,这样能够加快遍历的速度,因为刷新也是要花时间的。
EnableControls最好在Try...Finally结构的Finally部分调用,这样能保证即使在遍历时出现异常,也能保证刷新能得到恢复。
修改数据
TDataSet中提供了一些方法用于在数据集中更新、插入和删除记录,它们是:
.Edit使数据集进入dsEdit状态;
.Append在数据集的末尾添加一条记录;
.Insert在数据集的当前位置插入一条记录;
.Post试图把用户对数据的修改写到数据集中;
.Cancel取消用户对数据的修改,使数据集回到dsBrowse状态;
.Delete删除当前记录。
进入dsEdit状态
要编辑数据集的记录,首先要进入dsEdit状态。要进入dsEdit状态,调用Edit函数。不过,调用Edit不一定会使数据集进入dsEdit状态,还取决于CanModify属性的值。
在使用缓存更新技术(CachedUpdates属性设为True)的情况下,调用Post只是把数据写到缓存中,而不是直接写到数据集中。要把缓存中的数据写到数据集中,需调用ApplyUpdates函数。
插入新的记录
要在数据集中插入新的记录,首先要进入dsInsert状态。要进入dsInsert状态,可以调用Insert或Append函数。不过,调用Insert或Append不一定会使数据集进入dsInsert状态,还取决于CanModify属性的值。
一旦进入了dsInsert状态,用户就可以在数据控件(一般是TDBGrid)中插入一条新的记录,并给这条记录输入数据。
如果要通过编程来插入新的记录,就要注意Insert和Append的区别。Insert将把一条新的记录插入到当前记录的前面,而Append将把一条新的记录添加到数据集的末尾。
插入了新的记录后,应当调用Post或在CachedUpdates属性设为True的情况下调用ApplyUpdates把新的记录写到数据集中。
事件
TDataSet的事件主要分为两大类,一类是Before系列,另一类是After系列,列表如下:
.BeforeOpen,AfterOpen发生在数据集打开前后;
.BeforeClose,AfterClose发生在数据集关闭前后;
.BeforeInsert,AfterInsert发生在插入了一条新的记录前后;
.BeforeEdit,AfterEdit 发生在进入dsEdit状态前后;
.BeforePost,AfterPost 发生在写数据集的前后;
.BeforeCancel,AfterCancel发生在取消修改的前后;
.BeforeDelete,AfterDelete发生在删除记录的前后。
当数据集中增加了一条新的记录时就会触发OnNewRecord事件,当“计算字段”的值需要重算时将触发OnCalcFields事件。
Before系列的事件常常用来中止操作。
当调用Delete函数试图删除当前记录时,在当前记录将要删除前会触发BeforeDelete事件,可以在处理BeforeDelete事件的句柄中调用Abort或触发一个异常放弃删除当前记录
程序示例如下:
Pocedure TForm1.TableBeforeDelete (Dataset: TDataset)
Begin
If MessageDlg(Delete This Record?, mtConfirmation, mbYesNoCancel, 0) <> mrYes Then Abort;
End;
After系列的事件往往用来在状态栏上通知用户
程序示例如下:
Procedure TForm1.Table1AfterDelete(DataSet: TDataSet);
Begin
StatusBar1.SimpleText := Format(有%d 条记录,[DataSet.RecordCount]);
End;
TBDEDataSet
TBDEDataSet是从TDataSet继承下来的,它提供了通过BDE(BorlandDatabase Engine)访问数据的能力。
TBDEDataSet的CacheBlobs属性用于控制BDE是否把BLOB字段的内容放到缓存中。如果这个属性设为True,当应用程序读取BLOB字段的值时,BDE将把BLOB字段的内容放在缓存中
TBDEDataSet提供了缓存更新的技术。所谓缓存更新就是,应用程序从数据库中检索数据,在本地缓存中建立一个副本,用户对数据进行修改后,也只是反映在缓存中,以后可以调用ApplyUpdates一次性地把所有的修改反映到数据集中。
TDBDataSet
TDBDataSet是从TBDEDataSet继承下来的,它提供了数据库和会话期管理的能力。
增加了若干个属性和方法用于管理数据库和BDE会话期,包括:
.CheckOpen检查数据库是否已打开;
.Database返回一个TDatabase构件;
.DBHandle返回一个BDE句柄,调用BDE的API时要用到这个句柄;
.DBLocale返回当前的国际语言驱动程序;
.DBSession返回一个BDE会话期对象;
.DatabaseName用于指定要访问的数据库;
.SessionName用于指定一个BDE会话期对象。
DatabaseName属性:如果应用程序要访问远程数据库服务器如Sybase、Oracle或InterBase,应当用TDatabase构件来连接数据库。DatabaseName属性指定要连接的数据库,可以设为TDatabase构件的名称。如果没有显式地使用TDatabase构件,DatabaseName属性应当设为BDE 别名
SessionName属性用于指定一个BDE会话期对象。如果应用程序没有显式地使用TSession构件,不必设置这个属性。如果应用程序显式地使用了多个TSession构件,应当设置SessionName属性指定其中一个。