第六章 什么是数据集
Delphi 4中有四种类型的标准
数据集构件,分别是TTable、TQuery、TStoredProc和TClientDataSet。这些
数据集构件都是从一个共同的基类TDataSet继承下来的,其中,只有TClientDataSet是直接从TDataSet继承下来的,而TTable、TQuery、TStoredProc的直接上级是TDBDataSet,TDBDataSet的上级是TBDEDataSet,TBDEDataSet 的上级才是TDataSet。这几个类之间的继承关系可以用图6.1来表示。
图6.1
数据集的继承关系
TDataSet是所有
数据集的抽象基类,它的大部分属性和方法是虚拟的或抽象的。所谓虚拟的方法,是指这些方法可以被派生类重载。所谓抽象的方法,是指这些方法只有声明,没有定义,派生类必须给出定义后才能调用这些方法,不同的派生类可以有不同的定义。
由于TDataSet中包含抽象的方法,您不能直接创建它的实例,否则会引起运行期错误。
如果从功能上划分,TDataSet的属性和方法可以分为这么几大块:打开和关闭
数据集、浏览记录、编辑
数据、书签管理、控制连接、访问字段、记录缓冲区管理、过滤、事件。
6.1 打开和关闭数据集 在对
数据集进行任何操作之前,首先要打开
数据集。要打开
数据集,可以把Active属性设为True,例如:
CustTable.Active := True;
也可以调用Open函数,例如:CustQuery.Open;
要关闭
数据集,可以把Active属性设为False或者调用Close函数。
6.2 数据集的状态 数据集的状态(State属性)决定了当前能够对
数据集进行的操作,例如,当
数据集已经关闭,它的状态是dsInactive,此时就不能访问
数据集的任何
数据。
6.2.1 State属性 State属性是只读的,下面列出了State属性可能的值:
.dsInactive
数据集已关闭,不能访问它的
数据;
.dsBrowse
数据集已打开,可以浏览
数据但不能修改
数据;
.dsEdit 此时为编辑状态,可以修改
数据;
.dsInsert 此时可以插入一条新的记录;
.dsSetKey 只适用于TTable和TClientDataSet,此时可以设置范围和键值,并且可以调用GotoKey函数;
.dsCalcFields 正在处理OnCalcFields事件,此时不能修改非计算字段的值;
.dsCurValue 内部使用;
.dsNewValue 内部使用;
.dsOldValue 内部使用;
.dsFilter 正在进行过滤操作。
当一个
数据集刚刚打开的时候,它的State属性被设为dsBrowse,以后,State属性的值会随着应用
程序的操作自动变化。
要使
数据集进入dsBrowse、dsEdit、dsInsert或dsSetKey状态,就得调用相应的方法。
例如,要使
数据集CustTable进入dsInsert状态,
程序示例如下:
Procedure TForm1.InsertButtonClick(Sender: TObject);
Begin
CustTable.Insert;{进入dsInsert状态}
AddressPromptDialog.ShowModal;
If AddressPromptDialog.ModalResult := mrOK then
CustTable.Post; {恢复为dsBrowse状态}
Else
CustTable.Cancel; {恢复为dsBrowse状态}
End;
从上面这个例子可以看出,有些操作会使
数据集自动变成dsBrowse状态,例如,调用Post函数如果成功的话,
数据集就恢复为dsBrowse状态,如果调用Post没有成功,
数据集仍然保持原来的状态。调用Cancel也能使
数据集恢复为dsBrowse状态。
如果把Active属性设为False,或者调用Close,将使
数据集进入dsInactive状态。例如,下面两行代码是等价的:
CustTable.Active := False;
CustTable.Close;
有些状态如dsCalcFields、dsCurValue、dsNewValue、dsOldValue和dsFilter不能被应用
程序所控制,而是由
数据集本身根据需要自动设置的。例如,当正在处理OnCalcFields事件时,就自动进入dsCalcFields状态。当退出处理OnCalcFields事件的句柄时,
数据集自动恢复成原先的状态。
当
数据集的状态发生改变时,会触发TDataSource构件的OnStateChange事件,如果这个TDataSource构件的DataSet属性指定了这个
数据集的话。
下面详细介绍
数据集的各种状态以及怎样进入这些状态。
6.2.2 dsInactive状态 当
数据集已关闭时,就处于dsInactive状态。此时,不能访问它的任何
数据。
要使
数据集进入dsInactive状态,可以把Active属性设为False,或者调用Close。在
数据集将要关闭之前,会触发BeforeClose事件。当
数据集刚刚关闭,会触发AfterClose事件。如果在
数据集处于dsEdit或dsInsert状态时调用Close,应当在处理BeforeClose事件的句柄中提示用户是认可还是取消。
程序示例如下:
Procedure CustTable.VerifyBeforeClose(DataSet: TDataSet)
Begin
If (CustTable.State = dsEdit) or (CustTable.State = dsInsert) then
Begin
If MessageDlg('认可修改吗?', mtConfirmation, mbYesNo, 0) = mrYes then
CustTable.Post;
ElseCustTable.Cancel;
End;
End;
6.2.3 dsBrowse状态 当一个
数据集刚刚打开的时候,
数据集总是处于dsBrowse状态,此时,可以显示
数据集中的记录,但不能编辑和插入记录。
dsBrowse状态可以认为是
数据集的基本状态,在此状态下,可以进入其他状态。例如,调用Insert或Append函数将使
数据集的状态从dsBrowse变成dsInsert(当然,这还取决于其他因素,如CanModify属性的值),调用SetKey将使
数据集从dsBrowse变成dsSetKey状态。
TDataSet有两个方法可以使
数据集回到dsBrowse状态,一个是Cancel,它将取消当前正在进行的编辑、插入、搜索等操作,使
数据集回到dsBrowse状态。另一个是Post,它将试图把修改了的
数据保存到
数据集中,如果成功的话,
数据集将回到dsBrowse状态,如果没有成功,
数据集仍然保持原先的状态。
6.2.4 dsEdit状态 如果应用
程序要修改
数据集的
数据,必须首先进入dsEdit状态。要进入dsEdit状态,可以调用Edit。不过,调用Edit并不能保证一定能进入dsEdit状态,这还取决于CanModify属性的值。如果这个属性返回True的话,表示
数据集是可以读和写的。
对于TTable构件来说,如果ReadOnly属性设为True,CanModify属性肯定返回False。对于TQuery构件来说,如果RequestLive属性设为False,CanModify属性肯定返回False。
即使
数据集进入了dsEdit状态,也并不意味着用户就一定能修改
数据,
数据控件的ReadOnly属性还必须设为False。此外,对于SQL数据库来说,用户能不能修改
数据还取决于用户有没有修改
数据的权限。
要从dsEdit状态返回到dsBrowse状态,可以调用Cancel、Post或Delete函数,其中,如果